@ -4557,12 +4557,16 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
vRecv > > LIMITED_STRING ( pfrom - > strSubVer , MAX_SUBVERSION_LENGTH ) ;
vRecv > > LIMITED_STRING ( pfrom - > strSubVer , MAX_SUBVERSION_LENGTH ) ;
pfrom - > cleanSubVer = SanitizeString ( pfrom - > strSubVer ) ;
pfrom - > cleanSubVer = SanitizeString ( pfrom - > strSubVer ) ;
}
}
if ( ! vRecv . empty ( ) )
if ( ! vRecv . empty ( ) ) {
vRecv > > pfrom - > nStartingHeight ;
vRecv > > pfrom - > nStartingHeight ;
if ( ! vRecv . empty ( ) )
}
vRecv > > pfrom - > fRelayTxes ; // set to true after we get the first filter* message
{
else
LOCK ( pfrom - > cs_filter ) ;
pfrom - > fRelayTxes = true ;
if ( ! vRecv . empty ( ) )
vRecv > > pfrom - > fRelayTxes ; // set to true after we get the first filter* message
else
pfrom - > fRelayTxes = true ;
}
// Disconnect if we connected to ourself
// Disconnect if we connected to ourself
if ( nNonce = = nLocalHostNonce & & nNonce > 1 )
if ( nNonce = = nLocalHostNonce & & nNonce > 1 )
@ -5325,12 +5329,13 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
CBloomFilter filter ;
CBloomFilter filter ;
vRecv > > filter ;
vRecv > > filter ;
LOCK ( pfrom - > cs_filter ) ;
if ( ! filter . IsWithinSizeConstraints ( ) )
if ( ! filter . IsWithinSizeConstraints ( ) )
// There is no excuse for sending a too-large filter
// There is no excuse for sending a too-large filter
Misbehaving ( pfrom - > GetId ( ) , 100 ) ;
Misbehaving ( pfrom - > GetId ( ) , 100 ) ;
else
else
{
{
LOCK ( pfrom - > cs_filter ) ;
delete pfrom - > pfilter ;
delete pfrom - > pfilter ;
pfrom - > pfilter = new CBloomFilter ( filter ) ;
pfrom - > pfilter = new CBloomFilter ( filter ) ;
pfrom - > pfilter - > UpdateEmptyFull ( ) ;
pfrom - > pfilter - > UpdateEmptyFull ( ) ;
@ -5798,6 +5803,12 @@ bool SendMessages(CNode* pto)
pto - > nNextInvSend = PoissonNextSend ( nNow , INVENTORY_BROADCAST_INTERVAL > > ! pto - > fInbound ) ;
pto - > nNextInvSend = PoissonNextSend ( nNow , INVENTORY_BROADCAST_INTERVAL > > ! pto - > fInbound ) ;
}
}
// Time to send but the peer has requested we not relay transactions.
if ( fSendTrickle ) {
LOCK ( pto - > cs_filter ) ;
if ( ! pto - > fRelayTxes ) pto - > setInventoryTxToSend . clear ( ) ;
}
// Respond to BIP35 mempool requests
// Respond to BIP35 mempool requests
if ( fSendTrickle & & pto - > fSendMempool ) {
if ( fSendTrickle & & pto - > fSendMempool ) {
std : : vector < uint256 > vtxid ;
std : : vector < uint256 > vtxid ;
@ -5843,6 +5854,11 @@ bool SendMessages(CNode* pto)
for ( std : : set < uint256 > : : iterator it = pto - > setInventoryTxToSend . begin ( ) ; it ! = pto - > setInventoryTxToSend . end ( ) ; it + + ) {
for ( std : : set < uint256 > : : iterator it = pto - > setInventoryTxToSend . begin ( ) ; it ! = pto - > setInventoryTxToSend . end ( ) ; it + + ) {
vInvTx . push_back ( it ) ;
vInvTx . push_back ( it ) ;
}
}
CAmount filterrate = 0 ;
{
LOCK ( pto - > cs_feeFilter ) ;
filterrate = pto - > minFeeFilter ;
}
// Topologically and fee-rate sort the inventory we send for privacy and priority reasons.
// Topologically and fee-rate sort the inventory we send for privacy and priority reasons.
// A heap is used so that not all items need sorting if only a few are being sent.
// A heap is used so that not all items need sorting if only a few are being sent.
CompareInvMempoolOrder compareInvMempoolOrder ( & mempool ) ;
CompareInvMempoolOrder compareInvMempoolOrder ( & mempool ) ;
@ -5850,6 +5866,7 @@ bool SendMessages(CNode* pto)
// No reason to drain out at many times the network's capacity,
// No reason to drain out at many times the network's capacity,
// especially since we have many peers and some will draw much shorter delays.
// especially since we have many peers and some will draw much shorter delays.
unsigned int nRelayedTransactions = 0 ;
unsigned int nRelayedTransactions = 0 ;
LOCK ( pto - > cs_filter ) ;
while ( ! vInvTx . empty ( ) & & nRelayedTransactions < INVENTORY_BROADCAST_MAX ) {
while ( ! vInvTx . empty ( ) & & nRelayedTransactions < INVENTORY_BROADCAST_MAX ) {
// Fetch the top element from the heap
// Fetch the top element from the heap
std : : pop_heap ( vInvTx . begin ( ) , vInvTx . end ( ) , compareInvMempoolOrder ) ;
std : : pop_heap ( vInvTx . begin ( ) , vInvTx . end ( ) , compareInvMempoolOrder ) ;
@ -5862,6 +5879,19 @@ bool SendMessages(CNode* pto)
if ( pto - > filterInventoryKnown . contains ( hash ) ) {
if ( pto - > filterInventoryKnown . contains ( hash ) ) {
continue ;
continue ;
}
}
// Not in the mempool anymore? don't bother sending it.
CFeeRate feeRate ;
if ( ! mempool . lookupFeeRate ( hash , feeRate ) ) {
continue ;
}
if ( filterrate & & feeRate . GetFeePerK ( ) < filterrate ) {
continue ;
}
if ( pto - > pfilter ) {
CTransaction tx ;
if ( ! mempool . lookup ( hash , tx ) ) continue ;
if ( ! pto - > pfilter - > IsRelevantAndUpdate ( tx ) ) continue ;
}
// Send
// Send
vInv . push_back ( CInv ( MSG_TX , hash ) ) ;
vInv . push_back ( CInv ( MSG_TX , hash ) ) ;
nRelayedTransactions + + ;
nRelayedTransactions + + ;