@@ -1448,7 +1448,7 @@ void static ProcessGetBlockData(CNode* pfrom, const CChainParams& chainparams, c
14481448 {
14491449 bool sendMerkleBlock = false ;
14501450 CMerkleBlock merkleBlock;
1451- {
1451+ if (pfrom-> m_tx_relay != nullptr ) {
14521452 LOCK (pfrom->m_tx_relay ->cs_filter );
14531453 if (pfrom->m_tx_relay ->pfilter ) {
14541454 sendMerkleBlock = true ;
@@ -1512,7 +1512,7 @@ void static ProcessGetData(CNode* pfrom, const CChainParams& chainparams, CConnm
15121512 std::deque<CInv>::iterator it = pfrom->vRecvGetData .begin ();
15131513 std::vector<CInv> vNotFound;
15141514 const CNetMsgMaker msgMaker (pfrom->GetSendVersion ());
1515- {
1515+ if (pfrom-> m_tx_relay != nullptr ) {
15161516 LOCK (cs_main);
15171517
15181518 while (it != pfrom->vRecvGetData .end () && (it->type == MSG_TX || it->type == MSG_WITNESS_TX)) {
@@ -1995,7 +1995,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
19951995 // set nodes not capable of serving the complete blockchain history as "limited nodes"
19961996 pfrom->m_limited_node = (!(nServices & NODE_NETWORK) && (nServices & NODE_NETWORK_LIMITED));
19971997
1998- {
1998+ if (pfrom-> m_tx_relay != nullptr ) {
19991999 LOCK (pfrom->m_tx_relay ->cs_filter );
20002000 pfrom->m_tx_relay ->fRelayTxes = fRelay ; // set to true after we get the first filter* message
20012001 }
@@ -3030,8 +3030,10 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
30303030 return true ;
30313031 }
30323032
3033- LOCK (pfrom->m_tx_relay ->cs_tx_inventory );
3034- pfrom->m_tx_relay ->fSendMempool = true ;
3033+ if (pfrom->m_tx_relay != nullptr ) {
3034+ LOCK (pfrom->m_tx_relay ->cs_tx_inventory );
3035+ pfrom->m_tx_relay ->fSendMempool = true ;
3036+ }
30353037 return true ;
30363038 }
30373039
@@ -3122,7 +3124,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
31223124 LOCK (cs_main);
31233125 Misbehaving (pfrom->GetId (), 100 );
31243126 }
3125- else
3127+ else if (pfrom-> m_tx_relay != nullptr )
31263128 {
31273129 LOCK (pfrom->m_tx_relay ->cs_filter );
31283130 pfrom->m_tx_relay ->pfilter .reset (new CBloomFilter (filter));
@@ -3141,7 +3143,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
31413143 bool bad = false ;
31423144 if (vData.size () > MAX_SCRIPT_ELEMENT_SIZE) {
31433145 bad = true ;
3144- } else {
3146+ } else if (pfrom-> m_tx_relay != nullptr ) {
31453147 LOCK (pfrom->m_tx_relay ->cs_filter );
31463148 if (pfrom->m_tx_relay ->pfilter ) {
31473149 pfrom->m_tx_relay ->pfilter ->insert (vData);
@@ -3157,6 +3159,9 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
31573159 }
31583160
31593161 if (strCommand == NetMsgType::FILTERCLEAR) {
3162+ if (pfrom->m_tx_relay == nullptr ) {
3163+ return true ;
3164+ }
31603165 LOCK (pfrom->m_tx_relay ->cs_filter );
31613166 if (pfrom->GetLocalServices () & NODE_BLOOM) {
31623167 pfrom->m_tx_relay ->pfilter .reset (new CBloomFilter ());
@@ -3169,7 +3174,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
31693174 CAmount newFeeFilter = 0 ;
31703175 vRecv >> newFeeFilter;
31713176 if (MoneyRange (newFeeFilter)) {
3172- {
3177+ if (pfrom-> m_tx_relay != nullptr ) {
31733178 LOCK (pfrom->m_tx_relay ->cs_feeFilter );
31743179 pfrom->m_tx_relay ->minFeeFilter = newFeeFilter;
31753180 }
@@ -3791,121 +3796,123 @@ bool PeerLogicValidation::SendMessages(CNode* pto)
37913796 }
37923797 pto->vInventoryBlockToSend .clear ();
37933798
3794- LOCK (pto->m_tx_relay ->cs_tx_inventory );
3795- // Check whether periodic sends should happen
3796- bool fSendTrickle = pto->HasPermission (PF_NOBAN);
3797- if (pto->m_tx_relay ->nNextInvSend < nNow) {
3798- fSendTrickle = true ;
3799- if (pto->fInbound ) {
3800- pto->m_tx_relay ->nNextInvSend = connman->PoissonNextSendInbound (nNow, INVENTORY_BROADCAST_INTERVAL);
3801- } else {
3802- // Use half the delay for outbound peers, as there is less privacy concern for them.
3803- pto->m_tx_relay ->nNextInvSend = PoissonNextSend (nNow, INVENTORY_BROADCAST_INTERVAL >> 1 );
3799+ if (pto->m_tx_relay != nullptr ) {
3800+ LOCK (pto->m_tx_relay ->cs_tx_inventory );
3801+ // Check whether periodic sends should happen
3802+ bool fSendTrickle = pto->HasPermission (PF_NOBAN);
3803+ if (pto->m_tx_relay ->nNextInvSend < nNow) {
3804+ fSendTrickle = true ;
3805+ if (pto->fInbound ) {
3806+ pto->m_tx_relay ->nNextInvSend = connman->PoissonNextSendInbound (nNow, INVENTORY_BROADCAST_INTERVAL);
3807+ } else {
3808+ // Use half the delay for outbound peers, as there is less privacy concern for them.
3809+ pto->m_tx_relay ->nNextInvSend = PoissonNextSend (nNow, INVENTORY_BROADCAST_INTERVAL >> 1 );
3810+ }
38043811 }
3805- }
3806-
3807- // Time to send but the peer has requested we not relay transactions.
3808- if (fSendTrickle ) {
3809- LOCK (pto->m_tx_relay ->cs_filter );
3810- if (!pto->m_tx_relay ->fRelayTxes ) pto->m_tx_relay ->setInventoryTxToSend .clear ();
3811- }
38123812
3813- // Respond to BIP35 mempool requests
3814- if (fSendTrickle && pto->m_tx_relay ->fSendMempool ) {
3815- auto vtxinfo = mempool.infoAll ();
3816- pto->m_tx_relay ->fSendMempool = false ;
3817- CAmount filterrate = 0 ;
3818- {
3819- LOCK (pto->m_tx_relay ->cs_feeFilter );
3820- filterrate = pto->m_tx_relay ->minFeeFilter ;
3813+ // Time to send but the peer has requested we not relay transactions.
3814+ if (fSendTrickle ) {
3815+ LOCK (pto->m_tx_relay ->cs_filter );
3816+ if (!pto->m_tx_relay ->fRelayTxes ) pto->m_tx_relay ->setInventoryTxToSend .clear ();
38213817 }
38223818
3823- LOCK (pto->m_tx_relay ->cs_filter );
3824-
3825- for (const auto & txinfo : vtxinfo) {
3826- const uint256& hash = txinfo.tx ->GetHash ();
3827- CInv inv (MSG_TX, hash);
3828- pto->m_tx_relay ->setInventoryTxToSend .erase (hash);
3829- if (filterrate) {
3830- if (txinfo.feeRate .GetFeePerK () < filterrate)
3831- continue ;
3832- }
3833- if (pto->m_tx_relay ->pfilter ) {
3834- if (!pto->m_tx_relay ->pfilter ->IsRelevantAndUpdate (*txinfo.tx )) continue ;
3819+ // Respond to BIP35 mempool requests
3820+ if (fSendTrickle && pto->m_tx_relay ->fSendMempool ) {
3821+ auto vtxinfo = mempool.infoAll ();
3822+ pto->m_tx_relay ->fSendMempool = false ;
3823+ CAmount filterrate = 0 ;
3824+ {
3825+ LOCK (pto->m_tx_relay ->cs_feeFilter );
3826+ filterrate = pto->m_tx_relay ->minFeeFilter ;
38353827 }
3836- pto->m_tx_relay ->filterInventoryKnown .insert (hash);
3837- vInv.push_back (inv);
3838- if (vInv.size () == MAX_INV_SZ) {
3839- connman->PushMessage (pto, msgMaker.Make (NetMsgType::INV, vInv));
3840- vInv.clear ();
3828+
3829+ LOCK (pto->m_tx_relay ->cs_filter );
3830+
3831+ for (const auto & txinfo : vtxinfo) {
3832+ const uint256& hash = txinfo.tx ->GetHash ();
3833+ CInv inv (MSG_TX, hash);
3834+ pto->m_tx_relay ->setInventoryTxToSend .erase (hash);
3835+ if (filterrate) {
3836+ if (txinfo.feeRate .GetFeePerK () < filterrate)
3837+ continue ;
3838+ }
3839+ if (pto->m_tx_relay ->pfilter ) {
3840+ if (!pto->m_tx_relay ->pfilter ->IsRelevantAndUpdate (*txinfo.tx )) continue ;
3841+ }
3842+ pto->m_tx_relay ->filterInventoryKnown .insert (hash);
3843+ vInv.push_back (inv);
3844+ if (vInv.size () == MAX_INV_SZ) {
3845+ connman->PushMessage (pto, msgMaker.Make (NetMsgType::INV, vInv));
3846+ vInv.clear ();
3847+ }
38413848 }
3849+ pto->m_tx_relay ->timeLastMempoolReq = GetTime ();
38423850 }
3843- pto->m_tx_relay ->timeLastMempoolReq = GetTime ();
3844- }
38453851
3846- // Determine transactions to relay
3847- if (fSendTrickle ) {
3848- // Produce a vector with all candidates for sending
3849- std::vector<std::set<uint256>::iterator> vInvTx;
3850- vInvTx.reserve (pto->m_tx_relay ->setInventoryTxToSend .size ());
3851- for (std::set<uint256>::iterator it = pto->m_tx_relay ->setInventoryTxToSend .begin (); it != pto->m_tx_relay ->setInventoryTxToSend .end (); it++) {
3852- vInvTx.push_back (it);
3853- }
3854- CAmount filterrate = 0 ;
3855- {
3856- LOCK (pto->m_tx_relay ->cs_feeFilter );
3857- filterrate = pto->m_tx_relay ->minFeeFilter ;
3858- }
3859- // Topologically and fee-rate sort the inventory we send for privacy and priority reasons.
3860- // A heap is used so that not all items need sorting if only a few are being sent.
3861- CompareInvMempoolOrder compareInvMempoolOrder (&mempool);
3862- std::make_heap (vInvTx.begin (), vInvTx.end (), compareInvMempoolOrder);
3863- // No reason to drain out at many times the network's capacity,
3864- // especially since we have many peers and some will draw much shorter delays.
3865- unsigned int nRelayedTransactions = 0 ;
3866- LOCK (pto->m_tx_relay ->cs_filter );
3867- while (!vInvTx.empty () && nRelayedTransactions < INVENTORY_BROADCAST_MAX) {
3868- // Fetch the top element from the heap
3869- std::pop_heap (vInvTx.begin (), vInvTx.end (), compareInvMempoolOrder);
3870- std::set<uint256>::iterator it = vInvTx.back ();
3871- vInvTx.pop_back ();
3872- uint256 hash = *it;
3873- // Remove it from the to-be-sent set
3874- pto->m_tx_relay ->setInventoryTxToSend .erase (it);
3875- // Check if not in the filter already
3876- if (pto->m_tx_relay ->filterInventoryKnown .contains (hash)) {
3877- continue ;
3878- }
3879- // Not in the mempool anymore? don't bother sending it.
3880- auto txinfo = mempool.info (hash);
3881- if (!txinfo.tx ) {
3882- continue ;
3852+ // Determine transactions to relay
3853+ if (fSendTrickle ) {
3854+ // Produce a vector with all candidates for sending
3855+ std::vector<std::set<uint256>::iterator> vInvTx;
3856+ vInvTx.reserve (pto->m_tx_relay ->setInventoryTxToSend .size ());
3857+ for (std::set<uint256>::iterator it = pto->m_tx_relay ->setInventoryTxToSend .begin (); it != pto->m_tx_relay ->setInventoryTxToSend .end (); it++) {
3858+ vInvTx.push_back (it);
38833859 }
3884- if (filterrate && txinfo.feeRate .GetFeePerK () < filterrate) {
3885- continue ;
3886- }
3887- if (pto->m_tx_relay ->pfilter && !pto->m_tx_relay ->pfilter ->IsRelevantAndUpdate (*txinfo.tx )) continue ;
3888- // Send
3889- vInv.push_back (CInv (MSG_TX, hash));
3890- nRelayedTransactions++;
3860+ CAmount filterrate = 0 ;
38913861 {
3892- // Expire old relay messages
3893- while (!vRelayExpiration.empty () && vRelayExpiration.front ().first < nNow)
3894- {
3895- mapRelay.erase (vRelayExpiration.front ().second );
3896- vRelayExpiration.pop_front ();
3862+ LOCK (pto->m_tx_relay ->cs_feeFilter );
3863+ filterrate = pto->m_tx_relay ->minFeeFilter ;
3864+ }
3865+ // Topologically and fee-rate sort the inventory we send for privacy and priority reasons.
3866+ // A heap is used so that not all items need sorting if only a few are being sent.
3867+ CompareInvMempoolOrder compareInvMempoolOrder (&mempool);
3868+ std::make_heap (vInvTx.begin (), vInvTx.end (), compareInvMempoolOrder);
3869+ // No reason to drain out at many times the network's capacity,
3870+ // especially since we have many peers and some will draw much shorter delays.
3871+ unsigned int nRelayedTransactions = 0 ;
3872+ LOCK (pto->m_tx_relay ->cs_filter );
3873+ while (!vInvTx.empty () && nRelayedTransactions < INVENTORY_BROADCAST_MAX) {
3874+ // Fetch the top element from the heap
3875+ std::pop_heap (vInvTx.begin (), vInvTx.end (), compareInvMempoolOrder);
3876+ std::set<uint256>::iterator it = vInvTx.back ();
3877+ vInvTx.pop_back ();
3878+ uint256 hash = *it;
3879+ // Remove it from the to-be-sent set
3880+ pto->m_tx_relay ->setInventoryTxToSend .erase (it);
3881+ // Check if not in the filter already
3882+ if (pto->m_tx_relay ->filterInventoryKnown .contains (hash)) {
3883+ continue ;
3884+ }
3885+ // Not in the mempool anymore? don't bother sending it.
3886+ auto txinfo = mempool.info (hash);
3887+ if (!txinfo.tx ) {
3888+ continue ;
3889+ }
3890+ if (filterrate && txinfo.feeRate .GetFeePerK () < filterrate) {
3891+ continue ;
38973892 }
3893+ if (pto->m_tx_relay ->pfilter && !pto->m_tx_relay ->pfilter ->IsRelevantAndUpdate (*txinfo.tx )) continue ;
3894+ // Send
3895+ vInv.push_back (CInv (MSG_TX, hash));
3896+ nRelayedTransactions++;
3897+ {
3898+ // Expire old relay messages
3899+ while (!vRelayExpiration.empty () && vRelayExpiration.front ().first < nNow)
3900+ {
3901+ mapRelay.erase (vRelayExpiration.front ().second );
3902+ vRelayExpiration.pop_front ();
3903+ }
38983904
3899- auto ret = mapRelay.insert (std::make_pair (hash, std::move (txinfo.tx )));
3900- if (ret.second ) {
3901- vRelayExpiration.push_back (std::make_pair (nNow + 15 * 60 * 1000000 , ret.first ));
3905+ auto ret = mapRelay.insert (std::make_pair (hash, std::move (txinfo.tx )));
3906+ if (ret.second ) {
3907+ vRelayExpiration.push_back (std::make_pair (nNow + 15 * 60 * 1000000 , ret.first ));
3908+ }
39023909 }
3910+ if (vInv.size () == MAX_INV_SZ) {
3911+ connman->PushMessage (pto, msgMaker.Make (NetMsgType::INV, vInv));
3912+ vInv.clear ();
3913+ }
3914+ pto->m_tx_relay ->filterInventoryKnown .insert (hash);
39033915 }
3904- if (vInv.size () == MAX_INV_SZ) {
3905- connman->PushMessage (pto, msgMaker.Make (NetMsgType::INV, vInv));
3906- vInv.clear ();
3907- }
3908- pto->m_tx_relay ->filterInventoryKnown .insert (hash);
39093916 }
39103917 }
39113918 }
@@ -4066,7 +4073,7 @@ bool PeerLogicValidation::SendMessages(CNode* pto)
40664073 // Message: feefilter
40674074 //
40684075 // We don't want white listed peers to filter txs to us if we have -whitelistforcerelay
4069- if (pto->nVersion >= FEEFILTER_VERSION && gArgs .GetBoolArg (" -feefilter" , DEFAULT_FEEFILTER) &&
4076+ if (pto->m_tx_relay != nullptr && pto-> nVersion >= FEEFILTER_VERSION && gArgs .GetBoolArg (" -feefilter" , DEFAULT_FEEFILTER) &&
40704077 !pto->HasPermission (PF_FORCERELAY)) {
40714078 CAmount currentFilter = mempool.GetMinFee (gArgs .GetArg (" -maxmempool" , DEFAULT_MAX_MEMPOOL_SIZE) * 1000000 ).GetFeePerK ();
40724079 int64_t timeNow = GetTimeMicros ();
0 commit comments