158 bool fValidatedHeaders;
159 std::unique_ptr<PartiallyDownloadedBlock> partialBlock;
179 Mutex m_misbehavior_mutex;
181 int m_misbehavior_score
GUARDED_BY(m_misbehavior_mutex){0};
183 bool m_should_discourage
GUARDED_BY(m_misbehavior_mutex){
false};
186 Mutex m_block_inv_mutex;
190 std::vector<uint256> m_blocks_for_inv_relay
GUARDED_BY(m_block_inv_mutex);
194 std::vector<uint256> m_blocks_for_headers_relay
GUARDED_BY(m_block_inv_mutex);
202 std::atomic<int> m_starting_height{-1};
205 std::atomic<uint64_t> m_ping_nonce_sent{0};
207 std::atomic<std::chrono::microseconds> m_ping_start{0us};
209 std::atomic<bool> m_ping_queued{
false};
215 Mutex m_getdata_requests_mutex;
217 std::deque<CInv> m_getdata_requests
GUARDED_BY(m_getdata_requests_mutex);
219 explicit Peer(
NodeId id) : m_id(
id) {}
222 using PeerRef = std::shared_ptr<Peer>;
229 bool ignore_incoming_txs);
249 void SetBestHeight(
int height)
override { m_best_height = height; };
250 void Misbehaving(
const NodeId pnode,
const int howmuch,
const std::string& message)
override;
252 const std::chrono::microseconds time_received,
const std::atomic<bool>& interruptMsgProc)
override;
262 void ReattemptInitialBroadcast(
CScheduler& scheduler)
const;
266 PeerRef GetPeerRef(
NodeId id)
const;
270 PeerRef RemovePeer(
NodeId id);
283 bool via_compact_block,
const std::string& message =
"");
298 bool MaybeDiscourageAndDisconnect(
CNode& pnode, Peer& peer);
302 void ProcessHeadersMessage(
CNode& pfrom,
const Peer& peer,
303 const std::vector<CBlockHeader>& headers,
304 bool via_compact_block);
311 void AddTxAnnouncement(
const CNode&
node,
const GenTxid& gtxid, std::chrono::microseconds current_time)
315 void PushNodeVersion(
CNode& pnode, int64_t nTime);
319 void MaybeSendPing(
CNode& node_to, Peer& peer);
330 std::atomic<int> m_best_height{-1};
332 int64_t m_stale_tip_check_time;
335 const bool m_ignore_incoming_txs;
339 bool m_initial_sync_finished{
false};
343 mutable Mutex m_peer_mutex;
350 std::map<NodeId, PeerRef> m_peer_map
GUARDED_BY(m_peer_mutex);
413 Mutex m_recent_confirmed_transactions_mutex;
414 std::unique_ptr<CRollingBloomFilter> m_recent_confirmed_transactions
GUARDED_BY(m_recent_confirmed_transactions_mutex);
434 std::map<uint256, std::pair<NodeId, std::list<QueuedBlock>::iterator> > mapBlocksInFlight
GUARDED_BY(
cs_main);
437 std::atomic<int64_t> m_last_tip_update{0};
445 typedef std::map<uint256, CTransactionRef> MapRelay;
448 std::deque<std::pair<std::chrono::microseconds, MapRelay::iterator>> g_relay_expiration
GUARDED_BY(
cs_main);
502 int nUnconnectingHeaders;
506 std::chrono::microseconds m_headers_sync_timeout{0us};
508 std::chrono::microseconds m_stalling_since{0us};
509 std::list<QueuedBlock> vBlocksInFlight;
511 std::chrono::microseconds m_downloading_since{0us};
513 int nBlocksInFlightValidHeaders;
515 bool fPreferredDownload;
519 bool fPreferHeaderAndIDs;
525 bool fProvidesHeaderAndIDs;
529 bool fWantsCmpctWitness;
534 bool fSupportsDesiredCmpctVersion;
560 struct ChainSyncTimeoutState {
566 bool m_sent_getheaders;
571 ChainSyncTimeoutState m_chain_sync;
574 int64_t m_last_block_announcement;
583 bool m_wtxid_relay{
false};
585 CNodeState(
CAddress addrIn,
bool is_inbound)
586 : address(addrIn), m_is_inbound(is_inbound)
588 pindexBestKnownBlock =
nullptr;
589 hashLastUnknownBlock.
SetNull();
590 pindexLastCommonBlock =
nullptr;
591 pindexBestHeaderSent =
nullptr;
592 nUnconnectingHeaders = 0;
593 fSyncStarted =
false;
595 nBlocksInFlightValidHeaders = 0;
596 fPreferredDownload =
false;
597 fPreferHeaders =
false;
598 fPreferHeaderAndIDs =
false;
599 fProvidesHeaderAndIDs =
false;
600 fHaveWitness =
false;
601 fWantsCmpctWitness =
false;
602 fSupportsDesiredCmpctVersion =
false;
603 m_chain_sync = { 0,
nullptr,
false,
false };
604 m_last_block_announcement = 0;
605 m_recently_announced_invs.
reset();
613 std::map<NodeId, CNodeState>::iterator
it = mapNodeState.find(pnode);
614 if (
it == mapNodeState.end())
621 nPreferredDownload -= state->fPreferredDownload;
624 state->fPreferredDownload = (!
node.IsInboundConn() ||
node.HasPermission(
PF_NOBAN)) && !
node.IsAddrFetchConn() && !
node.fClient;
626 nPreferredDownload += state->fPreferredDownload;
629 bool PeerManagerImpl::MarkBlockAsReceived(
const uint256& hash)
631 std::map<uint256, std::pair<NodeId, std::list<QueuedBlock>::iterator> >::iterator itInFlight = mapBlocksInFlight.find(hash);
632 if (itInFlight != mapBlocksInFlight.end()) {
633 CNodeState *state = State(itInFlight->second.first);
635 state->nBlocksInFlightValidHeaders -= itInFlight->second.second->fValidatedHeaders;
636 if (state->nBlocksInFlightValidHeaders == 0 && itInFlight->second.second->fValidatedHeaders) {
638 nPeersWithValidatedDownloads--;
640 if (state->vBlocksInFlight.begin() == itInFlight->second.second) {
642 state->m_downloading_since = std::max(state->m_downloading_since, GetTime<std::chrono::microseconds>());
644 state->vBlocksInFlight.erase(itInFlight->second.second);
645 state->nBlocksInFlight--;
646 state->m_stalling_since = 0us;
647 mapBlocksInFlight.erase(itInFlight);
653 bool PeerManagerImpl::MarkBlockAsInFlight(
NodeId nodeid,
const uint256& hash,
const CBlockIndex* pindex, std::list<QueuedBlock>::iterator** pit)
655 CNodeState *state = State(nodeid);
659 std::map<uint256, std::pair<NodeId, std::list<QueuedBlock>::iterator> >::iterator itInFlight = mapBlocksInFlight.find(hash);
660 if (itInFlight != mapBlocksInFlight.end() && itInFlight->second.first == nodeid) {
662 *pit = &itInFlight->second.second;
668 MarkBlockAsReceived(hash);
670 std::list<QueuedBlock>::iterator
it = state->vBlocksInFlight.insert(state->vBlocksInFlight.end(),
671 {hash, pindex, pindex != nullptr, std::unique_ptr<PartiallyDownloadedBlock>(pit ? new PartiallyDownloadedBlock(&m_mempool) : nullptr)});
672 state->nBlocksInFlight++;
673 state->nBlocksInFlightValidHeaders +=
it->fValidatedHeaders;
674 if (state->nBlocksInFlight == 1) {
676 state->m_downloading_since = GetTime<std::chrono::microseconds>();
678 if (state->nBlocksInFlightValidHeaders == 1 && pindex !=
nullptr) {
679 nPeersWithValidatedDownloads++;
681 itInFlight = mapBlocksInFlight.insert(std::make_pair(hash, std::make_pair(nodeid,
it))).first;
683 *pit = &itInFlight->second.second;
689 CNodeState *state = State(nodeid);
692 if (!state->hashLastUnknownBlock.IsNull()) {
695 if (state->pindexBestKnownBlock ==
nullptr || pindex->
nChainWork >= state->pindexBestKnownBlock->nChainWork) {
696 state->pindexBestKnownBlock = pindex;
698 state->hashLastUnknownBlock.SetNull();
705 CNodeState *state = State(nodeid);
708 ProcessBlockAvailability(nodeid);
713 if (state->pindexBestKnownBlock ==
nullptr || pindex->
nChainWork >= state->pindexBestKnownBlock->nChainWork) {
714 state->pindexBestKnownBlock = pindex;
718 state->hashLastUnknownBlock = hash;
722 void PeerManagerImpl::MaybeSetPeerAsAnnouncingHeaderAndIDs(
NodeId nodeid)
725 CNodeState* nodestate = State(nodeid);
726 if (!nodestate || !nodestate->fSupportsDesiredCmpctVersion) {
730 if (nodestate->fProvidesHeaderAndIDs) {
731 for (std::list<NodeId>::iterator
it = lNodesAnnouncingHeaderAndIDs.begin();
it != lNodesAnnouncingHeaderAndIDs.end();
it++) {
733 lNodesAnnouncingHeaderAndIDs.erase(
it);
734 lNodesAnnouncingHeaderAndIDs.push_back(nodeid);
741 if (lNodesAnnouncingHeaderAndIDs.size() >= 3) {
744 m_connman.ForNode(lNodesAnnouncingHeaderAndIDs.front(), [
this, nCMPCTBLOCKVersion](
CNode* pnodeStop){
747 pnodeStop->m_bip152_highbandwidth_to =
false;
750 lNodesAnnouncingHeaderAndIDs.pop_front();
755 lNodesAnnouncingHeaderAndIDs.push_back(pfrom->
GetId());
761 bool PeerManagerImpl::TipMayBeStale()
765 if (m_last_tip_update == 0) {
778 if (state->pindexBestKnownBlock && pindex == state->pindexBestKnownBlock->GetAncestor(pindex->
nHeight))
780 if (state->pindexBestHeaderSent && pindex == state->pindexBestHeaderSent->GetAncestor(pindex->
nHeight))
785 void PeerManagerImpl::FindNextBlocksToDownload(
NodeId nodeid,
unsigned int count, std::vector<const CBlockIndex*>& vBlocks,
NodeId& nodeStaller)
790 vBlocks.reserve(vBlocks.size() +
count);
791 CNodeState *state = State(nodeid);
795 ProcessBlockAvailability(nodeid);
797 if (state->pindexBestKnownBlock ==
nullptr || state->pindexBestKnownBlock->nChainWork < ::
ChainActive().Tip()->nChainWork || state->pindexBestKnownBlock->nChainWork <
nMinimumChainWork) {
802 if (state->pindexLastCommonBlock ==
nullptr) {
805 state->pindexLastCommonBlock =
::ChainActive()[std::min(state->pindexBestKnownBlock->nHeight, ::
ChainActive().Height())];
810 state->pindexLastCommonBlock =
LastCommonAncestor(state->pindexLastCommonBlock, state->pindexBestKnownBlock);
811 if (state->pindexLastCommonBlock == state->pindexBestKnownBlock)
815 std::vector<const CBlockIndex*> vToFetch;
816 const CBlockIndex *pindexWalk = state->pindexLastCommonBlock;
821 int nMaxHeight = std::min<int>(state->pindexBestKnownBlock->nHeight, nWindowEnd + 1);
823 while (pindexWalk->
nHeight < nMaxHeight) {
827 int nToFetch = std::min(nMaxHeight - pindexWalk->
nHeight, std::max<int>(
count - vBlocks.size(), 128));
828 vToFetch.resize(nToFetch);
829 pindexWalk = state->pindexBestKnownBlock->GetAncestor(pindexWalk->
nHeight + nToFetch);
830 vToFetch[nToFetch - 1] = pindexWalk;
831 for (
unsigned int i = nToFetch - 1; i > 0; i--) {
832 vToFetch[i - 1] = vToFetch[i]->
pprev;
850 state->pindexLastCommonBlock = pindex;
851 }
else if (mapBlocksInFlight.count(pindex->
GetBlockHash()) == 0) {
853 if (pindex->
nHeight > nWindowEnd) {
855 if (vBlocks.size() == 0 && waitingfor != nodeid) {
857 nodeStaller = waitingfor;
861 vBlocks.push_back(pindex);
862 if (vBlocks.size() ==
count) {
865 }
else if (waitingfor == -1) {
867 waitingfor = mapBlocksInFlight[pindex->
GetBlockHash()].first;
875 void PeerManagerImpl::PushNodeVersion(
CNode& pnode, int64_t nTime)
882 const int nNodeStartingHeight{m_best_height};
891 const bool tx_relay = !m_ignore_incoming_txs && pnode.
m_tx_relay !=
nullptr;
896 LogPrint(
BCLog::NET,
"send version message: version %d, blocks=%d, us=%s, them=%s, txrelay=%d, peer=%d\n",
PROTOCOL_VERSION, nNodeStartingHeight, addrMe.
ToString(), addrYou.
ToString(), tx_relay, nodeid);
898 LogPrint(
BCLog::NET,
"send version message: version %d, blocks=%d, us=%s, txrelay=%d, peer=%d\n",
PROTOCOL_VERSION, nNodeStartingHeight, addrMe.
ToString(), tx_relay, nodeid);
902 void PeerManagerImpl::AddTxAnnouncement(
const CNode&
node,
const GenTxid& gtxid, std::chrono::microseconds current_time)
910 const CNodeState* state = State(nodeid);
919 auto delay = std::chrono::microseconds{0};
920 const bool preferred = state->fPreferredDownload;
923 const bool overloaded = !
node.HasPermission(
PF_RELAY) &&
926 m_txrequest.ReceivedInv(nodeid, gtxid, preferred, current_time + delay);
934 CNodeState *state = State(
node);
935 if (state) state->m_last_block_announcement = time_in_seconds;
938 void PeerManagerImpl::InitializeNode(
CNode *pnode)
945 mapNodeState.emplace_hint(mapNodeState.end(), std::piecewise_construct, std::forward_as_tuple(nodeid), std::forward_as_tuple(addr, pnode->
IsInboundConn()));
946 assert(m_txrequest.Count(nodeid) == 0);
949 PeerRef peer = std::make_shared<Peer>(nodeid);
951 m_peer_map.emplace_hint(m_peer_map.end(), nodeid, std::move(peer));
954 PushNodeVersion(*pnode,
GetTime());
958 void PeerManagerImpl::ReattemptInitialBroadcast(
CScheduler& scheduler)
const
960 std::set<uint256> unbroadcast_txids = m_mempool.GetUnbroadcastTxs();
962 for (
const auto& txid : unbroadcast_txids) {
969 m_mempool.RemoveUnbroadcastTx(txid,
true);
975 const std::chrono::milliseconds delta = std::chrono::minutes{10} +
GetRandMillis(std::chrono::minutes{5});
976 scheduler.
scheduleFromNow([&] { ReattemptInitialBroadcast(scheduler); }, delta);
979 void PeerManagerImpl::FinalizeNode(
const CNode&
node,
bool& fUpdateConnectionTime)
982 fUpdateConnectionTime =
false;
991 PeerRef peer = RemovePeer(nodeid);
993 misbehavior =
WITH_LOCK(peer->m_misbehavior_mutex,
return peer->m_misbehavior_score);
995 CNodeState *state = State(nodeid);
998 if (state->fSyncStarted)
1001 if (
node.fSuccessfullyConnected && misbehavior == 0 &&
1002 !
node.IsBlockOnlyConn() && !
node.IsInboundConn()) {
1004 fUpdateConnectionTime =
true;
1007 for (
const QueuedBlock& entry : state->vBlocksInFlight) {
1008 mapBlocksInFlight.erase(entry.hash);
1011 m_txrequest.DisconnectedPeer(nodeid);
1012 nPreferredDownload -= state->fPreferredDownload;
1013 nPeersWithValidatedDownloads -= (state->nBlocksInFlightValidHeaders != 0);
1014 assert(nPeersWithValidatedDownloads >= 0);
1015 m_outbound_peers_with_protect_from_disconnect -= state->m_chain_sync.m_protect;
1016 assert(m_outbound_peers_with_protect_from_disconnect >= 0);
1017 m_wtxid_relay_peers -= state->m_wtxid_relay;
1018 assert(m_wtxid_relay_peers >= 0);
1020 mapNodeState.erase(nodeid);
1022 if (mapNodeState.empty()) {
1024 assert(mapBlocksInFlight.empty());
1025 assert(nPreferredDownload == 0);
1026 assert(nPeersWithValidatedDownloads == 0);
1027 assert(m_outbound_peers_with_protect_from_disconnect == 0);
1028 assert(m_wtxid_relay_peers == 0);
1029 assert(m_txrequest.Size() == 0);
1034 PeerRef PeerManagerImpl::GetPeerRef(
NodeId id)
const
1037 auto it = m_peer_map.find(
id);
1038 return it != m_peer_map.end() ?
it->second :
nullptr;
1041 PeerRef PeerManagerImpl::RemovePeer(
NodeId id)
1045 auto it = m_peer_map.find(
id);
1046 if (
it != m_peer_map.end()) {
1047 ret = std::move(
it->second);
1048 m_peer_map.erase(
it);
1057 CNodeState* state = State(nodeid);
1058 if (state ==
nullptr)
1060 stats.
nSyncHeight = state->pindexBestKnownBlock ? state->pindexBestKnownBlock->nHeight : -1;
1061 stats.
nCommonHeight = state->pindexLastCommonBlock ? state->pindexLastCommonBlock->nHeight : -1;
1062 for (
const QueuedBlock& queue : state->vBlocksInFlight) {
1068 PeerRef peer = GetPeerRef(nodeid);
1069 if (peer ==
nullptr)
return false;
1077 std::chrono::microseconds ping_wait{0};
1078 if ((0 != peer->m_ping_nonce_sent) && (0 != peer->m_ping_start.load().count())) {
1079 ping_wait = GetTime<std::chrono::microseconds>() - peer->m_ping_start.load();
1087 void PeerManagerImpl::AddToCompactExtraTransactions(
const CTransactionRef& tx)
1090 if (max_extra_txn <= 0)
1092 if (!vExtraTxnForCompact.size())
1093 vExtraTxnForCompact.resize(max_extra_txn);
1094 vExtraTxnForCompact[vExtraTxnForCompactIt] = std::make_pair(tx->GetWitnessHash(), tx);
1095 vExtraTxnForCompactIt = (vExtraTxnForCompactIt + 1) % max_extra_txn;
1098 void PeerManagerImpl::Misbehaving(
const NodeId pnode,
const int howmuch,
const std::string& message)
1102 PeerRef peer = GetPeerRef(pnode);
1103 if (peer ==
nullptr)
return;
1105 LOCK(peer->m_misbehavior_mutex);
1106 peer->m_misbehavior_score += howmuch;
1107 const std::string message_prefixed = message.empty() ?
"" : (
": " + message);
1109 LogPrint(
BCLog::NET,
"Misbehaving: peer=%d (%d -> %d) DISCOURAGE THRESHOLD EXCEEDED%s\n", pnode, peer->m_misbehavior_score - howmuch, peer->m_misbehavior_score, message_prefixed);
1110 peer->m_should_discourage =
true;
1112 LogPrint(
BCLog::NET,
"Misbehaving: peer=%d (%d -> %d)%s\n", pnode, peer->m_misbehavior_score - howmuch, peer->m_misbehavior_score, message_prefixed);
1117 bool via_compact_block,
const std::string& message)
1125 if (!via_compact_block) {
1126 Misbehaving(nodeid, 100, message);
1133 CNodeState *node_state = State(nodeid);
1134 if (node_state ==
nullptr) {
1140 if (!via_compact_block && !node_state->m_is_inbound) {
1141 Misbehaving(nodeid, 100, message);
1149 Misbehaving(nodeid, 100, message);
1154 Misbehaving(nodeid, 10, message);
1160 if (message !=
"") {
1166 bool PeerManagerImpl::MaybePunishNodeForTx(
NodeId nodeid,
const TxValidationState& state,
const std::string& message)
1173 Misbehaving(nodeid, 100, message);
1187 if (message !=
"") {
1206 if (::
ChainActive().Contains(pindex))
return true;
1214 bool ignore_incoming_txs)
1216 return std::make_unique<PeerManagerImpl>(chainparams, connman, banman, scheduler, chainman, pool, ignore_incoming_txs);
1221 bool ignore_incoming_txs)
1222 : m_chainparams(chainparams),
1225 m_chainman(chainman),
1227 m_stale_tip_check_time(0),
1228 m_ignore_incoming_txs(ignore_incoming_txs)
1252 const std::chrono::milliseconds delta = std::chrono::minutes{10} +
GetRandMillis(std::chrono::minutes{5});
1253 scheduler.
scheduleFromNow([&] { ReattemptInitialBroadcast(scheduler); }, delta);
1261 void PeerManagerImpl::BlockConnected(
const std::shared_ptr<const CBlock>& pblock,
const CBlockIndex* pindex)
1263 m_orphanage.EraseForBlock(*pblock);
1264 m_last_tip_update =
GetTime();
1267 LOCK(m_recent_confirmed_transactions_mutex);
1268 for (
const auto& ptx : pblock->vtx) {
1269 m_recent_confirmed_transactions->insert(ptx->GetHash());
1270 if (ptx->GetHash() != ptx->GetWitnessHash()) {
1271 m_recent_confirmed_transactions->insert(ptx->GetWitnessHash());
1277 for (
const auto& ptx : pblock->vtx) {
1278 m_txrequest.ForgetTxHash(ptx->GetHash());
1279 m_txrequest.ForgetTxHash(ptx->GetWitnessHash());
1284 void PeerManagerImpl::BlockDisconnected(
const std::shared_ptr<const CBlock> &block,
const CBlockIndex* pindex)
1294 LOCK(m_recent_confirmed_transactions_mutex);
1295 m_recent_confirmed_transactions->reset();
1309 void PeerManagerImpl::NewPoWValidBlock(
const CBlockIndex *pindex,
const std::shared_ptr<const CBlock>& pblock)
1311 std::shared_ptr<const CBlockHeaderAndShortTxIDs> pcmpctblock = std::make_shared<const CBlockHeaderAndShortTxIDs> (*pblock,
true);
1316 static int nHighestFastAnnounce = 0;
1317 if (pindex->
nHeight <= nHighestFastAnnounce)
1319 nHighestFastAnnounce = pindex->
nHeight;
1322 uint256 hashBlock(pblock->GetHash());
1326 most_recent_block_hash = hashBlock;
1327 most_recent_block = pblock;
1328 most_recent_compact_block = pcmpctblock;
1329 fWitnessesPresentInMostRecentCompactBlock = fWitnessEnabled;
1338 ProcessBlockAvailability(pnode->
GetId());
1339 CNodeState &state = *State(pnode->
GetId());
1342 if (state.fPreferHeaderAndIDs && (!fWitnessEnabled || state.fWantsCmpctWitness) &&
1343 !PeerHasHeader(&state, pindex) && PeerHasHeader(&state, pindex->
pprev)) {
1345 LogPrint(
BCLog::NET,
"%s sending header-and-ids %s to peer=%d\n",
"PeerManager::NewPoWValidBlock",
1346 hashBlock.ToString(), pnode->
GetId());
1348 state.pindexBestHeaderSent = pindex;
1357 void PeerManagerImpl::UpdatedBlockTip(
const CBlockIndex *pindexNew,
const CBlockIndex *pindexFork,
bool fInitialDownload)
1359 SetBestHeight(pindexNew->
nHeight);
1363 if (fInitialDownload)
return;
1366 std::vector<uint256> vHashes;
1368 while (pindexToAnnounce != pindexFork) {
1370 pindexToAnnounce = pindexToAnnounce->
pprev;
1380 for (
auto&
it : m_peer_map) {
1381 Peer& peer = *
it.second;
1382 LOCK(peer.m_block_inv_mutex);
1384 peer.m_blocks_for_headers_relay.push_back(hash);
1389 m_connman.WakeMessageHandler();
1401 std::map<uint256, std::pair<NodeId, bool>>::iterator
it = mapBlockSource.find(hash);
1406 it != mapBlockSource.end() &&
1407 State(
it->second.first)) {
1408 MaybePunishNodeForBlock(
it->second.first, state, !
it->second.second);
1418 mapBlocksInFlight.count(hash) == mapBlocksInFlight.size()) {
1419 if (
it != mapBlockSource.end()) {
1420 MaybeSetPeerAsAnnouncingHeaderAndIDs(
it->second.first);
1423 if (
it != mapBlockSource.end())
1424 mapBlockSource.erase(
it);
1433 bool PeerManagerImpl::AlreadyHaveTx(
const GenTxid& gtxid)
1436 if (::
ChainActive().Tip()->GetBlockHash() != hashRecentRejectsChainTip) {
1442 recentRejects->reset();
1447 if (m_orphanage.HaveTx(gtxid))
return true;
1450 LOCK(m_recent_confirmed_transactions_mutex);
1451 if (m_recent_confirmed_transactions->contains(hash))
return true;
1454 return recentRejects->contains(hash) || m_mempool.exists(gtxid);
1459 return g_chainman.m_blockman.LookupBlockIndex(block_hash) !=
nullptr;
1462 void PeerManagerImpl::SendPings()
1465 for(
auto&
it : m_peer_map)
it.second->m_ping_queued =
true;
1473 CNodeState* state = State(pnode->
GetId());
1474 if (state ==
nullptr)
return;
1475 if (state->m_wtxid_relay) {
1506 uint64_t hashAddr = addr.
GetHash();
1511 unsigned int nRelayNodes = (fReachable || (hasher.
Finalize() & 1)) ? 2 : 1;
1513 std::array<std::pair<uint64_t, CNode*>,2> best{{{0,
nullptr}, {0,
nullptr}}};
1514 assert(nRelayNodes <= best.size());
1516 auto sortfunc = [&best, &hasher, nRelayNodes, &originator, &addr](
CNode* pnode) {
1519 for (
unsigned int i = 0; i < nRelayNodes; i++) {
1520 if (hashKey > best[i].first) {
1521 std::copy(best.begin() + i, best.begin() + nRelayNodes - 1, best.begin() + i + 1);
1522 best[i] = std::make_pair(hashKey, pnode);
1529 auto pushfunc = [&addr, &best, nRelayNodes, &insecure_rand] {
1530 for (
unsigned int i = 0; i < nRelayNodes && best[i].first != 0; i++) {
1531 best[i].second->PushAddress(addr, insecure_rand);
1541 std::shared_ptr<const CBlock> a_recent_block;
1542 std::shared_ptr<const CBlockHeaderAndShortTxIDs> a_recent_compact_block;
1543 bool fWitnessesPresentInARecentCompactBlock;
1547 a_recent_block = most_recent_block;
1548 a_recent_compact_block = most_recent_compact_block;
1549 fWitnessesPresentInARecentCompactBlock = fWitnessesPresentInMostRecentCompactBlock;
1552 bool need_activate_chain =
false;
1564 need_activate_chain =
true;
1568 if (need_activate_chain) {
1570 if (!::
ChainstateActive().ActivateBestChain(state, chainparams, a_recent_block)) {
1580 LogPrint(
BCLog::NET,
"%s: ignoring request from peer=%i for old block that isn't in the main chain\n", __func__, pfrom.
GetId());
1600 LogPrint(
BCLog::NET,
"Ignore block request below NODE_NETWORK_LIMITED threshold from peer=%d\n", pfrom.
GetId());
1610 std::shared_ptr<const CBlock> pblock;
1611 if (a_recent_block && a_recent_block->GetHash() == pindex->
GetBlockHash()) {
1612 pblock = a_recent_block;
1616 std::vector<uint8_t> block_data;
1618 assert(!
"cannot load block from disk");
1624 std::shared_ptr<CBlock> pblockRead = std::make_shared<CBlock>();
1626 assert(!
"cannot load block from disk");
1627 pblock = pblockRead;
1635 bool sendMerkleBlock =
false;
1640 sendMerkleBlock =
true;
1644 if (sendMerkleBlock) {
1652 typedef std::pair<unsigned int, uint256> PairType;
1663 bool fPeerWantsWitness = State(pfrom.
GetId())->fWantsCmpctWitness;
1666 if ((fPeerWantsWitness || !fWitnessesPresentInARecentCompactBlock) && a_recent_compact_block && a_recent_compact_block->header.GetHash() == pindex->
GetBlockHash()) {
1679 LOCK(peer.m_block_inv_mutex);
1681 if (inv.
hash == peer.m_continuation_block) {
1685 std::vector<CInv> vInv;
1688 peer.m_continuation_block.SetNull();
1694 CTransactionRef PeerManagerImpl::FindTxForGetData(
const CNode& peer,
const GenTxid& gtxid,
const std::chrono::seconds mempool_req,
const std::chrono::seconds now)
1696 auto txinfo = m_mempool.info(gtxid);
1702 return std::move(txinfo.tx);
1709 if (State(peer.
GetId())->m_recently_announced_invs.contains(gtxid.
GetHash())) {
1711 if (txinfo.tx)
return std::move(txinfo.tx);
1713 auto mi = mapRelay.find(gtxid.
GetHash());
1714 if (mi != mapRelay.end())
return mi->second;
1721 void PeerManagerImpl::ProcessGetData(
CNode& pfrom, Peer& peer,
const std::atomic<bool>& interruptMsgProc)
1725 std::deque<CInv>::iterator
it = peer.m_getdata_requests.begin();
1726 std::vector<CInv> vNotFound;
1729 const std::chrono::seconds now = GetTime<std::chrono::seconds>();
1731 const std::chrono::seconds mempool_req = pfrom.
m_tx_relay !=
nullptr ? pfrom.
m_tx_relay->m_last_mempool_req.load()
1732 : std::chrono::seconds::min();
1737 while (
it != peer.m_getdata_requests.end() &&
it->IsGenTxMsg()) {
1738 if (interruptMsgProc)
return;
1754 m_connman.PushMessage(&pfrom, msgMaker.Make(nSendFlags,
NetMsgType::TX, *tx));
1755 m_mempool.RemoveUnbroadcastTx(tx->GetHash());
1757 std::vector<uint256> parent_ids_to_add;
1760 auto txiter = m_mempool.GetIter(tx->GetHash());
1763 parent_ids_to_add.reserve(parents.size());
1766 parent_ids_to_add.push_back(parent.GetTx().GetHash());
1771 for (
const uint256& parent_txid : parent_ids_to_add) {
1775 State(pfrom.
GetId())->m_recently_announced_invs.insert(parent_txid);
1779 vNotFound.push_back(inv);
1785 if (
it != peer.m_getdata_requests.end() && !pfrom.
fPauseSend) {
1794 peer.m_getdata_requests.erase(peer.m_getdata_requests.begin(),
it);
1796 if (!vNotFound.empty()) {
1816 uint32_t nFetchFlags = 0;
1826 for (
size_t i = 0; i < req.
indexes.size(); i++) {
1828 Misbehaving(pfrom.
GetId(), 100,
"getblocktxn with out-of-bounds tx indices");
1839 void PeerManagerImpl::ProcessHeadersMessage(
CNode& pfrom,
const Peer& peer,
1840 const std::vector<CBlockHeader>& headers,
1841 bool via_compact_block)
1844 size_t nCount = headers.size();
1851 bool received_new_header =
false;
1855 CNodeState *nodestate = State(pfrom.
GetId());
1866 nodestate->nUnconnectingHeaders++;
1868 LogPrint(
BCLog::NET,
"received header %s: missing prev block %s, sending getheaders (%d) to end (peer=%d, nUnconnectingHeaders=%d)\n",
1870 headers[0].hashPrevBlock.ToString(),
1872 pfrom.
GetId(), nodestate->nUnconnectingHeaders);
1876 UpdateBlockAvailability(pfrom.
GetId(), headers.back().GetHash());
1879 Misbehaving(pfrom.
GetId(), 20,
strprintf(
"%d non-connecting headers", nodestate->nUnconnectingHeaders));
1886 if (!hashLastBlock.
IsNull() && header.hashPrevBlock != hashLastBlock) {
1887 Misbehaving(pfrom.
GetId(), 20,
"non-continuous headers sequence");
1890 hashLastBlock = header.GetHash();
1895 if (!
g_chainman.m_blockman.LookupBlockIndex(hashLastBlock)) {
1896 received_new_header =
true;
1901 if (!m_chainman.ProcessNewBlockHeaders(headers, state, m_chainparams, &pindexLast)) {
1903 MaybePunishNodeForBlock(pfrom.
GetId(), state, via_compact_block,
"invalid header received");
1910 CNodeState *nodestate = State(pfrom.
GetId());
1911 if (nodestate->nUnconnectingHeaders > 0) {
1912 LogPrint(
BCLog::NET,
"peer=%d: resetting nUnconnectingHeaders (%d -> 0)\n", pfrom.
GetId(), nodestate->nUnconnectingHeaders);
1914 nodestate->nUnconnectingHeaders = 0;
1924 nodestate->m_last_block_announcement =
GetTime();
1932 pindexLast->
nHeight, pfrom.
GetId(), peer.m_starting_height);
1936 bool fCanDirectFetch = CanDirectFetch(m_chainparams.GetConsensus());
1940 std::vector<const CBlockIndex*> vToFetch;
1945 !mapBlocksInFlight.count(pindexWalk->
GetBlockHash()) &&
1948 vToFetch.push_back(pindexWalk);
1950 pindexWalk = pindexWalk->
pprev;
1961 std::vector<CInv> vGetData;
1974 if (vGetData.size() > 1) {
1978 if (vGetData.size() > 0) {
1979 if (nodestate->fSupportsDesiredCmpctVersion && vGetData.size() == 1 && mapBlocksInFlight.size() == 1 && pindexLast->
pprev->
IsValid(
BLOCK_VALID_CHAIN)) {
1992 if (nodestate->pindexBestKnownBlock && nodestate->pindexBestKnownBlock->nChainWork <
nMinimumChainWork) {
2002 LogPrintf(
"Disconnecting outbound peer %d -- headers chain has insufficient work\n", pfrom.
GetId());
2014 if (m_outbound_peers_with_protect_from_disconnect < MAX_OUTBOUND_PEERS_TO_PROTECT_FROM_DISCONNECT && nodestate->pindexBestKnownBlock->
nChainWork >= ::
ChainActive().Tip()->nChainWork && !nodestate->m_chain_sync.m_protect) {
2016 nodestate->m_chain_sync.m_protect =
true;
2017 ++m_outbound_peers_with_protect_from_disconnect;
2033 void PeerManagerImpl::ProcessOrphanTx(std::set<uint256>& orphan_work_set)
2038 while (!orphan_work_set.empty()) {
2040 orphan_work_set.erase(orphan_work_set.begin());
2042 const auto [porphanTx, from_peer] = m_orphanage.GetTx(orphanHash);
2043 if (porphanTx ==
nullptr)
continue;
2051 m_orphanage.AddChildrenToWorkSet(*porphanTx, orphan_work_set);
2052 m_orphanage.EraseTx(orphanHash);
2054 AddToCompactExtraTransactions(removedTx);
2064 MaybePunishNodeForTx(from_peer, state);
2084 recentRejects->insert(porphanTx->GetWitnessHash());
2096 recentRejects->insert(porphanTx->GetHash());
2099 m_orphanage.EraseTx(orphanHash);
2103 m_mempool.check(m_chainman.ActiveChainstate());
2123 const uint256& stop_hash, uint32_t max_height_diff,
2127 const bool supported_filter_type =
2130 if (!supported_filter_type) {
2132 peer.
GetId(),
static_cast<uint8_t
>(filter_type));
2139 stop_index =
g_chainman.m_blockman.LookupBlockIndex(stop_hash);
2150 uint32_t stop_height = stop_index->
nHeight;
2151 if (start_height > stop_height) {
2153 "start height %d and stop height %d\n",
2154 peer.
GetId(), start_height, stop_height);
2158 if (stop_height - start_height >= max_height_diff) {
2160 peer.
GetId(), stop_height - start_height + 1, max_height_diff);
2166 if (!filter_index) {
2187 uint8_t filter_type_ser;
2188 uint32_t start_height;
2191 vRecv >> filter_type_ser >> start_height >> stop_hash;
2202 std::vector<BlockFilter> filters;
2204 LogPrint(
BCLog::NET,
"Failed to find block filter in index: filter_type=%s, start_height=%d, stop_hash=%s\n",
2209 for (
const auto& filter : filters) {
2229 uint8_t filter_type_ser;
2230 uint32_t start_height;
2233 vRecv >> filter_type_ser >> start_height >> stop_hash;
2245 if (start_height > 0) {
2247 stop_index->
GetAncestor(
static_cast<int>(start_height - 1));
2249 LogPrint(
BCLog::NET,
"Failed to find block filter header in index: filter_type=%s, block_hash=%s\n",
2255 std::vector<uint256> filter_hashes;
2257 LogPrint(
BCLog::NET,
"Failed to find block filter hashes in index: filter_type=%s, start_height=%d, stop_hash=%s\n",
2284 uint8_t filter_type_ser;
2287 vRecv >> filter_type_ser >> stop_hash;
2294 std::numeric_limits<uint32_t>::max(),
2295 stop_index, filter_index)) {
2303 for (
int i = headers.size() - 1; i >= 0; i--) {
2308 LogPrint(
BCLog::NET,
"Failed to find block filter header in index: filter_type=%s, block_hash=%s\n",
2322 void PeerManagerImpl::ProcessMessage(
CNode& pfrom,
const std::string& msg_type,
CDataStream& vRecv,
2323 const std::chrono::microseconds time_received,
2324 const std::atomic<bool>& interruptMsgProc)
2328 PeerRef peer = GetPeerRef(pfrom.
GetId());
2329 if (peer ==
nullptr)
return;
2340 uint64_t nNonce = 1;
2341 uint64_t nServiceInt;
2344 std::string cleanSubVer;
2345 int starting_height = -1;
2348 vRecv >> nVersion >> nServiceInt >> nTime >> addrMe;
2355 m_connman.SetServices(pfrom.
addr, nServices);
2372 vRecv >> addrFrom >> nNonce;
2373 if (!vRecv.
empty()) {
2374 std::string strSubVer;
2378 if (!vRecv.
empty()) {
2379 vRecv >> starting_height;
2384 if (pfrom.
IsInboundConn() && !m_connman.CheckIncomingNonce(nNonce))
2412 if (greatest_common_version >= 70016) {
2426 pfrom.cleanSubVer = cleanSubVer;
2428 peer->m_starting_height = starting_height;
2444 State(pfrom.
GetId())->fHaveWitness =
true;
2450 UpdatePreferredDownload(pfrom, State(pfrom.
GetId()));
2499 m_connman.MarkAddressGood(pfrom.
addr);
2502 std::string remoteAddr;
2506 LogPrint(
BCLog::NET,
"receive version message: %s: version %d, blocks=%d, us=%s, txrelay=%d, peer=%d%s\n",
2508 peer->m_starting_height, addrMe.ToString(), fRelay, pfrom.
GetId(),
2511 int64_t nTimeOffset = nTime -
GetTime();
2516 if (greatest_common_version <= 70012) {
2517 CDataStream finalAlert(
ParseHex(
"60010000000000000000000000ffffff7f00000000ffffff7ffeffff7f01ffffff7f00000000ffffff7f00ffffff7f002f555247454e543a20416c657274206b657920636f6d70726f6d697365642c2075706772616465207265717569726564004630440220653febd6410f470f6bae11cad19c48413becb1ac2c17f908fd0fd53bdc3abd5202206d0e9c96fe88d4a0f01ed9dedae2b6f9e00da94cad0fecaae66ecf689bf71b50"),
SER_NETWORK,
PROTOCOL_VERSION);
2518 m_connman.PushMessage(&pfrom,
CNetMsgMaker(greatest_common_version).Make(
"alert", finalAlert));
2545 LogPrintf(
"New outbound peer connected: version: %d, blocks=%d, peer=%d%s (%s)\n",
2546 pfrom.
nVersion.load(), peer->m_starting_height,
2564 bool fAnnounceUsingCMPCTBLOCK =
false;
2565 uint64_t nCMPCTBLOCKVersion = 2;
2567 m_connman.PushMessage(&pfrom, msgMaker.Make(
NetMsgType::SENDCMPCT, fAnnounceUsingCMPCTBLOCK, nCMPCTBLOCKVersion));
2568 nCMPCTBLOCKVersion = 1;
2569 m_connman.PushMessage(&pfrom, msgMaker.Make(
NetMsgType::SENDCMPCT, fAnnounceUsingCMPCTBLOCK, nCMPCTBLOCKVersion));
2577 State(pfrom.
GetId())->fPreferHeaders =
true;
2582 bool fAnnounceUsingCMPCTBLOCK =
false;
2583 uint64_t nCMPCTBLOCKVersion = 0;
2584 vRecv >> fAnnounceUsingCMPCTBLOCK >> nCMPCTBLOCKVersion;
2588 if (!State(pfrom.
GetId())->fProvidesHeaderAndIDs) {
2589 State(pfrom.
GetId())->fProvidesHeaderAndIDs =
true;
2590 State(pfrom.
GetId())->fWantsCmpctWitness = nCMPCTBLOCKVersion == 2;
2592 if (State(pfrom.
GetId())->fWantsCmpctWitness == (nCMPCTBLOCKVersion == 2)) {
2593 State(pfrom.
GetId())->fPreferHeaderAndIDs = fAnnounceUsingCMPCTBLOCK;
2598 if (!State(pfrom.
GetId())->fSupportsDesiredCmpctVersion) {
2600 State(pfrom.
GetId())->fSupportsDesiredCmpctVersion = (nCMPCTBLOCKVersion == 2);
2602 State(pfrom.
GetId())->fSupportsDesiredCmpctVersion = (nCMPCTBLOCKVersion == 1);
2619 if (!State(pfrom.
GetId())->m_wtxid_relay) {
2620 State(pfrom.
GetId())->m_wtxid_relay =
true;
2621 m_wtxid_relay_peers++;
2658 std::vector<CAddress> vAddr;
2668 Misbehaving(pfrom.
GetId(), 20,
strprintf(
"%s message size = %u", msg_type, vAddr.size()));
2673 std::vector<CAddress> vAddrOk;
2675 int64_t nSince = nNow - 10 * 60;
2678 if (interruptMsgProc)
2687 if (addr.
nTime <= 100000000 || addr.
nTime > nNow + 10 * 60)
2688 addr.
nTime = nNow - 5 * 24 * 60 * 60;
2690 if (m_banman && (m_banman->IsDiscouraged(addr) || m_banman->IsBanned(addr))) {
2702 vAddrOk.push_back(addr);
2704 m_connman.AddNewAddresses(vAddrOk, pfrom.
addr, 2 * 60 * 60);
2705 if (vAddr.size() < 1000)
2715 std::vector<CInv> vInv;
2719 Misbehaving(pfrom.
GetId(), 20,
strprintf(
"inv message size = %u", vInv.size()));
2725 bool fBlocksOnly = m_ignore_incoming_txs || (pfrom.
m_tx_relay ==
nullptr);
2729 fBlocksOnly =
false;
2734 const auto current_time = GetTime<std::chrono::microseconds>();
2737 for (
CInv& inv : vInv) {
2738 if (interruptMsgProc)
return;
2743 if (State(pfrom.
GetId())->m_wtxid_relay) {
2753 UpdateBlockAvailability(pfrom.
GetId(), inv.
hash);
2760 best_block = &inv.
hash;
2764 const bool fAlreadyHave = AlreadyHaveTx(gtxid);
2772 }
else if (!fAlreadyHave && !m_chainman.ActiveChainstate().IsInitialBlockDownload()) {
2773 AddTxAnnouncement(pfrom, gtxid, current_time);
2780 if (best_block !=
nullptr) {
2789 std::vector<CInv> vInv;
2793 Misbehaving(pfrom.
GetId(), 20,
strprintf(
"getdata message size = %u", vInv.size()));
2799 if (vInv.size() > 0) {
2804 LOCK(peer->m_getdata_requests_mutex);
2805 peer->m_getdata_requests.insert(peer->m_getdata_requests.end(), vInv.begin(), vInv.end());
2806 ProcessGetData(pfrom, *peer, interruptMsgProc);
2815 vRecv >> locator >> hashStop;
2831 std::shared_ptr<const CBlock> a_recent_block;
2834 a_recent_block = most_recent_block;
2837 if (!::
ChainstateActive().ActivateBestChain(state, m_chainparams, a_recent_block)) {
2851 LogPrint(
BCLog::NET,
"getblocks %d to %s limit %d from peer=%d\n", (pindex ? pindex->
nHeight : -1), hashStop.IsNull() ?
"end" : hashStop.ToString(), nLimit, pfrom.
GetId());
2861 const int nPrunedBlocksLikelyToHave =
MIN_BLOCKS_TO_KEEP - 3600 / m_chainparams.GetConsensus().nPowTargetSpacing;
2868 if (--nLimit <= 0) {
2872 WITH_LOCK(peer->m_block_inv_mutex, {peer->m_continuation_block = pindex->GetBlockHash();});
2883 std::shared_ptr<const CBlock> recent_block;
2886 if (most_recent_block_hash == req.blockhash)
2887 recent_block = most_recent_block;
2891 SendBlockTransactions(pfrom, *recent_block, req);
2909 SendBlockTransactions(pfrom, block, req);
2924 inv.
hash = req.blockhash;
2925 WITH_LOCK(peer->m_getdata_requests_mutex, peer->m_getdata_requests.push_back(inv));
2933 vRecv >> locator >> hashStop;
2943 LogPrint(
BCLog::NET,
"Ignoring getheaders from peer=%d because node is in initial block download\n", pfrom.
GetId());
2947 CNodeState *nodestate = State(pfrom.
GetId());
2952 pindex =
g_chainman.m_blockman.LookupBlockIndex(hashStop);
2958 LogPrint(
BCLog::NET,
"%s: ignoring request from peer=%i for old block header that isn't in the main chain\n", __func__, pfrom.
GetId());
2971 std::vector<CBlock> vHeaders;
2973 LogPrint(
BCLog::NET,
"getheaders %d to %s from peer=%d\n", (pindex ? pindex->
nHeight : -1), hashStop.IsNull() ?
"end" : hashStop.ToString(), pfrom.
GetId());
2977 if (--nLimit <= 0 || pindex->GetBlockHash() == hashStop)
3012 const uint256& txid = ptx->GetHash();
3013 const uint256& wtxid = ptx->GetWitnessHash();
3017 CNodeState* nodestate = State(pfrom.
GetId());
3019 const uint256& hash = nodestate->m_wtxid_relay ? wtxid : txid;
3021 if (nodestate->m_wtxid_relay && txid != wtxid) {
3030 m_txrequest.ReceivedResponse(pfrom.
GetId(), txid);
3031 if (tx.
HasWitness()) m_txrequest.ReceivedResponse(pfrom.
GetId(), wtxid);
3045 if (AlreadyHaveTx(
GenTxid(
true, wtxid))) {
3050 if (!m_mempool.exists(tx.
GetHash())) {
3064 m_mempool.check(m_chainman.ActiveChainstate());
3067 m_txrequest.ForgetTxHash(tx.
GetHash());
3070 m_orphanage.AddChildrenToWorkSet(tx, peer->m_orphan_work_set);
3077 m_mempool.size(), m_mempool.DynamicMemoryUsage() / 1000);
3080 AddToCompactExtraTransactions(removedTx);
3084 ProcessOrphanTx(peer->m_orphan_work_set);
3088 bool fRejectedParents =
false;
3092 std::vector<uint256> unique_parents;
3093 unique_parents.reserve(tx.
vin.size());
3098 std::sort(unique_parents.begin(), unique_parents.end());
3099 unique_parents.erase(std::unique(unique_parents.begin(), unique_parents.end()), unique_parents.end());
3100 for (
const uint256& parent_txid : unique_parents) {
3101 if (recentRejects->contains(parent_txid)) {
3102 fRejectedParents =
true;
3106 if (!fRejectedParents) {
3107 const auto current_time = GetTime<std::chrono::microseconds>();
3109 for (
const uint256& parent_txid : unique_parents) {
3115 const GenTxid gtxid{
false, parent_txid};
3117 if (!AlreadyHaveTx(gtxid)) AddTxAnnouncement(pfrom, gtxid, current_time);
3120 if (m_orphanage.AddTx(ptx, pfrom.
GetId())) {
3121 AddToCompactExtraTransactions(ptx);
3125 m_txrequest.ForgetTxHash(tx.
GetHash());
3130 unsigned int nEvicted = m_orphanage.LimitOrphans(nMaxOrphanTx);
3142 recentRejects->insert(tx.
GetHash());
3144 m_txrequest.ForgetTxHash(tx.
GetHash());
3174 recentRejects->insert(tx.
GetHash());
3175 m_txrequest.ForgetTxHash(tx.
GetHash());
3178 AddToCompactExtraTransactions(ptx);
3204 MaybePunishNodeForTx(pfrom.
GetId(), state);
3218 vRecv >> cmpctblock;
3220 bool received_new_header =
false;
3225 if (!
g_chainman.m_blockman.LookupBlockIndex(cmpctblock.header.hashPrevBlock)) {
3232 if (!
g_chainman.m_blockman.LookupBlockIndex(cmpctblock.header.GetHash())) {
3233 received_new_header =
true;
3239 if (!m_chainman.ProcessNewBlockHeaders({cmpctblock.header}, state, m_chainparams, &pindex)) {
3241 MaybePunishNodeForBlock(pfrom.
GetId(), state,
true,
"invalid header via cmpctblock");
3250 bool fProcessBLOCKTXN =
false;
3255 bool fRevertToHeaderProcessing =
false;
3259 std::shared_ptr<CBlock> pblock = std::make_shared<CBlock>();
3260 bool fBlockReconstructed =
false;
3268 CNodeState *nodestate = State(pfrom.
GetId());
3273 nodestate->m_last_block_announcement =
GetTime();
3276 std::map<uint256, std::pair<NodeId, std::list<QueuedBlock>::iterator> >::iterator blockInFlightIt = mapBlocksInFlight.find(pindex->
GetBlockHash());
3277 bool fAlreadyInFlight = blockInFlightIt != mapBlocksInFlight.end();
3284 if (fAlreadyInFlight) {
3287 std::vector<CInv> vInv(1);
3295 if (!fAlreadyInFlight && !CanDirectFetch(m_chainparams.GetConsensus()))
3298 if (
IsWitnessEnabled(pindex->
pprev, m_chainparams.GetConsensus()) && !nodestate->fSupportsDesiredCmpctVersion) {
3308 (fAlreadyInFlight && blockInFlightIt->second.first == pfrom.
GetId())) {
3309 std::list<QueuedBlock>::iterator* queuedBlockIt =
nullptr;
3310 if (!MarkBlockAsInFlight(pfrom.
GetId(), pindex->
GetBlockHash(), pindex, &queuedBlockIt)) {
3311 if (!(*queuedBlockIt)->partialBlock)
3324 Misbehaving(pfrom.
GetId(), 100,
"invalid compact block");
3328 std::vector<CInv> vInv(1);
3335 for (
size_t i = 0; i < cmpctblock.BlockTxCount(); i++) {
3342 txn.
blockhash = cmpctblock.header.GetHash();
3344 fProcessBLOCKTXN =
true;
3356 ReadStatus status = tempBlock.InitData(cmpctblock, vExtraTxnForCompact);
3361 std::vector<CTransactionRef> dummy;
3362 status = tempBlock.FillBlock(*pblock, dummy);
3364 fBlockReconstructed =
true;
3368 if (fAlreadyInFlight) {
3371 std::vector<CInv> vInv(1);
3377 fRevertToHeaderProcessing =
true;
3382 if (fProcessBLOCKTXN) {
3383 return ProcessMessage(pfrom,
NetMsgType::BLOCKTXN, blockTxnMsg, time_received, interruptMsgProc);
3386 if (fRevertToHeaderProcessing) {
3392 return ProcessHeadersMessage(pfrom, *peer, {cmpctblock.header},
true);
3395 if (fBlockReconstructed) {
3400 mapBlockSource.emplace(pblock->GetHash(), std::make_pair(pfrom.
GetId(),
false));
3402 bool fNewBlock =
false;
3412 m_chainman.ProcessNewBlock(m_chainparams, pblock,
true, &fNewBlock);
3417 mapBlockSource.erase(pblock->GetHash());
3425 MarkBlockAsReceived(pblock->GetHash());
3442 std::shared_ptr<CBlock> pblock = std::make_shared<CBlock>();
3443 bool fBlockRead =
false;
3447 std::map<uint256, std::pair<NodeId, std::list<QueuedBlock>::iterator> >::iterator
it = mapBlocksInFlight.find(resp.blockhash);
3448 if (
it == mapBlocksInFlight.end() || !
it->second.second->partialBlock ||
3449 it->second.first != pfrom.
GetId()) {
3457 MarkBlockAsReceived(resp.blockhash);
3458 Misbehaving(pfrom.
GetId(), 100,
"invalid compact block/non-matching block transactions");
3462 std::vector<CInv> invs;
3483 MarkBlockAsReceived(resp.blockhash);
3491 mapBlockSource.emplace(resp.blockhash, std::make_pair(pfrom.
GetId(),
false));
3495 bool fNewBlock =
false;
3502 m_chainman.ProcessNewBlock(m_chainparams, pblock,
true, &fNewBlock);
3507 mapBlockSource.erase(pblock->GetHash());
3521 std::vector<CBlockHeader> headers;
3526 Misbehaving(pfrom.
GetId(), 20,
strprintf(
"headers message size = %u", nCount));
3529 headers.resize(nCount);
3530 for (
unsigned int n = 0; n < nCount; n++) {
3531 vRecv >> headers[n];
3535 return ProcessHeadersMessage(pfrom, *peer, headers,
false);
3546 std::shared_ptr<CBlock> pblock = std::make_shared<CBlock>();
3551 bool forceProcessing =
false;
3552 const uint256 hash(pblock->GetHash());
3557 forceProcessing |= MarkBlockAsReceived(hash);
3561 mapBlockSource.emplace(hash, std::make_pair(pfrom.
GetId(),
true));
3563 bool fNewBlock =
false;
3564 m_chainman.ProcessNewBlock(m_chainparams, pblock, forceProcessing, &fNewBlock);
3569 mapBlockSource.erase(pblock->GetHash());
3594 std::vector<CAddress> vAddr;
3601 for (
const CAddress &addr : vAddr) {
3656 const auto ping_end = time_received;
3659 bool bPingFinished =
false;
3660 std::string sProblem;
3662 if (nAvail >=
sizeof(nonce)) {
3666 if (peer->m_ping_nonce_sent != 0) {
3667 if (nonce == peer->m_ping_nonce_sent) {
3669 bPingFinished =
true;
3670 const auto ping_time = ping_end - peer->m_ping_start.load();
3671 if (ping_time.count() >= 0) {
3676 sProblem =
"Timing mishap";
3680 sProblem =
"Nonce mismatch";
3683 bPingFinished =
true;
3684 sProblem =
"Nonce zero";
3688 sProblem =
"Unsolicited pong without ping";
3692 bPingFinished =
true;
3693 sProblem =
"Short payload";
3696 if (!(sProblem.empty())) {
3700 peer->m_ping_nonce_sent,
3704 if (bPingFinished) {
3705 peer->m_ping_nonce_sent = 0;
3712 LogPrint(
BCLog::NET,
"filterload received despite not offering bloom services from peer=%d; disconnecting\n", pfrom.
GetId());
3719 if (!filter.IsWithinSizeConstraints())
3722 Misbehaving(pfrom.
GetId(), 100,
"too-large bloom filter");
3735 LogPrint(
BCLog::NET,
"filteradd received despite not offering bloom services from peer=%d; disconnecting\n", pfrom.
GetId());
3739 std::vector<unsigned char> vData;
3756 Misbehaving(pfrom.
GetId(), 100,
"bad filteradd message");
3763 LogPrint(
BCLog::NET,
"filterclear received despite not offering bloom services from peer=%d; disconnecting\n", pfrom.
GetId());
3778 vRecv >> newFeeFilter;
3781 pfrom.
m_tx_relay->minFeeFilter = newFeeFilter;
3804 std::vector<CInv> vInv;
3808 for (
CInv &inv : vInv) {
3812 m_txrequest.ReceivedResponse(pfrom.
GetId(), inv.
hash);
3824 bool PeerManagerImpl::MaybeDiscourageAndDisconnect(
CNode& pnode, Peer& peer)
3827 LOCK(peer.m_misbehavior_mutex);
3830 if (!peer.m_should_discourage)
return false;
3832 peer.m_should_discourage =
false;
3837 LogPrintf(
"Warning: not punishing noban peer %d!\n", peer.m_id);
3843 LogPrintf(
"Warning: not punishing manually connected peer %d!\n", peer.m_id);
3858 if (m_banman) m_banman->Discourage(pnode.
addr);
3859 m_connman.DisconnectNode(pnode.
addr);
3863 bool PeerManagerImpl::ProcessMessages(
CNode* pfrom, std::atomic<bool>& interruptMsgProc)
3865 bool fMoreWork =
false;
3867 PeerRef peer = GetPeerRef(pfrom->
GetId());
3868 if (peer ==
nullptr)
return false;
3871 LOCK(peer->m_getdata_requests_mutex);
3872 if (!peer->m_getdata_requests.empty()) {
3873 ProcessGetData(*pfrom, *peer, interruptMsgProc);
3879 if (!peer->m_orphan_work_set.empty()) {
3880 ProcessOrphanTx(peer->m_orphan_work_set);
3890 LOCK(peer->m_getdata_requests_mutex);
3891 if (!peer->m_getdata_requests.empty())
return true;
3896 if (!peer->m_orphan_work_set.empty())
return true;
3902 std::list<CNetMessage> msgs;
3905 if (pfrom->vProcessMsg.empty())
return false;
3907 msgs.splice(msgs.begin(), pfrom->vProcessMsg, pfrom->vProcessMsg.begin());
3910 fMoreWork = !pfrom->vProcessMsg.empty();
3919 const std::string& msg_type = msg.m_command;
3922 unsigned int nMessageSize = msg.m_message_size;
3925 ProcessMessage(*pfrom, msg_type, msg.m_recv, msg.m_time, interruptMsgProc);
3926 if (interruptMsgProc)
return false;
3928 LOCK(peer->m_getdata_requests_mutex);
3929 if (!peer->m_getdata_requests.empty()) fMoreWork =
true;
3931 }
catch (
const std::exception& e) {
3940 void PeerManagerImpl::ConsiderEviction(
CNode& pto, int64_t time_in_seconds)
3944 CNodeState &state = *State(pto.
GetId());
3954 if (state.pindexBestKnownBlock !=
nullptr && state.pindexBestKnownBlock->nChainWork >= ::
ChainActive().Tip()->nChainWork) {
3955 if (state.m_chain_sync.m_timeout != 0) {
3956 state.m_chain_sync.m_timeout = 0;
3957 state.m_chain_sync.m_work_header =
nullptr;
3958 state.m_chain_sync.m_sent_getheaders =
false;
3960 }
else if (state.m_chain_sync.m_timeout == 0 || (state.m_chain_sync.m_work_header !=
nullptr && state.pindexBestKnownBlock !=
nullptr && state.pindexBestKnownBlock->nChainWork >= state.m_chain_sync.m_work_header->nChainWork)) {
3967 state.m_chain_sync.m_sent_getheaders =
false;
3968 }
else if (state.m_chain_sync.m_timeout > 0 && time_in_seconds > state.m_chain_sync.m_timeout) {
3972 if (state.m_chain_sync.m_sent_getheaders) {
3974 LogPrintf(
"Disconnecting outbound peer %d for old chain, best known block = %s\n", pto.
GetId(), state.pindexBestKnownBlock !=
nullptr ? state.pindexBestKnownBlock->GetBlockHash().ToString() :
"<none>");
3977 assert(state.m_chain_sync.m_work_header);
3978 LogPrint(
BCLog::NET,
"sending getheaders to outbound peer=%d to verify chain work (current best known block:%s, benchmark blockhash: %s)\n", pto.
GetId(), state.pindexBestKnownBlock !=
nullptr ? state.pindexBestKnownBlock->GetBlockHash().ToString() :
"<none>", state.m_chain_sync.m_work_header->GetBlockHash().ToString());
3980 state.m_chain_sync.m_sent_getheaders =
true;
3981 constexpr int64_t HEADERS_RESPONSE_TIME = 120;
3987 state.m_chain_sync.m_timeout = time_in_seconds + HEADERS_RESPONSE_TIME;
3993 void PeerManagerImpl::EvictExtraOutboundPeers(int64_t time_in_seconds)
4001 if (m_connman.GetExtraBlockRelayCount() > 0) {
4002 std::pair<NodeId, int64_t> youngest_peer{-1, 0}, next_youngest_peer{-1, 0};
4004 m_connman.ForEachNode([&](
CNode* pnode) {
4006 if (pnode->
GetId() > youngest_peer.first) {
4007 next_youngest_peer = youngest_peer;
4008 youngest_peer.first = pnode->GetId();
4009 youngest_peer.second = pnode->nLastBlockTime;
4012 NodeId to_disconnect = youngest_peer.first;
4013 if (youngest_peer.second > next_youngest_peer.second) {
4016 to_disconnect = next_youngest_peer.first;
4025 CNodeState *node_state = State(pnode->
GetId());
4026 if (node_state ==
nullptr ||
4032 LogPrint(
BCLog::NET,
"keeping block-relay-only peer=%d chosen for eviction (connect time: %d, blocks_in_flight: %d)\n",
4040 if (m_connman.GetExtraFullOutboundCount() > 0) {
4046 int64_t oldest_block_announcement = std::numeric_limits<int64_t>::max();
4054 CNodeState *state = State(pnode->
GetId());
4055 if (state ==
nullptr)
return;
4057 if (state->m_chain_sync.m_protect)
return;
4058 if (state->m_last_block_announcement < oldest_block_announcement || (state->m_last_block_announcement == oldest_block_announcement && pnode->
GetId() > worst_peer)) {
4059 worst_peer = pnode->
GetId();
4060 oldest_block_announcement = state->m_last_block_announcement;
4063 if (worst_peer != -1) {
4072 CNodeState &state = *State(pnode->
GetId());
4074 LogPrint(
BCLog::NET,
"disconnecting extra outbound peer=%d (last block announcement received at time %d)\n", pnode->
GetId(), oldest_block_announcement);
4088 m_connman.SetTryNewOutboundPeer(
false);
4094 void PeerManagerImpl::CheckForStaleTipAndEvictPeers()
4098 int64_t time_in_seconds =
GetTime();
4100 EvictExtraOutboundPeers(time_in_seconds);
4102 if (time_in_seconds > m_stale_tip_check_time) {
4105 if (!
fImporting && !
fReindex && m_connman.GetNetworkActive() && m_connman.GetUseAddrmanOutgoing() && TipMayBeStale()) {
4106 LogPrintf(
"Potential stale tip detected, will try using extra outbound peer (last tip update: %d seconds ago)\n", time_in_seconds - m_last_tip_update);
4107 m_connman.SetTryNewOutboundPeer(
true);
4108 }
else if (m_connman.GetTryNewOutboundPeer()) {
4109 m_connman.SetTryNewOutboundPeer(
false);
4114 if (!m_initial_sync_finished && CanDirectFetch(m_chainparams.GetConsensus())) {
4115 m_connman.StartExtraBlockRelayPeers();
4116 m_initial_sync_finished =
true;
4120 void PeerManagerImpl::MaybeSendPing(
CNode& node_to, Peer& peer)
4124 auto now = GetTime<std::chrono::microseconds>();
4126 if (m_connman.RunInactivityChecks(node_to) && peer.m_ping_nonce_sent &&
4127 now > peer.m_ping_start.load() + std::chrono::seconds{TIMEOUT_INTERVAL}) {
4134 bool pingSend =
false;
4136 if (peer.m_ping_queued) {
4141 if (peer.m_ping_nonce_sent == 0 && now > peer.m_ping_start.load() +
PING_INTERVAL) {
4148 while (nonce == 0) {
4151 peer.m_ping_queued =
false;
4152 peer.m_ping_start = now;
4154 peer.m_ping_nonce_sent = nonce;
4158 peer.m_ping_nonce_sent = 0;
4165 class CompareInvMempoolOrder
4170 explicit CompareInvMempoolOrder(
CTxMemPool *_mempool,
bool use_wtxid)
4173 m_wtxid_relay = use_wtxid;
4176 bool operator()(std::set<uint256>::iterator a, std::set<uint256>::iterator b)
4185 bool PeerManagerImpl::SendMessages(
CNode* pto)
4187 PeerRef peer = GetPeerRef(pto->
GetId());
4188 if (!peer)
return false;
4193 if (MaybeDiscourageAndDisconnect(*pto, *peer))
return true;
4202 MaybeSendPing(*pto, *peer);
4210 CNodeState &state = *State(pto->
GetId());
4213 auto current_time = GetTime<std::chrono::microseconds>();
4217 pto->m_next_local_addr_send < current_time) {
4224 if (pto->m_next_local_addr_send != 0us) {
4239 std::vector<CAddress> vAddr;
4243 const char* msg_type;
4258 vAddr.push_back(addr);
4262 m_connman.PushMessage(pto, msgMaker.Make(make_flags, msg_type, vAddr));
4269 m_connman.PushMessage(pto, msgMaker.Make(make_flags, msg_type, vAddr));
4278 bool fFetch = state.fPreferredDownload || (nPreferredDownload == 0 && !pto->
fClient && !pto->
IsAddrFetchConn());
4282 state.fSyncStarted =
true;
4299 if (pindexStart->
pprev)
4300 pindexStart = pindexStart->
pprev;
4317 LOCK(peer->m_block_inv_mutex);
4318 std::vector<CBlock> vHeaders;
4319 bool fRevertToInv = ((!state.fPreferHeaders &&
4320 (!state.fPreferHeaderAndIDs || peer->m_blocks_for_headers_relay.size() > 1)) ||
4323 ProcessBlockAvailability(pto->
GetId());
4325 if (!fRevertToInv) {
4326 bool fFoundStartingHeader =
false;
4330 for (
const uint256& hash : peer->m_blocks_for_headers_relay) {
4335 fRevertToInv =
true;
4338 if (pBestIndex !=
nullptr && pindex->
pprev != pBestIndex) {
4350 fRevertToInv =
true;
4353 pBestIndex = pindex;
4354 if (fFoundStartingHeader) {
4357 }
else if (PeerHasHeader(&state, pindex)) {
4359 }
else if (pindex->
pprev ==
nullptr || PeerHasHeader(&state, pindex->
pprev)) {
4362 fFoundStartingHeader =
true;
4367 fRevertToInv =
true;
4372 if (!fRevertToInv && !vHeaders.empty()) {
4373 if (vHeaders.size() == 1 && state.fPreferHeaderAndIDs) {
4377 vHeaders.front().GetHash().ToString(), pto->
GetId());
4381 bool fGotBlockFromCache =
false;
4384 if (most_recent_block_hash == pBestIndex->
GetBlockHash()) {
4385 if (state.fWantsCmpctWitness || !fWitnessesPresentInMostRecentCompactBlock)
4386 m_connman.PushMessage(pto, msgMaker.Make(nSendFlags,
NetMsgType::CMPCTBLOCK, *most_recent_compact_block));
4391 fGotBlockFromCache =
true;
4394 if (!fGotBlockFromCache) {
4401 state.pindexBestHeaderSent = pBestIndex;
4402 }
else if (state.fPreferHeaders) {
4403 if (vHeaders.size() > 1) {
4406 vHeaders.front().GetHash().ToString(),
4407 vHeaders.back().GetHash().ToString(), pto->
GetId());
4410 vHeaders.front().GetHash().ToString(), pto->
GetId());
4413 state.pindexBestHeaderSent = pBestIndex;
4415 fRevertToInv =
true;
4421 if (!peer->m_blocks_for_headers_relay.empty()) {
4422 const uint256& hashToAnnounce = peer->m_blocks_for_headers_relay.back();
4435 if (!PeerHasHeader(&state, pindex)) {
4436 peer->m_blocks_for_inv_relay.push_back(hashToAnnounce);
4442 peer->m_blocks_for_headers_relay.clear();
4448 std::vector<CInv> vInv;
4450 LOCK(peer->m_block_inv_mutex);
4454 for (
const uint256& hash : peer->m_blocks_for_inv_relay) {
4461 peer->m_blocks_for_inv_relay.clear();
4467 if (pto->
m_tx_relay->nNextInvSend < current_time) {
4468 fSendTrickle =
true;
4483 if (fSendTrickle && pto->
m_tx_relay->fSendMempool) {
4484 auto vtxinfo = m_mempool.infoAll();
4490 for (
const auto& txinfo : vtxinfo) {
4491 const uint256& hash = state.m_wtxid_relay ? txinfo.tx->GetWitnessHash() : txinfo.tx->GetHash();
4493 pto->
m_tx_relay->setInventoryTxToSend.erase(hash);
4495 if (txinfo.fee < filterrate.GetFee(txinfo.vsize)) {
4499 if (!pto->
m_tx_relay->pfilter->IsRelevantAndUpdate(*txinfo.tx))
continue;
4501 pto->
m_tx_relay->filterInventoryKnown.insert(hash);
4503 vInv.push_back(inv);
4509 pto->
m_tx_relay->m_last_mempool_req = GetTime<std::chrono::seconds>();
4515 std::vector<std::set<uint256>::iterator> vInvTx;
4516 vInvTx.reserve(pto->
m_tx_relay->setInventoryTxToSend.size());
4517 for (std::set<uint256>::iterator
it = pto->
m_tx_relay->setInventoryTxToSend.begin();
it != pto->
m_tx_relay->setInventoryTxToSend.end();
it++) {
4518 vInvTx.push_back(
it);
4523 CompareInvMempoolOrder compareInvMempoolOrder(&m_mempool, state.m_wtxid_relay);
4524 std::make_heap(vInvTx.begin(), vInvTx.end(), compareInvMempoolOrder);
4527 unsigned int nRelayedTransactions = 0;
4531 std::pop_heap(vInvTx.begin(), vInvTx.end(), compareInvMempoolOrder);
4532 std::set<uint256>::iterator
it = vInvTx.back();
4539 if (pto->
m_tx_relay->filterInventoryKnown.contains(hash)) {
4543 auto txinfo = m_mempool.info(
ToGenTxid(inv));
4547 auto txid = txinfo.tx->GetHash();
4548 auto wtxid = txinfo.tx->GetWitnessHash();
4550 if (txinfo.fee < filterrate.GetFee(txinfo.vsize)) {
4553 if (pto->
m_tx_relay->pfilter && !pto->
m_tx_relay->pfilter->IsRelevantAndUpdate(*txinfo.tx))
continue;
4555 State(pto->
GetId())->m_recently_announced_invs.insert(hash);
4556 vInv.push_back(inv);
4557 nRelayedTransactions++;
4560 while (!g_relay_expiration.empty() && g_relay_expiration.front().first < current_time)
4562 mapRelay.erase(g_relay_expiration.front().second);
4563 g_relay_expiration.pop_front();
4566 auto ret = mapRelay.emplace(txid, std::move(txinfo.tx));
4571 auto ret2 = mapRelay.emplace(wtxid, ret.first->second);
4580 pto->
m_tx_relay->filterInventoryKnown.insert(hash);
4587 pto->
m_tx_relay->filterInventoryKnown.insert(txid);
4597 current_time = GetTime<std::chrono::microseconds>();
4602 LogPrintf(
"Peer=%d is stalling block download, disconnecting\n", pto->
GetId());
4611 if (state.vBlocksInFlight.size() > 0) {
4612 QueuedBlock &queuedBlock = state.vBlocksInFlight.front();
4613 int nOtherPeersWithValidatedDownloads = nPeersWithValidatedDownloads - (state.nBlocksInFlightValidHeaders > 0);
4615 LogPrintf(
"Timeout downloading block %s from peer=%d, disconnecting\n", queuedBlock.hash.ToString(), pto->
GetId());
4621 if (state.fSyncStarted && state.m_headers_sync_timeout < std::chrono::microseconds::max()) {
4624 if (current_time > state.m_headers_sync_timeout && nSyncStarted == 1 && (nPreferredDownload - state.fPreferredDownload >= 1)) {
4631 LogPrintf(
"Timeout downloading headers from peer=%d, disconnecting\n", pto->
GetId());
4635 LogPrintf(
"Timeout downloading headers from noban peer=%d, not disconnecting\n", pto->
GetId());
4641 state.fSyncStarted =
false;
4643 state.m_headers_sync_timeout = 0us;
4649 state.m_headers_sync_timeout = std::chrono::microseconds::max();
4655 ConsiderEviction(*pto,
GetTime());
4660 std::vector<CInv> vGetData;
4662 std::vector<const CBlockIndex*> vToDownload;
4672 if (state.nBlocksInFlight == 0 && staller != -1) {
4673 if (State(staller)->m_stalling_since == 0us) {
4674 State(staller)->m_stalling_since = current_time;
4683 std::vector<std::pair<NodeId, GenTxid>> expired;
4684 auto requestable = m_txrequest.GetRequestable(pto->
GetId(), current_time, &expired);
4685 for (
const auto& entry : expired) {
4686 LogPrint(
BCLog::NET,
"timeout of inflight %s %s from peer=%d\n", entry.second.IsWtxid() ?
"wtx" :
"tx",
4687 entry.second.GetHash().ToString(), entry.first);
4689 for (
const GenTxid& gtxid : requestable) {
4690 if (!AlreadyHaveTx(gtxid)) {
4702 m_txrequest.ForgetTxHash(gtxid.
GetHash());
4707 if (!vGetData.empty())
4718 if (m_chainman.ActiveChainstate().IsInitialBlockDownload()) {
4724 if (pto->
m_tx_relay->lastSentFeeFilter == MAX_FILTER) {
4727 pto->
m_tx_relay->m_next_send_feefilter = 0us;
4730 if (current_time > pto->
m_tx_relay->m_next_send_feefilter) {
4731 CAmount filterToSend = g_filter_rounder.round(currentFilter);
4734 if (filterToSend != pto->
m_tx_relay->lastSentFeeFilter) {
4736 pto->
m_tx_relay->lastSentFeeFilter = filterToSend;
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)) {