@@ -4557,12 +4557,16 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
45574557 vRecv >> LIMITED_STRING (pfrom->strSubVer , MAX_SUBVERSION_LENGTH);
45584558 pfrom->cleanSubVer = SanitizeString (pfrom->strSubVer );
45594559 }
4560- if (!vRecv.empty ())
4560+ if (!vRecv.empty ()) {
45614561 vRecv >> pfrom->nStartingHeight ;
4562- if (!vRecv.empty ())
4563- vRecv >> pfrom->fRelayTxes ; // set to true after we get the first filter* message
4564- else
4565- pfrom->fRelayTxes = true ;
4562+ }
4563+ {
4564+ LOCK (pfrom->cs_filter );
4565+ if (!vRecv.empty ())
4566+ vRecv >> pfrom->fRelayTxes ; // set to true after we get the first filter* message
4567+ else
4568+ pfrom->fRelayTxes = true ;
4569+ }
45664570
45674571 // Disconnect if we connected to ourself
45684572 if (nNonce == nLocalHostNonce && nNonce > 1 )
@@ -5325,12 +5329,13 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
53255329 CBloomFilter filter;
53265330 vRecv >> filter;
53275331
5332+ LOCK (pfrom->cs_filter );
5333+
53285334 if (!filter.IsWithinSizeConstraints ())
53295335 // There is no excuse for sending a too-large filter
53305336 Misbehaving (pfrom->GetId (), 100 );
53315337 else
53325338 {
5333- LOCK (pfrom->cs_filter );
53345339 delete pfrom->pfilter ;
53355340 pfrom->pfilter = new CBloomFilter (filter);
53365341 pfrom->pfilter ->UpdateEmptyFull ();
@@ -5798,6 +5803,12 @@ bool SendMessages(CNode* pto)
57985803 pto->nNextInvSend = PoissonNextSend (nNow, INVENTORY_BROADCAST_INTERVAL >> !pto->fInbound );
57995804 }
58005805
5806+ // Time to send but the peer has requested we not relay transactions.
5807+ if (fSendTrickle ) {
5808+ LOCK (pto->cs_filter );
5809+ if (!pto->fRelayTxes ) pto->setInventoryTxToSend .clear ();
5810+ }
5811+
58015812 // Respond to BIP35 mempool requests
58025813 if (fSendTrickle && pto->fSendMempool ) {
58035814 std::vector<uint256> vtxid;
@@ -5843,13 +5854,19 @@ bool SendMessages(CNode* pto)
58435854 for (std::set<uint256>::iterator it = pto->setInventoryTxToSend .begin (); it != pto->setInventoryTxToSend .end (); it++) {
58445855 vInvTx.push_back (it);
58455856 }
5857+ CAmount filterrate = 0 ;
5858+ {
5859+ LOCK (pto->cs_feeFilter );
5860+ filterrate = pto->minFeeFilter ;
5861+ }
58465862 // Topologically and fee-rate sort the inventory we send for privacy and priority reasons.
58475863 // A heap is used so that not all items need sorting if only a few are being sent.
58485864 CompareInvMempoolOrder compareInvMempoolOrder (&mempool);
58495865 std::make_heap (vInvTx.begin (), vInvTx.end (), compareInvMempoolOrder);
58505866 // No reason to drain out at many times the network's capacity,
58515867 // especially since we have many peers and some will draw much shorter delays.
58525868 unsigned int nRelayedTransactions = 0 ;
5869+ LOCK (pto->cs_filter );
58535870 while (!vInvTx.empty () && nRelayedTransactions < INVENTORY_BROADCAST_MAX) {
58545871 // Fetch the top element from the heap
58555872 std::pop_heap (vInvTx.begin (), vInvTx.end (), compareInvMempoolOrder);
@@ -5862,6 +5879,19 @@ bool SendMessages(CNode* pto)
58625879 if (pto->filterInventoryKnown .contains (hash)) {
58635880 continue ;
58645881 }
5882+ // Not in the mempool anymore? don't bother sending it.
5883+ CFeeRate feeRate;
5884+ if (!mempool.lookupFeeRate (hash, feeRate)) {
5885+ continue ;
5886+ }
5887+ if (filterrate && feeRate.GetFeePerK () < filterrate) {
5888+ continue ;
5889+ }
5890+ if (pto->pfilter ) {
5891+ CTransaction tx;
5892+ if (!mempool.lookup (hash, tx)) continue ;
5893+ if (!pto->pfilter ->IsRelevantAndUpdate (tx)) continue ;
5894+ }
58655895 // Send
58665896 vInv.push_back (CInv (MSG_TX, hash));
58675897 nRelayedTransactions++;
0 commit comments