@@ -331,6 +331,9 @@ class PeerManagerImpl final : public PeerManager
331
331
/* * Send `addr` messages on a regular schedule. */
332
332
void MaybeSendAddr (CNode& node, std::chrono::microseconds current_time);
333
333
334
+ /* * Send `feefilter` message. */
335
+ void MaybeSendFeefilter (CNode& node, std::chrono::microseconds current_time) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
336
+
334
337
const CChainParams& m_chainparams;
335
338
CConnman& m_connman;
336
339
CAddrMan& m_addrman;
@@ -4219,6 +4222,49 @@ void PeerManagerImpl::MaybeSendAddr(CNode& node, std::chrono::microseconds curre
4219
4222
}
4220
4223
}
4221
4224
4225
+ void PeerManagerImpl::MaybeSendFeefilter (CNode& pto, std::chrono::microseconds current_time)
4226
+ {
4227
+ AssertLockHeld (cs_main);
4228
+
4229
+ if (m_ignore_incoming_txs) return ;
4230
+ if (!pto.m_tx_relay ) return ;
4231
+ if (pto.GetCommonVersion () < FEEFILTER_VERSION) return ;
4232
+ // peers with the forcerelay permission should not filter txs to us
4233
+ if (pto.HasPermission (NetPermissionFlags::ForceRelay)) return ;
4234
+
4235
+ CAmount currentFilter = m_mempool.GetMinFee (gArgs .GetArg (" -maxmempool" , DEFAULT_MAX_MEMPOOL_SIZE) * 1000000 ).GetFeePerK ();
4236
+ static FeeFilterRounder g_filter_rounder{CFeeRate{DEFAULT_MIN_RELAY_TX_FEE}};
4237
+
4238
+ if (m_chainman.ActiveChainstate ().IsInitialBlockDownload ()) {
4239
+ // Received tx-inv messages are discarded when the active
4240
+ // chainstate is in IBD, so tell the peer to not send them.
4241
+ currentFilter = MAX_MONEY;
4242
+ } else {
4243
+ static const CAmount MAX_FILTER{g_filter_rounder.round (MAX_MONEY)};
4244
+ if (pto.m_tx_relay ->lastSentFeeFilter == MAX_FILTER) {
4245
+ // Send the current filter if we sent MAX_FILTER previously
4246
+ // and made it out of IBD.
4247
+ pto.m_tx_relay ->m_next_send_feefilter = 0us;
4248
+ }
4249
+ }
4250
+ if (current_time > pto.m_tx_relay ->m_next_send_feefilter ) {
4251
+ CAmount filterToSend = g_filter_rounder.round (currentFilter);
4252
+ // We always have a fee filter of at least minRelayTxFee
4253
+ filterToSend = std::max (filterToSend, ::minRelayTxFee.GetFeePerK ());
4254
+ if (filterToSend != pto.m_tx_relay ->lastSentFeeFilter ) {
4255
+ m_connman.PushMessage (&pto, CNetMsgMaker (pto.GetCommonVersion ()).Make (NetMsgType::FEEFILTER, filterToSend));
4256
+ pto.m_tx_relay ->lastSentFeeFilter = filterToSend;
4257
+ }
4258
+ pto.m_tx_relay ->m_next_send_feefilter = PoissonNextSend (current_time, AVG_FEEFILTER_BROADCAST_INTERVAL);
4259
+ }
4260
+ // If the fee filter has changed substantially and it's still more than MAX_FEEFILTER_CHANGE_DELAY
4261
+ // until scheduled broadcast, then move the broadcast to within MAX_FEEFILTER_CHANGE_DELAY.
4262
+ else if (current_time + MAX_FEEFILTER_CHANGE_DELAY < pto.m_tx_relay ->m_next_send_feefilter &&
4263
+ (currentFilter < 3 * pto.m_tx_relay ->lastSentFeeFilter / 4 || currentFilter > 4 * pto.m_tx_relay ->lastSentFeeFilter / 3 )) {
4264
+ pto.m_tx_relay ->m_next_send_feefilter = current_time + GetRandomDuration<std::chrono::microseconds>(MAX_FEEFILTER_CHANGE_DELAY);
4265
+ }
4266
+ }
4267
+
4222
4268
namespace {
4223
4269
class CompareInvMempoolOrder
4224
4270
{
@@ -4705,45 +4751,7 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
4705
4751
if (!vGetData.empty ())
4706
4752
m_connman.PushMessage (pto, msgMaker.Make (NetMsgType::GETDATA, vGetData));
4707
4753
4708
- //
4709
- // Message: feefilter
4710
- //
4711
- if (pto->m_tx_relay != nullptr &&
4712
- !m_ignore_incoming_txs &&
4713
- pto->GetCommonVersion () >= FEEFILTER_VERSION &&
4714
- !pto->HasPermission (NetPermissionFlags::ForceRelay) // peers with the forcerelay permission should not filter txs to us
4715
- ) {
4716
- CAmount currentFilter = m_mempool.GetMinFee (gArgs .GetArg (" -maxmempool" , DEFAULT_MAX_MEMPOOL_SIZE) * 1000000 ).GetFeePerK ();
4717
- static FeeFilterRounder g_filter_rounder{CFeeRate{DEFAULT_MIN_RELAY_TX_FEE}};
4718
- if (m_chainman.ActiveChainstate ().IsInitialBlockDownload ()) {
4719
- // Received tx-inv messages are discarded when the active
4720
- // chainstate is in IBD, so tell the peer to not send them.
4721
- currentFilter = MAX_MONEY;
4722
- } else {
4723
- static const CAmount MAX_FILTER{g_filter_rounder.round (MAX_MONEY)};
4724
- if (pto->m_tx_relay ->lastSentFeeFilter == MAX_FILTER) {
4725
- // Send the current filter if we sent MAX_FILTER previously
4726
- // and made it out of IBD.
4727
- pto->m_tx_relay ->m_next_send_feefilter = 0us;
4728
- }
4729
- }
4730
- if (current_time > pto->m_tx_relay ->m_next_send_feefilter ) {
4731
- CAmount filterToSend = g_filter_rounder.round (currentFilter);
4732
- // We always have a fee filter of at least minRelayTxFee
4733
- filterToSend = std::max (filterToSend, ::minRelayTxFee.GetFeePerK ());
4734
- if (filterToSend != pto->m_tx_relay ->lastSentFeeFilter ) {
4735
- m_connman.PushMessage (pto, msgMaker.Make (NetMsgType::FEEFILTER, filterToSend));
4736
- pto->m_tx_relay ->lastSentFeeFilter = filterToSend;
4737
- }
4738
- pto->m_tx_relay ->m_next_send_feefilter = PoissonNextSend (current_time, AVG_FEEFILTER_BROADCAST_INTERVAL);
4739
- }
4740
- // If the fee filter has changed substantially and it's still more than MAX_FEEFILTER_CHANGE_DELAY
4741
- // until scheduled broadcast, then move the broadcast to within MAX_FEEFILTER_CHANGE_DELAY.
4742
- else if (current_time + MAX_FEEFILTER_CHANGE_DELAY < pto->m_tx_relay ->m_next_send_feefilter &&
4743
- (currentFilter < 3 * pto->m_tx_relay ->lastSentFeeFilter / 4 || currentFilter > 4 * pto->m_tx_relay ->lastSentFeeFilter / 3 )) {
4744
- pto->m_tx_relay ->m_next_send_feefilter = current_time + GetRandomDuration<std::chrono::microseconds>(MAX_FEEFILTER_CHANGE_DELAY);
4745
- }
4746
- }
4754
+ MaybeSendFeefilter (*pto, current_time);
4747
4755
} // release cs_main
4748
4756
return true ;
4749
4757
}
0 commit comments