@@ -1448,7 +1448,7 @@ void static ProcessGetBlockData(CNode* pfrom, const CChainParams& chainparams, c
1448
1448
{
1449
1449
bool sendMerkleBlock = false ;
1450
1450
CMerkleBlock merkleBlock;
1451
- {
1451
+ if (pfrom-> m_tx_relay != nullptr ) {
1452
1452
LOCK (pfrom->m_tx_relay ->cs_filter );
1453
1453
if (pfrom->m_tx_relay ->pfilter ) {
1454
1454
sendMerkleBlock = true ;
@@ -1512,7 +1512,7 @@ void static ProcessGetData(CNode* pfrom, const CChainParams& chainparams, CConnm
1512
1512
std::deque<CInv>::iterator it = pfrom->vRecvGetData .begin ();
1513
1513
std::vector<CInv> vNotFound;
1514
1514
const CNetMsgMaker msgMaker (pfrom->GetSendVersion ());
1515
- {
1515
+ if (pfrom-> m_tx_relay != nullptr ) {
1516
1516
LOCK (cs_main);
1517
1517
1518
1518
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
1995
1995
// set nodes not capable of serving the complete blockchain history as "limited nodes"
1996
1996
pfrom->m_limited_node = (!(nServices & NODE_NETWORK) && (nServices & NODE_NETWORK_LIMITED));
1997
1997
1998
- {
1998
+ if (pfrom-> m_tx_relay != nullptr ) {
1999
1999
LOCK (pfrom->m_tx_relay ->cs_filter );
2000
2000
pfrom->m_tx_relay ->fRelayTxes = fRelay ; // set to true after we get the first filter* message
2001
2001
}
@@ -3030,8 +3030,10 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
3030
3030
return true ;
3031
3031
}
3032
3032
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
+ }
3035
3037
return true ;
3036
3038
}
3037
3039
@@ -3122,7 +3124,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
3122
3124
LOCK (cs_main);
3123
3125
Misbehaving (pfrom->GetId (), 100 );
3124
3126
}
3125
- else
3127
+ else if (pfrom-> m_tx_relay != nullptr )
3126
3128
{
3127
3129
LOCK (pfrom->m_tx_relay ->cs_filter );
3128
3130
pfrom->m_tx_relay ->pfilter .reset (new CBloomFilter (filter));
@@ -3141,7 +3143,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
3141
3143
bool bad = false ;
3142
3144
if (vData.size () > MAX_SCRIPT_ELEMENT_SIZE) {
3143
3145
bad = true ;
3144
- } else {
3146
+ } else if (pfrom-> m_tx_relay != nullptr ) {
3145
3147
LOCK (pfrom->m_tx_relay ->cs_filter );
3146
3148
if (pfrom->m_tx_relay ->pfilter ) {
3147
3149
pfrom->m_tx_relay ->pfilter ->insert (vData);
@@ -3157,6 +3159,9 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
3157
3159
}
3158
3160
3159
3161
if (strCommand == NetMsgType::FILTERCLEAR) {
3162
+ if (pfrom->m_tx_relay == nullptr ) {
3163
+ return true ;
3164
+ }
3160
3165
LOCK (pfrom->m_tx_relay ->cs_filter );
3161
3166
if (pfrom->GetLocalServices () & NODE_BLOOM) {
3162
3167
pfrom->m_tx_relay ->pfilter .reset (new CBloomFilter ());
@@ -3169,7 +3174,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
3169
3174
CAmount newFeeFilter = 0 ;
3170
3175
vRecv >> newFeeFilter;
3171
3176
if (MoneyRange (newFeeFilter)) {
3172
- {
3177
+ if (pfrom-> m_tx_relay != nullptr ) {
3173
3178
LOCK (pfrom->m_tx_relay ->cs_feeFilter );
3174
3179
pfrom->m_tx_relay ->minFeeFilter = newFeeFilter;
3175
3180
}
@@ -3791,121 +3796,123 @@ bool PeerLogicValidation::SendMessages(CNode* pto)
3791
3796
}
3792
3797
pto->vInventoryBlockToSend .clear ();
3793
3798
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
+ }
3804
3811
}
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
- }
3812
3812
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 ();
3821
3817
}
3822
3818
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 ;
3835
3827
}
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
+ }
3841
3848
}
3849
+ pto->m_tx_relay ->timeLastMempoolReq = GetTime ();
3842
3850
}
3843
- pto->m_tx_relay ->timeLastMempoolReq = GetTime ();
3844
- }
3845
3851
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);
3883
3859
}
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 ;
3891
3861
{
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 ;
3897
3892
}
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
+ }
3898
3904
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
+ }
3902
3909
}
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);
3903
3915
}
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);
3909
3916
}
3910
3917
}
3911
3918
}
@@ -4066,7 +4073,7 @@ bool PeerLogicValidation::SendMessages(CNode* pto)
4066
4073
// Message: feefilter
4067
4074
//
4068
4075
// 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) &&
4070
4077
!pto->HasPermission (PF_FORCERELAY)) {
4071
4078
CAmount currentFilter = mempool.GetMinFee (gArgs .GetArg (" -maxmempool" , DEFAULT_MAX_MEMPOOL_SIZE) * 1000000 ).GetFeePerK ();
4072
4079
int64_t timeNow = GetTimeMicros ();
0 commit comments