183 std::unique_ptr<PartiallyDownloadedBlock> partialBlock;
203 Mutex m_misbehavior_mutex;
205 int m_misbehavior_score
GUARDED_BY(m_misbehavior_mutex){0};
207 bool m_should_discourage
GUARDED_BY(m_misbehavior_mutex){
false};
210 Mutex m_block_inv_mutex;
214 std::vector<uint256> m_blocks_for_inv_relay
GUARDED_BY(m_block_inv_mutex);
218 std::vector<uint256> m_blocks_for_headers_relay
GUARDED_BY(m_block_inv_mutex);
226 std::atomic<int> m_starting_height{-1};
229 std::atomic<uint64_t> m_ping_nonce_sent{0};
231 std::atomic<std::chrono::microseconds> m_ping_start{0us};
233 std::atomic<bool> m_ping_queued{
false};
236 std::vector<CAddress> m_addrs_to_send;
246 std::unique_ptr<CRollingBloomFilter> m_addr_known;
261 std::atomic_bool m_addr_relay_enabled{
false};
263 bool m_getaddr_sent{
false};
265 mutable Mutex m_addr_send_times_mutex;
267 std::chrono::microseconds m_next_addr_send
GUARDED_BY(m_addr_send_times_mutex){0};
269 std::chrono::microseconds m_next_local_addr_send
GUARDED_BY(m_addr_send_times_mutex){0};
272 std::atomic_bool m_wants_addrv2{
false};
274 bool m_getaddr_recvd{
false};
277 double m_addr_token_bucket{1.0};
279 std::chrono::microseconds m_addr_token_timestamp{GetTime<std::chrono::microseconds>()};
281 std::atomic<uint64_t> m_addr_rate_limited{0};
283 std::atomic<uint64_t> m_addr_processed{0};
289 Mutex m_getdata_requests_mutex;
291 std::deque<CInv> m_getdata_requests
GUARDED_BY(m_getdata_requests_mutex);
298 using PeerRef = std::shared_ptr<Peer>;
328 void SetBestHeight(
int height)
override { m_best_height = height; };
329 void Misbehaving(
const NodeId pnode,
const int howmuch,
const std::string& message)
override;
331 const std::chrono::microseconds time_received,
const std::atomic<bool>& interruptMsgProc)
override;
344 void ReattemptInitialBroadcast(
CScheduler& scheduler);
348 PeerRef GetPeerRef(
NodeId id)
const;
352 PeerRef RemovePeer(
NodeId id);
365 bool via_compact_block,
const std::string& message =
"");
380 bool MaybeDiscourageAndDisconnect(
CNode& pnode, Peer& peer);
384 void ProcessHeadersMessage(
CNode& pfrom,
const Peer& peer,
385 const std::vector<CBlockHeader>& headers,
386 bool via_compact_block);
393 void AddTxAnnouncement(
const CNode&
node,
const GenTxid& gtxid, std::chrono::microseconds current_time)
397 void PushNodeVersion(
CNode& pnode);
403 void MaybeSendPing(
CNode& node_to, Peer& peer, std::chrono::microseconds now);
406 void MaybeSendAddr(
CNode&
node, Peer& peer, std::chrono::microseconds current_time);
415 void RelayAddress(
NodeId originator,
const CAddress& addr,
bool fReachable);
430 std::atomic<int> m_best_height{-1};
433 std::chrono::seconds m_stale_tip_check_time{0s};
436 const bool m_ignore_incoming_txs;
440 bool m_initial_sync_finished{
false};
444 mutable Mutex m_peer_mutex;
451 std::map<NodeId, PeerRef> m_peer_map
GUARDED_BY(m_peer_mutex);
453 std::atomic<std::chrono::microseconds> m_next_inv_to_inbounds{0us};
526 Mutex m_recent_confirmed_transactions_mutex;
535 std::chrono::microseconds NextInvToInbounds(std::chrono::microseconds now,
536 std::chrono::seconds average_interval);
563 std::atomic<
std::chrono::seconds> m_last_tip_update{0s};
571 void ProcessBlock(
CNode&
node, const
std::shared_ptr<const
CBlock>& block,
bool force_processing);
619 void ProcessGetBlockData(
CNode& pfrom, Peer& peer, const
CInv& inv);
635 bool PrepareBlockFilterRequest(
CNode& peer,
637 const
uint256& stop_hash, uint32_t max_height_diff,
677 bool SetupAddressRelay(const
CNode&
node, Peer& peer);
697 uint256 hashLastUnknownBlock{};
703 int nUnconnectingHeaders{0};
705 bool fSyncStarted{
false};
707 std::chrono::microseconds m_headers_sync_timeout{0us};
709 std::chrono::microseconds m_stalling_since{0us};
710 std::list<QueuedBlock> vBlocksInFlight;
712 std::chrono::microseconds m_downloading_since{0us};
713 int nBlocksInFlight{0};
715 bool fPreferredDownload{
false};
717 bool fPreferHeaders{
false};
719 bool fPreferHeaderAndIDs{
false};
725 bool fProvidesHeaderAndIDs{
false};
727 bool fHaveWitness{
false};
729 bool fWantsCmpctWitness{
false};
734 bool fSupportsDesiredCmpctVersion{
false};
760 struct ChainSyncTimeoutState {
762 std::chrono::seconds m_timeout{0s};
766 bool m_sent_getheaders{
false};
768 bool m_protect{
false};
771 ChainSyncTimeoutState m_chain_sync;
774 int64_t m_last_block_announcement{0};
777 const bool m_is_inbound;
783 bool m_wtxid_relay{
false};
785 CNodeState(
bool is_inbound) : m_is_inbound(is_inbound) {}
792 std::map<NodeId, CNodeState>::iterator it = mapNodeState.find(pnode);
793 if (it == mapNodeState.end())
803 static bool IsAddrCompatible(
const Peer& peer,
const CAddress& addr)
808 static void AddAddressKnown(Peer& peer,
const CAddress& addr)
810 assert(peer.m_addr_known);
811 peer.m_addr_known->insert(addr.
GetKey());
819 assert(peer.m_addr_known);
820 if (addr.
IsValid() && !peer.m_addr_known->contains(addr.
GetKey()) && IsAddrCompatible(peer, addr)) {
822 peer.m_addrs_to_send[insecure_rand.
randrange(peer.m_addrs_to_send.size())] = addr;
824 peer.m_addrs_to_send.push_back(addr);
831 nPreferredDownload -= state->fPreferredDownload;
836 nPreferredDownload += state->fPreferredDownload;
839 std::chrono::microseconds PeerManagerImpl::NextInvToInbounds(std::chrono::microseconds now,
840 std::chrono::seconds average_interval)
842 if (m_next_inv_to_inbounds.load() < now) {
848 return m_next_inv_to_inbounds;
851 bool PeerManagerImpl::IsBlockRequested(
const uint256& hash)
853 return mapBlocksInFlight.find(hash) != mapBlocksInFlight.end();
856 void PeerManagerImpl::RemoveBlockRequest(
const uint256& hash)
858 auto it = mapBlocksInFlight.find(hash);
859 if (it == mapBlocksInFlight.end()) {
864 auto [node_id, list_it] = it->second;
865 CNodeState *state = State(node_id);
868 if (state->vBlocksInFlight.begin() == list_it) {
870 state->m_downloading_since = std::max(state->m_downloading_since, GetTime<std::chrono::microseconds>());
872 state->vBlocksInFlight.erase(list_it);
874 state->nBlocksInFlight--;
875 if (state->nBlocksInFlight == 0) {
877 m_peers_downloading_from--;
879 state->m_stalling_since = 0us;
880 mapBlocksInFlight.erase(it);
883 bool PeerManagerImpl::BlockRequested(
NodeId nodeid,
const CBlockIndex& block, std::list<QueuedBlock>::iterator** pit)
887 CNodeState *state = State(nodeid);
891 std::map<uint256, std::pair<NodeId, std::list<QueuedBlock>::iterator> >::iterator itInFlight = mapBlocksInFlight.find(hash);
892 if (itInFlight != mapBlocksInFlight.end() && itInFlight->second.first == nodeid) {
894 *pit = &itInFlight->second.second;
900 RemoveBlockRequest(hash);
902 std::list<QueuedBlock>::iterator it = state->vBlocksInFlight.insert(state->vBlocksInFlight.end(),
903 {&block, std::unique_ptr<PartiallyDownloadedBlock>(pit ? new PartiallyDownloadedBlock(&m_mempool) : nullptr)});
904 state->nBlocksInFlight++;
905 if (state->nBlocksInFlight == 1) {
907 state->m_downloading_since = GetTime<std::chrono::microseconds>();
908 m_peers_downloading_from++;
910 itInFlight = mapBlocksInFlight.insert(std::make_pair(hash, std::make_pair(nodeid, it))).first;
912 *pit = &itInFlight->second.second;
917 void PeerManagerImpl::MaybeSetPeerAsAnnouncingHeaderAndIDs(
NodeId nodeid)
924 if (m_ignore_incoming_txs)
return;
926 CNodeState* nodestate = State(nodeid);
927 if (!nodestate || !nodestate->fSupportsDesiredCmpctVersion) {
931 if (nodestate->fProvidesHeaderAndIDs) {
932 int num_outbound_hb_peers = 0;
933 for (std::list<NodeId>::iterator it = lNodesAnnouncingHeaderAndIDs.begin(); it != lNodesAnnouncingHeaderAndIDs.end(); it++) {
935 lNodesAnnouncingHeaderAndIDs.erase(it);
936 lNodesAnnouncingHeaderAndIDs.push_back(nodeid);
939 CNodeState *state = State(*it);
940 if (state !=
nullptr && !state->m_is_inbound) ++num_outbound_hb_peers;
942 if (nodestate->m_is_inbound) {
945 if (lNodesAnnouncingHeaderAndIDs.size() >= 3 && num_outbound_hb_peers == 1) {
946 CNodeState *remove_node = State(lNodesAnnouncingHeaderAndIDs.front());
947 if (remove_node !=
nullptr && !remove_node->m_is_inbound) {
950 std::swap(lNodesAnnouncingHeaderAndIDs.front(), *std::next(lNodesAnnouncingHeaderAndIDs.begin()));
956 uint64_t nCMPCTBLOCKVersion = 2;
957 if (lNodesAnnouncingHeaderAndIDs.size() >= 3) {
960 m_connman.
ForNode(lNodesAnnouncingHeaderAndIDs.front(), [
this, nCMPCTBLOCKVersion](
CNode* pnodeStop){
961 m_connman.PushMessage(pnodeStop, CNetMsgMaker(pnodeStop->GetCommonVersion()).Make(NetMsgType::SENDCMPCT, false, nCMPCTBLOCKVersion));
963 pnodeStop->m_bip152_highbandwidth_to = false;
966 lNodesAnnouncingHeaderAndIDs.pop_front();
971 lNodesAnnouncingHeaderAndIDs.push_back(pfrom->
GetId());
977 bool PeerManagerImpl::TipMayBeStale()
981 if (m_last_tip_update.load() == 0s) {
982 m_last_tip_update = GetTime<std::chrono::seconds>();
984 return m_last_tip_update.load() < GetTime<std::chrono::seconds>() - std::chrono::seconds{consensusParams.
nPowTargetSpacing * 3} && mapBlocksInFlight.empty();
987 bool PeerManagerImpl::CanDirectFetch()
994 if (state->pindexBestKnownBlock && pindex == state->pindexBestKnownBlock->GetAncestor(pindex->nHeight))
996 if (state->pindexBestHeaderSent && pindex == state->pindexBestHeaderSent->GetAncestor(pindex->nHeight))
1001 void PeerManagerImpl::ProcessBlockAvailability(
NodeId nodeid) {
1002 CNodeState *state = State(nodeid);
1003 assert(state !=
nullptr);
1005 if (!state->hashLastUnknownBlock.IsNull()) {
1008 if (state->pindexBestKnownBlock ==
nullptr || pindex->
nChainWork >= state->pindexBestKnownBlock->nChainWork) {
1009 state->pindexBestKnownBlock = pindex;
1011 state->hashLastUnknownBlock.SetNull();
1016 void PeerManagerImpl::UpdateBlockAvailability(
NodeId nodeid,
const uint256 &hash) {
1017 CNodeState *state = State(nodeid);
1018 assert(state !=
nullptr);
1020 ProcessBlockAvailability(nodeid);
1025 if (state->pindexBestKnownBlock ==
nullptr || pindex->
nChainWork >= state->pindexBestKnownBlock->nChainWork) {
1026 state->pindexBestKnownBlock = pindex;
1030 state->hashLastUnknownBlock = hash;
1034 void PeerManagerImpl::FindNextBlocksToDownload(
NodeId nodeid,
unsigned int count, std::vector<const CBlockIndex*>& vBlocks,
NodeId& nodeStaller)
1039 vBlocks.reserve(vBlocks.size() +
count);
1040 CNodeState *state = State(nodeid);
1041 assert(state !=
nullptr);
1044 ProcessBlockAvailability(nodeid);
1051 if (state->pindexLastCommonBlock ==
nullptr) {
1054 state->pindexLastCommonBlock = m_chainman.
ActiveChain()[std::min(state->pindexBestKnownBlock->nHeight, m_chainman.
ActiveChain().
Height())];
1059 state->pindexLastCommonBlock =
LastCommonAncestor(state->pindexLastCommonBlock, state->pindexBestKnownBlock);
1060 if (state->pindexLastCommonBlock == state->pindexBestKnownBlock)
1064 std::vector<const CBlockIndex*> vToFetch;
1065 const CBlockIndex *pindexWalk = state->pindexLastCommonBlock;
1070 int nMaxHeight = std::min<int>(state->pindexBestKnownBlock->nHeight, nWindowEnd + 1);
1072 while (pindexWalk->
nHeight < nMaxHeight) {
1076 int nToFetch = std::min(nMaxHeight - pindexWalk->
nHeight, std::max<int>(
count - vBlocks.size(), 128));
1077 vToFetch.resize(nToFetch);
1078 pindexWalk = state->pindexBestKnownBlock->GetAncestor(pindexWalk->
nHeight + nToFetch);
1079 vToFetch[nToFetch - 1] = pindexWalk;
1080 for (
unsigned int i = nToFetch - 1; i > 0; i--) {
1081 vToFetch[i - 1] = vToFetch[i]->
pprev;
1099 state->pindexLastCommonBlock = pindex;
1100 }
else if (!IsBlockRequested(pindex->
GetBlockHash())) {
1102 if (pindex->
nHeight > nWindowEnd) {
1104 if (vBlocks.size() == 0 && waitingfor != nodeid) {
1106 nodeStaller = waitingfor;
1110 vBlocks.push_back(pindex);
1111 if (vBlocks.size() ==
count) {
1114 }
else if (waitingfor == -1) {
1116 waitingfor = mapBlocksInFlight[pindex->
GetBlockHash()].first;
1124 void PeerManagerImpl::PushNodeVersion(
CNode& pnode)
1130 const int64_t nTime{
count_seconds(GetTime<std::chrono::seconds>())};
1132 const int nNodeStartingHeight{m_best_height};
1141 your_services, addr_you,
1146 LogPrint(
BCLog::NET,
"send version message: version %d, blocks=%d, them=%s, txrelay=%d, peer=%d\n",
PROTOCOL_VERSION, nNodeStartingHeight, addr_you.
ToString(), tx_relay, nodeid);
1152 void PeerManagerImpl::AddTxAnnouncement(
const CNode&
node,
const GenTxid& gtxid, std::chrono::microseconds current_time)
1160 const CNodeState* state = State(nodeid);
1170 const bool preferred = state->fPreferredDownload;
1176 m_txrequest.ReceivedInv(nodeid, gtxid, preferred, current_time + delay);
1184 CNodeState *state = State(
node);
1185 if (state) state->m_last_block_announcement = time_in_seconds;
1188 void PeerManagerImpl::InitializeNode(
CNode *pnode)
1193 mapNodeState.emplace_hint(mapNodeState.end(), std::piecewise_construct, std::forward_as_tuple(nodeid), std::forward_as_tuple(pnode->
IsInboundConn()));
1194 assert(m_txrequest.Count(nodeid) == 0);
1197 PeerRef peer = std::make_shared<Peer>(nodeid);
1199 m_peer_map.emplace_hint(m_peer_map.end(), nodeid, std::move(peer));
1202 PushNodeVersion(*pnode);
1206 void PeerManagerImpl::ReattemptInitialBroadcast(
CScheduler& scheduler)
1210 for (
const auto& txid : unbroadcast_txids) {
1213 if (tx !=
nullptr) {
1215 _RelayTransaction(txid, tx->GetWitnessHash());
1223 const std::chrono::milliseconds delta = 10min +
GetRandMillis(5min);
1224 scheduler.
scheduleFromNow([&] { ReattemptInitialBroadcast(scheduler); }, delta);
1227 void PeerManagerImpl::FinalizeNode(
const CNode&
node)
1239 PeerRef peer = RemovePeer(nodeid);
1241 misbehavior =
WITH_LOCK(peer->m_misbehavior_mutex,
return peer->m_misbehavior_score);
1243 CNodeState *state = State(nodeid);
1244 assert(state !=
nullptr);
1246 if (state->fSyncStarted)
1249 for (
const QueuedBlock& entry : state->vBlocksInFlight) {
1250 mapBlocksInFlight.erase(entry.pindex->GetBlockHash());
1253 m_txrequest.DisconnectedPeer(nodeid);
1254 nPreferredDownload -= state->fPreferredDownload;
1255 m_peers_downloading_from -= (state->nBlocksInFlight != 0);
1256 assert(m_peers_downloading_from >= 0);
1257 m_outbound_peers_with_protect_from_disconnect -= state->m_chain_sync.m_protect;
1258 assert(m_outbound_peers_with_protect_from_disconnect >= 0);
1259 m_wtxid_relay_peers -= state->m_wtxid_relay;
1260 assert(m_wtxid_relay_peers >= 0);
1262 mapNodeState.erase(nodeid);
1264 if (mapNodeState.empty()) {
1266 assert(mapBlocksInFlight.empty());
1267 assert(nPreferredDownload == 0);
1268 assert(m_peers_downloading_from == 0);
1269 assert(m_outbound_peers_with_protect_from_disconnect == 0);
1270 assert(m_wtxid_relay_peers == 0);
1271 assert(m_txrequest.Size() == 0);
1272 assert(m_orphanage.Size() == 0);
1275 if (
node.fSuccessfullyConnected && misbehavior == 0 &&
1276 !
node.IsBlockOnlyConn() && !
node.IsInboundConn()) {
1285 PeerRef PeerManagerImpl::GetPeerRef(
NodeId id)
const
1288 auto it = m_peer_map.find(
id);
1289 return it != m_peer_map.end() ? it->second :
nullptr;
1292 PeerRef PeerManagerImpl::RemovePeer(
NodeId id)
1296 auto it = m_peer_map.find(
id);
1297 if (it != m_peer_map.end()) {
1298 ret = std::move(it->second);
1299 m_peer_map.erase(it);
1308 CNodeState* state = State(nodeid);
1309 if (state ==
nullptr)
1311 stats.
nSyncHeight = state->pindexBestKnownBlock ? state->pindexBestKnownBlock->nHeight : -1;
1312 stats.
nCommonHeight = state->pindexLastCommonBlock ? state->pindexLastCommonBlock->nHeight : -1;
1313 for (
const QueuedBlock& queue : state->vBlocksInFlight) {
1319 PeerRef peer = GetPeerRef(nodeid);
1320 if (peer ==
nullptr)
return false;
1328 auto ping_wait{0us};
1329 if ((0 != peer->m_ping_nonce_sent) && (0 != peer->m_ping_start.load().count())) {
1330 ping_wait = GetTime<std::chrono::microseconds>() - peer->m_ping_start.load();
1341 void PeerManagerImpl::AddToCompactExtraTransactions(
const CTransactionRef& tx)
1344 if (max_extra_txn <= 0)
1346 if (!vExtraTxnForCompact.size())
1347 vExtraTxnForCompact.resize(max_extra_txn);
1348 vExtraTxnForCompact[vExtraTxnForCompactIt] = std::make_pair(tx->GetWitnessHash(), tx);
1349 vExtraTxnForCompactIt = (vExtraTxnForCompactIt + 1) % max_extra_txn;
1352 void PeerManagerImpl::Misbehaving(
const NodeId pnode,
const int howmuch,
const std::string& message)
1356 PeerRef peer = GetPeerRef(pnode);
1357 if (peer ==
nullptr)
return;
1359 LOCK(peer->m_misbehavior_mutex);
1360 const int score_before{peer->m_misbehavior_score};
1361 peer->m_misbehavior_score += howmuch;
1362 const int score_now{peer->m_misbehavior_score};
1364 const std::string message_prefixed = message.empty() ?
"" : (
": " + message);
1365 std::string warning;
1368 warning =
" DISCOURAGE THRESHOLD EXCEEDED";
1369 peer->m_should_discourage =
true;
1373 pnode, score_before, score_now, warning, message_prefixed);
1377 bool via_compact_block,
const std::string& message)
1385 if (!via_compact_block) {
1393 CNodeState *node_state = State(nodeid);
1394 if (node_state ==
nullptr) {
1400 if (!via_compact_block && !node_state->m_is_inbound) {
1420 if (message !=
"") {
1426 bool PeerManagerImpl::MaybePunishNodeForTx(
NodeId nodeid,
const TxValidationState& state,
const std::string& message)
1448 if (message !=
"") {
1454 bool PeerManagerImpl::BlockRequestAllowed(
const CBlockIndex* pindex)
1463 std::optional<std::string> PeerManagerImpl::FetchBlock(
NodeId peer_id,
const CBlockIndex& block_index)
1466 if (
fReindex)
return "Reindexing...";
1470 CNodeState* state = State(peer_id);
1471 if (state ==
nullptr)
return "Peer does not exist";
1473 if (!state->fHaveWitness)
return "Pre-SegWit peer";
1478 if (!BlockRequested(peer_id, block_index))
return "Already requested from this peer";
1491 if (!success)
return "Peer not fully connected";
1495 return std::nullopt;
1502 return std::make_unique<PeerManagerImpl>(chainparams, connman, addrman, banman, chainman, pool, ignore_incoming_txs);
1508 : m_chainparams(chainparams),
1512 m_chainman(chainman),
1514 m_ignore_incoming_txs(ignore_incoming_txs)
1518 void PeerManagerImpl::StartScheduledTasks(
CScheduler& scheduler)
1528 const std::chrono::milliseconds delta = 10min +
GetRandMillis(5min);
1529 scheduler.
scheduleFromNow([&] { ReattemptInitialBroadcast(scheduler); }, delta);
1537 void PeerManagerImpl::BlockConnected(
const std::shared_ptr<const CBlock>& pblock,
const CBlockIndex* pindex)
1539 m_orphanage.EraseForBlock(*pblock);
1540 m_last_tip_update = GetTime<std::chrono::seconds>();
1543 LOCK(m_recent_confirmed_transactions_mutex);
1544 for (
const auto& ptx : pblock->vtx) {
1545 m_recent_confirmed_transactions.insert(ptx->GetHash());
1546 if (ptx->GetHash() != ptx->GetWitnessHash()) {
1547 m_recent_confirmed_transactions.insert(ptx->GetWitnessHash());
1553 for (
const auto& ptx : pblock->vtx) {
1554 m_txrequest.ForgetTxHash(ptx->GetHash());
1555 m_txrequest.ForgetTxHash(ptx->GetWitnessHash());
1560 void PeerManagerImpl::BlockDisconnected(
const std::shared_ptr<const CBlock> &block,
const CBlockIndex* pindex)
1570 LOCK(m_recent_confirmed_transactions_mutex);
1571 m_recent_confirmed_transactions.reset();
1585 void PeerManagerImpl::NewPoWValidBlock(
const CBlockIndex *pindex,
const std::shared_ptr<const CBlock>& pblock)
1587 std::shared_ptr<const CBlockHeaderAndShortTxIDs> pcmpctblock = std::make_shared<const CBlockHeaderAndShortTxIDs> (*pblock,
true);
1592 static int nHighestFastAnnounce = 0;
1593 if (pindex->
nHeight <= nHighestFastAnnounce)
1595 nHighestFastAnnounce = pindex->
nHeight;
1598 uint256 hashBlock(pblock->GetHash());
1602 most_recent_block_hash = hashBlock;
1603 most_recent_block = pblock;
1604 most_recent_compact_block = pcmpctblock;
1605 fWitnessesPresentInMostRecentCompactBlock = fWitnessEnabled;
1614 ProcessBlockAvailability(pnode->
GetId());
1615 CNodeState &state = *State(pnode->
GetId());
1618 if (state.fPreferHeaderAndIDs && (!fWitnessEnabled || state.fWantsCmpctWitness) &&
1619 !PeerHasHeader(&state, pindex) && PeerHasHeader(&state, pindex->
pprev)) {
1621 LogPrint(
BCLog::NET,
"%s sending header-and-ids %s to peer=%d\n",
"PeerManager::NewPoWValidBlock",
1622 hashBlock.ToString(), pnode->
GetId());
1624 state.pindexBestHeaderSent = pindex;
1633 void PeerManagerImpl::UpdatedBlockTip(
const CBlockIndex *pindexNew,
const CBlockIndex *pindexFork,
bool fInitialDownload)
1635 SetBestHeight(pindexNew->
nHeight);
1639 if (fInitialDownload)
return;
1642 std::vector<uint256> vHashes;
1644 while (pindexToAnnounce != pindexFork) {
1646 pindexToAnnounce = pindexToAnnounce->
pprev;
1656 for (
auto& it : m_peer_map) {
1657 Peer& peer = *it.second;
1658 LOCK(peer.m_block_inv_mutex);
1660 peer.m_blocks_for_headers_relay.push_back(hash);
1677 std::map<uint256, std::pair<NodeId, bool>>::iterator it = mapBlockSource.find(hash);
1682 it != mapBlockSource.end() &&
1683 State(it->second.first)) {
1684 MaybePunishNodeForBlock( it->second.first, state, !it->second.second);
1694 mapBlocksInFlight.count(hash) == mapBlocksInFlight.size()) {
1695 if (it != mapBlockSource.end()) {
1696 MaybeSetPeerAsAnnouncingHeaderAndIDs(it->second.first);
1699 if (it != mapBlockSource.end())
1700 mapBlockSource.erase(it);
1709 bool PeerManagerImpl::AlreadyHaveTx(
const GenTxid& gtxid)
1717 m_recent_rejects.reset();
1722 if (m_orphanage.HaveTx(gtxid))
return true;
1725 LOCK(m_recent_confirmed_transactions_mutex);
1726 if (m_recent_confirmed_transactions.contains(hash))
return true;
1729 return m_recent_rejects.contains(hash) || m_mempool.
exists(gtxid);
1732 bool PeerManagerImpl::AlreadyHaveBlock(
const uint256& block_hash)
1737 void PeerManagerImpl::SendPings()
1740 for(
auto& it : m_peer_map) it.second->m_ping_queued =
true;
1743 void PeerManagerImpl::RelayTransaction(
const uint256& txid,
const uint256& wtxid)
1748 void PeerManagerImpl::_RelayTransaction(
const uint256& txid,
const uint256& wtxid)
1753 CNodeState* state = State(pnode->
GetId());
1754 if (state ==
nullptr)
return;
1755 if (state->m_wtxid_relay) {
1763 void PeerManagerImpl::RelayAddress(
NodeId originator,
1778 const uint64_t hashAddr{addr.
GetHash()};
1783 unsigned int nRelayNodes = (fReachable || (hasher.Finalize() & 1)) ? 2 : 1;
1785 std::array<std::pair<uint64_t, Peer*>, 2> best{{{0,
nullptr}, {0,
nullptr}}};
1786 assert(nRelayNodes <= best.size());
1790 for (
auto& [
id, peer] : m_peer_map) {
1791 if (peer->m_addr_relay_enabled &&
id != originator && IsAddrCompatible(*peer, addr)) {
1793 for (
unsigned int i = 0; i < nRelayNodes; i++) {
1794 if (hashKey > best[i].first) {
1795 std::copy(best.begin() + i, best.begin() + nRelayNodes - 1, best.begin() + i + 1);
1796 best[i] = std::make_pair(hashKey, peer.get());
1803 for (
unsigned int i = 0; i < nRelayNodes && best[i].first != 0; i++) {
1804 PushAddress(*best[i].second, addr, insecure_rand);
1808 void PeerManagerImpl::ProcessGetBlockData(
CNode& pfrom, Peer& peer,
const CInv& inv)
1810 std::shared_ptr<const CBlock> a_recent_block;
1811 std::shared_ptr<const CBlockHeaderAndShortTxIDs> a_recent_compact_block;
1812 bool fWitnessesPresentInARecentCompactBlock;
1815 a_recent_block = most_recent_block;
1816 a_recent_compact_block = most_recent_compact_block;
1817 fWitnessesPresentInARecentCompactBlock = fWitnessesPresentInMostRecentCompactBlock;
1820 bool need_activate_chain =
false;
1832 need_activate_chain =
true;
1836 if (need_activate_chain) {
1838 if (!m_chainman.
ActiveChainstate().ActivateBestChain(state, a_recent_block)) {
1848 if (!BlockRequestAllowed(pindex)) {
1849 LogPrint(
BCLog::NET,
"%s: ignoring request from peer=%i for old block that isn't in the main chain\n", __func__, pfrom.
GetId());
1866 LogPrint(
BCLog::NET,
"Ignore block request below NODE_NETWORK_LIMITED threshold, disconnect peer=%d\n", pfrom.
GetId());
1876 std::shared_ptr<const CBlock> pblock;
1877 if (a_recent_block && a_recent_block->GetHash() == pindex->
GetBlockHash()) {
1878 pblock = a_recent_block;
1882 std::vector<uint8_t> block_data;
1884 assert(!
"cannot load block from disk");
1890 std::shared_ptr<CBlock> pblockRead = std::make_shared<CBlock>();
1892 assert(!
"cannot load block from disk");
1894 pblock = pblockRead;
1902 bool sendMerkleBlock =
false;
1907 sendMerkleBlock =
true;
1911 if (sendMerkleBlock) {
1919 typedef std::pair<unsigned int, uint256> PairType;
1930 bool fPeerWantsWitness = State(pfrom.
GetId())->fWantsCmpctWitness;
1933 if ((fPeerWantsWitness || !fWitnessesPresentInARecentCompactBlock) && a_recent_compact_block && a_recent_compact_block->header.GetHash() == pindex->
GetBlockHash()) {
1946 LOCK(peer.m_block_inv_mutex);
1948 if (inv.
hash == peer.m_continuation_block) {
1952 std::vector<CInv> vInv;
1955 peer.m_continuation_block.SetNull();
1960 CTransactionRef PeerManagerImpl::FindTxForGetData(
const CNode& peer,
const GenTxid& gtxid,
const std::chrono::seconds mempool_req,
const std::chrono::seconds now)
1962 auto txinfo = m_mempool.
info(gtxid);
1968 return std::move(txinfo.tx);
1975 if (State(peer.
GetId())->m_recently_announced_invs.contains(gtxid.
GetHash())) {
1977 if (txinfo.tx)
return std::move(txinfo.tx);
1979 auto mi = mapRelay.find(gtxid.
GetHash());
1980 if (mi != mapRelay.end())
return mi->second;
1987 void PeerManagerImpl::ProcessGetData(
CNode& pfrom, Peer& peer,
const std::atomic<bool>& interruptMsgProc)
1991 std::deque<CInv>::iterator it = peer.m_getdata_requests.begin();
1992 std::vector<CInv> vNotFound;
1995 const auto now{GetTime<std::chrono::seconds>()};
1997 const auto mempool_req = pfrom.
m_tx_relay !=
nullptr ? pfrom.
m_tx_relay->m_last_mempool_req.load() : std::chrono::seconds::min();
2002 while (it != peer.m_getdata_requests.end() && it->IsGenTxMsg()) {
2003 if (interruptMsgProc)
return;
2008 const CInv &inv = *it++;
2022 std::vector<uint256> parent_ids_to_add;
2025 auto txiter = m_mempool.
GetIter(tx->GetHash());
2028 parent_ids_to_add.reserve(parents.size());
2031 parent_ids_to_add.push_back(parent.GetTx().GetHash());
2036 for (
const uint256& parent_txid : parent_ids_to_add) {
2040 State(pfrom.
GetId())->m_recently_announced_invs.insert(parent_txid);
2044 vNotFound.push_back(inv);
2050 if (it != peer.m_getdata_requests.end() && !pfrom.
fPauseSend) {
2051 const CInv &inv = *it++;
2053 ProcessGetBlockData(pfrom, peer, inv);
2059 peer.m_getdata_requests.erase(peer.m_getdata_requests.begin(), it);
2061 if (!vNotFound.empty()) {
2081 uint32_t nFetchFlags = 0;
2082 if (State(pfrom.
GetId())->fHaveWitness) {
2091 for (
size_t i = 0; i < req.
indexes.size(); i++) {
2093 Misbehaving(pfrom.
GetId(), 100,
"getblocktxn with out-of-bounds tx indices");
2104 void PeerManagerImpl::ProcessHeadersMessage(
CNode& pfrom,
const Peer& peer,
2105 const std::vector<CBlockHeader>& headers,
2106 bool via_compact_block)
2109 size_t nCount = headers.size();
2116 bool received_new_header =
false;
2120 CNodeState *nodestate = State(pfrom.
GetId());
2131 nodestate->nUnconnectingHeaders++;
2133 LogPrint(
BCLog::NET,
"received header %s: missing prev block %s, sending getheaders (%d) to end (peer=%d, nUnconnectingHeaders=%d)\n",
2135 headers[0].hashPrevBlock.ToString(),
2137 pfrom.
GetId(), nodestate->nUnconnectingHeaders);
2141 UpdateBlockAvailability(pfrom.
GetId(), headers.back().GetHash());
2144 Misbehaving(pfrom.
GetId(), 20,
strprintf(
"%d non-connecting headers", nodestate->nUnconnectingHeaders));
2151 if (!hashLastBlock.
IsNull() && header.hashPrevBlock != hashLastBlock) {
2152 Misbehaving(pfrom.
GetId(), 20,
"non-continuous headers sequence");
2155 hashLastBlock = header.GetHash();
2161 received_new_header =
true;
2168 MaybePunishNodeForBlock(pfrom.
GetId(), state, via_compact_block,
"invalid header received");
2175 CNodeState *nodestate = State(pfrom.
GetId());
2176 if (nodestate->nUnconnectingHeaders > 0) {
2177 LogPrint(
BCLog::NET,
"peer=%d: resetting nUnconnectingHeaders (%d -> 0)\n", pfrom.
GetId(), nodestate->nUnconnectingHeaders);
2179 nodestate->nUnconnectingHeaders = 0;
2189 nodestate->m_last_block_announcement =
GetTime();
2197 pindexLast->
nHeight, pfrom.
GetId(), peer.m_starting_height);
2204 std::vector<const CBlockIndex*> vToFetch;
2212 vToFetch.push_back(pindexWalk);
2214 pindexWalk = pindexWalk->
pprev;
2225 std::vector<CInv> vGetData;
2234 BlockRequested(pfrom.
GetId(), *pindex);
2238 if (vGetData.size() > 1) {
2242 if (vGetData.size() > 0) {
2243 if (!m_ignore_incoming_txs &&
2244 nodestate->fSupportsDesiredCmpctVersion &&
2245 vGetData.size() == 1 &&
2246 mapBlocksInFlight.size() == 1 &&
2260 if (nodestate->pindexBestKnownBlock && nodestate->pindexBestKnownBlock->nChainWork <
nMinimumChainWork) {
2270 LogPrintf(
"Disconnecting outbound peer %d -- headers chain has insufficient work\n", pfrom.
GetId());
2282 if (m_outbound_peers_with_protect_from_disconnect < MAX_OUTBOUND_PEERS_TO_PROTECT_FROM_DISCONNECT && nodestate->pindexBestKnownBlock->nChainWork >= m_chainman.
ActiveChain().
Tip()->
nChainWork && !nodestate->m_chain_sync.m_protect) {
2284 nodestate->m_chain_sync.m_protect =
true;
2285 ++m_outbound_peers_with_protect_from_disconnect;
2301 void PeerManagerImpl::ProcessOrphanTx(std::set<uint256>& orphan_work_set)
2306 while (!orphan_work_set.empty()) {
2308 orphan_work_set.erase(orphan_work_set.begin());
2310 const auto [porphanTx, from_peer] = m_orphanage.GetTx(orphanHash);
2311 if (porphanTx ==
nullptr)
continue;
2318 _RelayTransaction(orphanHash, porphanTx->GetWitnessHash());
2319 m_orphanage.AddChildrenToWorkSet(*porphanTx, orphan_work_set);
2320 m_orphanage.EraseTx(orphanHash);
2322 AddToCompactExtraTransactions(removedTx);
2332 MaybePunishNodeForTx(from_peer, state);
2351 m_recent_rejects.insert(porphanTx->GetWitnessHash());
2363 m_recent_rejects.insert(porphanTx->GetHash());
2366 m_orphanage.EraseTx(orphanHash);
2372 bool PeerManagerImpl::PrepareBlockFilterRequest(
CNode& peer,
2374 const uint256& stop_hash, uint32_t max_height_diff,
2378 const bool supported_filter_type =
2381 if (!supported_filter_type) {
2383 peer.
GetId(),
static_cast<uint8_t
>(filter_type));
2393 if (!stop_index || !BlockRequestAllowed(stop_index)) {
2401 uint32_t stop_height = stop_index->
nHeight;
2402 if (start_height > stop_height) {
2404 "start height %d and stop height %d\n",
2405 peer.
GetId(), start_height, stop_height);
2409 if (stop_height - start_height >= max_height_diff) {
2411 peer.
GetId(), stop_height - start_height + 1, max_height_diff);
2417 if (!filter_index) {
2427 uint8_t filter_type_ser;
2428 uint32_t start_height;
2431 vRecv >> filter_type_ser >> start_height >> stop_hash;
2437 if (!PrepareBlockFilterRequest(peer, filter_type, start_height, stop_hash,
2442 std::vector<BlockFilter> filters;
2444 LogPrint(
BCLog::NET,
"Failed to find block filter in index: filter_type=%s, start_height=%d, stop_hash=%s\n",
2449 for (
const auto& filter : filters) {
2458 uint8_t filter_type_ser;
2459 uint32_t start_height;
2462 vRecv >> filter_type_ser >> start_height >> stop_hash;
2468 if (!PrepareBlockFilterRequest(peer, filter_type, start_height, stop_hash,
2474 if (start_height > 0) {
2476 stop_index->
GetAncestor(
static_cast<int>(start_height - 1));
2478 LogPrint(
BCLog::NET,
"Failed to find block filter header in index: filter_type=%s, block_hash=%s\n",
2484 std::vector<uint256> filter_hashes;
2486 LogPrint(
BCLog::NET,
"Failed to find block filter hashes in index: filter_type=%s, start_height=%d, stop_hash=%s\n",
2502 uint8_t filter_type_ser;
2505 vRecv >> filter_type_ser >> stop_hash;
2511 if (!PrepareBlockFilterRequest(peer, filter_type, 0, stop_hash,
2512 std::numeric_limits<uint32_t>::max(),
2513 stop_index, filter_index)) {
2521 for (
int i = headers.size() - 1; i >= 0; i--) {
2526 LogPrint(
BCLog::NET,
"Failed to find block filter header in index: filter_type=%s, block_hash=%s\n",
2540 void PeerManagerImpl::ProcessBlock(
CNode&
node,
const std::shared_ptr<const CBlock>& block,
bool force_processing)
2542 bool new_block{
false};
2543 m_chainman.
ProcessNewBlock(m_chainparams, block, force_processing, &new_block);
2545 node.m_last_block_time = GetTime<std::chrono::seconds>();
2548 mapBlockSource.erase(block->GetHash());
2552 void PeerManagerImpl::ProcessMessage(
CNode& pfrom,
const std::string& msg_type,
CDataStream& vRecv,
2553 const std::chrono::microseconds time_received,
2554 const std::atomic<bool>& interruptMsgProc)
2558 PeerRef peer = GetPeerRef(pfrom.
GetId());
2559 if (peer ==
nullptr)
return;
2569 uint64_t nNonce = 1;
2572 std::string cleanSubVer;
2573 int starting_height = -1;
2576 vRecv >> nVersion >> Using<CustomUintFormatter<8>>(nServices) >> nTime;
2600 if (!vRecv.
empty()) {
2608 if (!vRecv.
empty()) {
2609 std::string strSubVer;
2613 if (!vRecv.
empty()) {
2614 vRecv >> starting_height;
2634 PushNodeVersion(pfrom);
2649 if (greatest_common_version >= 70016) {
2663 pfrom.cleanSubVer = cleanSubVer;
2665 peer->m_starting_height = starting_height;
2681 State(pfrom.
GetId())->fHaveWitness =
true;
2687 UpdatePreferredDownload(pfrom, State(pfrom.
GetId()));
2691 if (!pfrom.
IsInboundConn() && SetupAddressRelay(pfrom, *peer)) {
2710 PushAddress(*peer, addr, insecure_rand);
2714 PushAddress(*peer, addr, insecure_rand);
2720 peer->m_getaddr_sent =
true;
2744 std::string remoteAddr;
2748 LogPrint(
BCLog::NET,
"receive version message: %s: version %d, blocks=%d, us=%s, txrelay=%d, peer=%d%s\n",
2750 peer->m_starting_height, addrMe.ToString(), fRelay, pfrom.
GetId(),
2753 int64_t nTimeOffset = nTime -
GetTime();
2762 if (greatest_common_version <= 70012) {
2763 CDataStream finalAlert(
ParseHex(
"60010000000000000000000000ffffff7f00000000ffffff7ffeffff7f01ffffff7f00000000ffffff7f00ffffff7f002f555247454e543a20416c657274206b657920636f6d70726f6d697365642c2075706772616465207265717569726564004630440220653febd6410f470f6bae11cad19c48413becb1ac2c17f908fd0fd53bdc3abd5202206d0e9c96fe88d4a0f01ed9dedae2b6f9e00da94cad0fecaae66ecf689bf71b50"),
SER_NETWORK,
PROTOCOL_VERSION);
2791 LogPrintf(
"New outbound peer connected: version: %d, blocks=%d, peer=%d%s (%s)\n",
2792 pfrom.
nVersion.load(), peer->m_starting_height,
2810 bool fAnnounceUsingCMPCTBLOCK =
false;
2811 uint64_t nCMPCTBLOCKVersion = 2;
2813 nCMPCTBLOCKVersion = 1;
2822 State(pfrom.
GetId())->fPreferHeaders =
true;
2827 bool fAnnounceUsingCMPCTBLOCK =
false;
2828 uint64_t nCMPCTBLOCKVersion = 0;
2829 vRecv >> fAnnounceUsingCMPCTBLOCK >> nCMPCTBLOCKVersion;
2830 if (nCMPCTBLOCKVersion == 1 || nCMPCTBLOCKVersion == 2) {
2833 if (!State(pfrom.
GetId())->fProvidesHeaderAndIDs) {
2834 State(pfrom.
GetId())->fProvidesHeaderAndIDs =
true;
2835 State(pfrom.
GetId())->fWantsCmpctWitness = nCMPCTBLOCKVersion == 2;
2837 if (State(pfrom.
GetId())->fWantsCmpctWitness == (nCMPCTBLOCKVersion == 2)) {
2838 State(pfrom.
GetId())->fPreferHeaderAndIDs = fAnnounceUsingCMPCTBLOCK;
2843 if (!State(pfrom.
GetId())->fSupportsDesiredCmpctVersion) {
2844 State(pfrom.
GetId())->fSupportsDesiredCmpctVersion = (nCMPCTBLOCKVersion == 2);
2861 if (!State(pfrom.
GetId())->m_wtxid_relay) {
2862 State(pfrom.
GetId())->m_wtxid_relay =
true;
2863 m_wtxid_relay_peers++;
2882 peer->m_wants_addrv2 =
true;
2900 std::vector<CAddress> vAddr;
2904 if (!SetupAddressRelay(pfrom, *peer)) {
2911 Misbehaving(pfrom.
GetId(), 20,
strprintf(
"%s message size = %u", msg_type, vAddr.size()));
2916 std::vector<CAddress> vAddrOk;
2918 int64_t nSince = nNow - 10 * 60;
2921 const auto current_time{GetTime<std::chrono::microseconds>()};
2924 const auto time_diff = std::max(current_time - peer->m_addr_token_timestamp, 0us);
2928 peer->m_addr_token_timestamp = current_time;
2931 uint64_t num_proc = 0;
2932 uint64_t num_rate_limit = 0;
2936 if (interruptMsgProc)
2940 if (peer->m_addr_token_bucket < 1.0) {
2946 peer->m_addr_token_bucket -= 1.0;
2954 if (addr.
nTime <= 100000000 || addr.
nTime > nNow + 10 * 60)
2955 addr.
nTime = nNow - 5 * 24 * 60 * 60;
2956 AddAddressKnown(*peer, addr);
2963 if (addr.
nTime > nSince && !peer->m_getaddr_sent && vAddr.size() <= 10 && addr.
IsRoutable()) {
2965 RelayAddress(pfrom.
GetId(), addr, fReachable);
2969 vAddrOk.push_back(addr);
2971 peer->m_addr_processed += num_proc;
2972 peer->m_addr_rate_limited += num_rate_limit;
2973 LogPrint(
BCLog::NET,
"Received addr: %u addresses (%u processed, %u rate-limited) from peer=%d\n",
2974 vAddr.size(), num_proc, num_rate_limit, pfrom.
GetId());
2976 m_addrman.
Add(vAddrOk, pfrom.
addr, 2 * 60 * 60);
2977 if (vAddr.size() < 1000) peer->m_getaddr_sent =
false;
2988 std::vector<CInv> vInv;
2992 Misbehaving(pfrom.
GetId(), 20,
strprintf(
"inv message size = %u", vInv.size()));
2998 bool reject_tx_invs{m_ignore_incoming_txs || (pfrom.
m_tx_relay ==
nullptr)};
3002 reject_tx_invs =
false;
3007 const auto current_time{GetTime<std::chrono::microseconds>()};
3010 for (
CInv& inv : vInv) {
3011 if (interruptMsgProc)
return;
3016 if (State(pfrom.
GetId())->m_wtxid_relay) {
3023 const bool fAlreadyHave = AlreadyHaveBlock(inv.
hash);
3026 UpdateBlockAvailability(pfrom.
GetId(), inv.
hash);
3033 best_block = &inv.
hash;
3036 if (reject_tx_invs) {
3042 const bool fAlreadyHave = AlreadyHaveTx(gtxid);
3046 if (!fAlreadyHave && !m_chainman.
ActiveChainstate().IsInitialBlockDownload()) {
3047 AddTxAnnouncement(pfrom, gtxid, current_time);
3054 if (best_block !=
nullptr) {
3063 std::vector<CInv> vInv;
3067 Misbehaving(pfrom.
GetId(), 20,
strprintf(
"getdata message size = %u", vInv.size()));
3073 if (vInv.size() > 0) {
3078 LOCK(peer->m_getdata_requests_mutex);
3079 peer->m_getdata_requests.insert(peer->m_getdata_requests.end(), vInv.begin(), vInv.end());
3080 ProcessGetData(pfrom, *peer, interruptMsgProc);
3089 vRecv >> locator >> hashStop;
3105 std::shared_ptr<const CBlock> a_recent_block;
3108 a_recent_block = most_recent_block;
3111 if (!m_chainman.
ActiveChainstate().ActivateBestChain(state, a_recent_block)) {
3125 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());
3126 for (; pindex; pindex = m_chainman.
ActiveChain().Next(pindex))
3142 if (--nLimit <= 0) {
3146 WITH_LOCK(peer->m_block_inv_mutex, {peer->m_continuation_block = pindex->GetBlockHash();});
3157 std::shared_ptr<const CBlock> recent_block;
3160 if (most_recent_block_hash == req.blockhash)
3161 recent_block = most_recent_block;
3165 SendBlockTransactions(pfrom, *recent_block, req);
3183 SendBlockTransactions(pfrom, block, req);
3198 inv.
hash = req.blockhash;
3199 WITH_LOCK(peer->m_getdata_requests_mutex, peer->m_getdata_requests.push_back(inv));
3207 vRecv >> locator >> hashStop;
3217 LogPrint(
BCLog::NET,
"Ignoring getheaders from peer=%d because node is in initial block download\n", pfrom.
GetId());
3221 CNodeState *nodestate = State(pfrom.
GetId());
3231 if (!BlockRequestAllowed(pindex)) {
3232 LogPrint(
BCLog::NET,
"%s: ignoring request from peer=%i for old block header that isn't in the main chain\n", __func__, pfrom.
GetId());
3245 std::vector<CBlock> vHeaders;
3247 LogPrint(
BCLog::NET,
"getheaders %d to %s from peer=%d\n", (pindex ? pindex->
nHeight : -1), hashStop.IsNull() ?
"end" : hashStop.ToString(), pfrom.
GetId());
3248 for (; pindex; pindex = m_chainman.
ActiveChain().Next(pindex))
3251 if (--nLimit <= 0 || pindex->GetBlockHash() == hashStop)
3266 nodestate->pindexBestHeaderSent = pindex ? pindex : m_chainman.
ActiveChain().
Tip();
3291 const uint256& txid = ptx->GetHash();
3292 const uint256& wtxid = ptx->GetWitnessHash();
3296 CNodeState* nodestate = State(pfrom.
GetId());
3298 const uint256& hash = nodestate->m_wtxid_relay ? wtxid : txid;
3300 if (nodestate->m_wtxid_relay && txid != wtxid) {
3309 m_txrequest.ReceivedResponse(pfrom.
GetId(), txid);
3310 if (tx.
HasWitness()) m_txrequest.ReceivedResponse(pfrom.
GetId(), wtxid);
3345 m_txrequest.ForgetTxHash(tx.
GetHash());
3348 m_orphanage.AddChildrenToWorkSet(tx, peer->m_orphan_work_set);
3358 AddToCompactExtraTransactions(removedTx);
3362 ProcessOrphanTx(peer->m_orphan_work_set);
3366 bool fRejectedParents =
false;
3370 std::vector<uint256> unique_parents;
3371 unique_parents.reserve(tx.
vin.size());
3376 std::sort(unique_parents.begin(), unique_parents.end());
3377 unique_parents.erase(std::unique(unique_parents.begin(), unique_parents.end()), unique_parents.end());
3378 for (
const uint256& parent_txid : unique_parents) {
3379 if (m_recent_rejects.contains(parent_txid)) {
3380 fRejectedParents =
true;
3384 if (!fRejectedParents) {
3385 const auto current_time{GetTime<std::chrono::microseconds>()};
3387 for (
const uint256& parent_txid : unique_parents) {
3395 if (!AlreadyHaveTx(gtxid)) AddTxAnnouncement(pfrom, gtxid, current_time);
3398 if (m_orphanage.AddTx(ptx, pfrom.
GetId())) {
3399 AddToCompactExtraTransactions(ptx);
3403 m_txrequest.ForgetTxHash(tx.
GetHash());
3408 unsigned int nEvicted = m_orphanage.LimitOrphans(nMaxOrphanTx);
3420 m_recent_rejects.insert(tx.
GetHash());
3422 m_txrequest.ForgetTxHash(tx.
GetHash());
3451 m_recent_rejects.insert(tx.
GetHash());
3452 m_txrequest.ForgetTxHash(tx.
GetHash());
3455 AddToCompactExtraTransactions(ptx);
3481 MaybePunishNodeForTx(pfrom.
GetId(), state);
3495 vRecv >> cmpctblock;
3497 bool received_new_header =
false;
3510 received_new_header =
true;
3518 MaybePunishNodeForBlock(pfrom.
GetId(), state,
true,
"invalid header via cmpctblock");
3527 bool fProcessBLOCKTXN =
false;
3532 bool fRevertToHeaderProcessing =
false;
3536 std::shared_ptr<CBlock> pblock = std::make_shared<CBlock>();
3537 bool fBlockReconstructed =
false;
3545 CNodeState *nodestate = State(pfrom.
GetId());
3550 nodestate->m_last_block_announcement =
GetTime();
3553 std::map<uint256, std::pair<NodeId, std::list<QueuedBlock>::iterator> >::iterator blockInFlightIt = mapBlocksInFlight.find(pindex->
GetBlockHash());
3554 bool fAlreadyInFlight = blockInFlightIt != mapBlocksInFlight.end();
3561 if (fAlreadyInFlight) {
3564 std::vector<CInv> vInv(1);
3572 if (!fAlreadyInFlight && !CanDirectFetch()) {
3586 (fAlreadyInFlight && blockInFlightIt->second.first == pfrom.
GetId())) {
3587 std::list<QueuedBlock>::iterator* queuedBlockIt =
nullptr;
3588 if (!BlockRequested(pfrom.
GetId(), *pindex, &queuedBlockIt)) {
3589 if (!(*queuedBlockIt)->partialBlock)
3602 Misbehaving(pfrom.
GetId(), 100,
"invalid compact block");
3606 std::vector<CInv> vInv(1);
3613 for (
size_t i = 0; i < cmpctblock.BlockTxCount(); i++) {
3620 txn.
blockhash = cmpctblock.header.GetHash();
3622 fProcessBLOCKTXN =
true;
3634 ReadStatus status = tempBlock.InitData(cmpctblock, vExtraTxnForCompact);
3639 std::vector<CTransactionRef> dummy;
3640 status = tempBlock.FillBlock(*pblock, dummy);
3642 fBlockReconstructed =
true;
3646 if (fAlreadyInFlight) {
3649 std::vector<CInv> vInv(1);
3655 fRevertToHeaderProcessing =
true;
3660 if (fProcessBLOCKTXN) {
3661 return ProcessMessage(pfrom,
NetMsgType::BLOCKTXN, blockTxnMsg, time_received, interruptMsgProc);
3664 if (fRevertToHeaderProcessing) {
3670 return ProcessHeadersMessage(pfrom, *peer, {cmpctblock.header},
true);
3673 if (fBlockReconstructed) {
3678 mapBlockSource.emplace(pblock->GetHash(), std::make_pair(pfrom.
GetId(),
false));
3689 ProcessBlock(pfrom, pblock,
true);
3696 RemoveBlockRequest(pblock->GetHash());
3713 std::shared_ptr<CBlock> pblock = std::make_shared<CBlock>();
3714 bool fBlockRead =
false;
3718 std::map<uint256, std::pair<NodeId, std::list<QueuedBlock>::iterator> >::iterator it = mapBlocksInFlight.find(resp.blockhash);
3719 if (it == mapBlocksInFlight.end() || !it->second.second->partialBlock ||
3720 it->second.first != pfrom.
GetId()) {
3728 RemoveBlockRequest(resp.blockhash);
3729 Misbehaving(pfrom.
GetId(), 100,
"invalid compact block/non-matching block transactions");
3733 std::vector<CInv> invs;
3754 RemoveBlockRequest(resp.blockhash);
3762 mapBlockSource.emplace(resp.blockhash, std::make_pair(pfrom.
GetId(),
false));
3772 ProcessBlock(pfrom, pblock,
true);
3785 std::vector<CBlockHeader> headers;
3790 Misbehaving(pfrom.
GetId(), 20,
strprintf(
"headers message size = %u", nCount));
3793 headers.resize(nCount);
3794 for (
unsigned int n = 0; n < nCount; n++) {
3795 vRecv >> headers[n];
3799 return ProcessHeadersMessage(pfrom, *peer, headers,
false);
3810 std::shared_ptr<CBlock> pblock = std::make_shared<CBlock>();
3815 bool forceProcessing =
false;
3816 const uint256 hash(pblock->GetHash());
3821 forceProcessing = IsBlockRequested(hash);
3822 RemoveBlockRequest(hash);
3826 mapBlockSource.emplace(hash, std::make_pair(pfrom.
GetId(),
true));
3828 ProcessBlock(pfrom, pblock, forceProcessing);
3845 Assume(SetupAddressRelay(pfrom, *peer));
3849 if (peer->m_getaddr_recvd) {
3853 peer->m_getaddr_recvd =
true;
3855 peer->m_addrs_to_send.clear();
3856 std::vector<CAddress> vAddr;
3863 for (
const CAddress &addr : vAddr) {
3864 PushAddress(*peer, addr, insecure_rand);
3918 const auto ping_end = time_received;
3921 bool bPingFinished =
false;
3922 std::string sProblem;
3924 if (nAvail >=
sizeof(
nonce)) {
3928 if (peer->m_ping_nonce_sent != 0) {
3929 if (
nonce == peer->m_ping_nonce_sent) {
3931 bPingFinished =
true;
3932 const auto ping_time = ping_end - peer->m_ping_start.load();
3933 if (ping_time.count() >= 0) {
3938 sProblem =
"Timing mishap";
3942 sProblem =
"Nonce mismatch";
3945 bPingFinished =
true;
3946 sProblem =
"Nonce zero";
3950 sProblem =
"Unsolicited pong without ping";
3954 bPingFinished =
true;
3955 sProblem =
"Short payload";
3958 if (!(sProblem.empty())) {
3962 peer->m_ping_nonce_sent,
3966 if (bPingFinished) {
3967 peer->m_ping_nonce_sent = 0;
3974 LogPrint(
BCLog::NET,
"filterload received despite not offering bloom services from peer=%d; disconnecting\n", pfrom.
GetId());
3981 if (!filter.IsWithinSizeConstraints())
3984 Misbehaving(pfrom.
GetId(), 100,
"too-large bloom filter");
3997 LogPrint(
BCLog::NET,
"filteradd received despite not offering bloom services from peer=%d; disconnecting\n", pfrom.
GetId());
4001 std::vector<unsigned char> vData;
4018 Misbehaving(pfrom.
GetId(), 100,
"bad filteradd message");
4025 LogPrint(
BCLog::NET,
"filterclear received despite not offering bloom services from peer=%d; disconnecting\n", pfrom.
GetId());
4040 vRecv >> newFeeFilter;
4043 pfrom.
m_tx_relay->minFeeFilter = newFeeFilter;
4051 ProcessGetCFilters(pfrom, vRecv);
4056 ProcessGetCFHeaders(pfrom, vRecv);
4061 ProcessGetCFCheckPt(pfrom, vRecv);
4066 std::vector<CInv> vInv;
4070 for (
CInv &inv : vInv) {
4074 m_txrequest.ReceivedResponse(pfrom.
GetId(), inv.
hash);
4086 bool PeerManagerImpl::MaybeDiscourageAndDisconnect(
CNode& pnode, Peer& peer)
4089 LOCK(peer.m_misbehavior_mutex);
4092 if (!peer.m_should_discourage)
return false;
4094 peer.m_should_discourage =
false;
4099 LogPrintf(
"Warning: not punishing noban peer %d!\n", peer.m_id);
4105 LogPrintf(
"Warning: not punishing manually connected peer %d!\n", peer.m_id);
4125 bool PeerManagerImpl::ProcessMessages(
CNode* pfrom, std::atomic<bool>& interruptMsgProc)
4127 bool fMoreWork =
false;
4129 PeerRef peer = GetPeerRef(pfrom->
GetId());
4130 if (peer ==
nullptr)
return false;
4133 LOCK(peer->m_getdata_requests_mutex);
4134 if (!peer->m_getdata_requests.empty()) {
4135 ProcessGetData(*pfrom, *peer, interruptMsgProc);
4141 if (!peer->m_orphan_work_set.empty()) {
4142 ProcessOrphanTx(peer->m_orphan_work_set);
4152 LOCK(peer->m_getdata_requests_mutex);
4153 if (!peer->m_getdata_requests.empty())
return true;
4158 if (!peer->m_orphan_work_set.empty())
return true;
4164 std::list<CNetMessage> msgs;
4167 if (pfrom->vProcessMsg.empty())
return false;
4169 msgs.splice(msgs.begin(), pfrom->vProcessMsg, pfrom->vProcessMsg.begin());
4172 fMoreWork = !pfrom->vProcessMsg.empty();
4176 TRACE6(net, inbound_message,
4192 ProcessMessage(*pfrom, msg.
m_type, msg.m_recv, msg.m_time, interruptMsgProc);
4193 if (interruptMsgProc)
return false;
4195 LOCK(peer->m_getdata_requests_mutex);
4196 if (!peer->m_getdata_requests.empty()) fMoreWork =
true;
4198 }
catch (
const std::exception& e) {
4207 void PeerManagerImpl::ConsiderEviction(
CNode& pto, std::chrono::seconds time_in_seconds)
4211 CNodeState &state = *State(pto.
GetId());
4221 if (state.pindexBestKnownBlock !=
nullptr && state.pindexBestKnownBlock->nChainWork >= m_chainman.
ActiveChain().
Tip()->
nChainWork) {
4222 if (state.m_chain_sync.m_timeout != 0s) {
4223 state.m_chain_sync.m_timeout = 0s;
4224 state.m_chain_sync.m_work_header =
nullptr;
4225 state.m_chain_sync.m_sent_getheaders =
false;
4227 }
else if (state.m_chain_sync.m_timeout == 0s || (state.m_chain_sync.m_work_header !=
nullptr && state.pindexBestKnownBlock !=
nullptr && state.pindexBestKnownBlock->nChainWork >= state.m_chain_sync.m_work_header->nChainWork)) {
4233 state.m_chain_sync.m_work_header = m_chainman.
ActiveChain().
Tip();
4234 state.m_chain_sync.m_sent_getheaders =
false;
4235 }
else if (state.m_chain_sync.m_timeout > 0s && time_in_seconds > state.m_chain_sync.m_timeout) {
4239 if (state.m_chain_sync.m_sent_getheaders) {
4241 LogPrintf(
"Disconnecting outbound peer %d for old chain, best known block = %s\n", pto.
GetId(), state.pindexBestKnownBlock !=
nullptr ? state.pindexBestKnownBlock->GetBlockHash().ToString() :
"<none>");
4244 assert(state.m_chain_sync.m_work_header);
4245 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());
4247 state.m_chain_sync.m_sent_getheaders =
true;
4248 constexpr
auto HEADERS_RESPONSE_TIME{2min};
4254 state.m_chain_sync.m_timeout = time_in_seconds + HEADERS_RESPONSE_TIME;
4260 void PeerManagerImpl::EvictExtraOutboundPeers(std::chrono::seconds now)
4269 std::pair<NodeId, std::chrono::seconds> youngest_peer{-1, 0}, next_youngest_peer{-1, 0};
4273 if (pnode->
GetId() > youngest_peer.first) {
4274 next_youngest_peer = youngest_peer;
4275 youngest_peer.first = pnode->GetId();
4276 youngest_peer.second = pnode->m_last_block_time;
4279 NodeId to_disconnect = youngest_peer.first;
4280 if (youngest_peer.second > next_youngest_peer.second) {
4283 to_disconnect = next_youngest_peer.first;
4292 CNodeState *node_state = State(pnode->
GetId());
4293 if (node_state ==
nullptr ||
4296 LogPrint(
BCLog::NET,
"disconnecting extra block-relay-only peer=%d (last block received at time %d)\n",
4300 LogPrint(
BCLog::NET,
"keeping block-relay-only peer=%d chosen for eviction (connect time: %d, blocks_in_flight: %d)\n",
4314 int64_t oldest_block_announcement = std::numeric_limits<int64_t>::max();
4322 CNodeState *state = State(pnode->
GetId());
4323 if (state ==
nullptr)
return;
4325 if (state->m_chain_sync.m_protect)
return;
4326 if (state->m_last_block_announcement < oldest_block_announcement || (state->m_last_block_announcement == oldest_block_announcement && pnode->
GetId() > worst_peer)) {
4327 worst_peer = pnode->
GetId();
4328 oldest_block_announcement = state->m_last_block_announcement;
4331 if (worst_peer != -1) {
4340 CNodeState &state = *State(pnode->
GetId());
4342 LogPrint(
BCLog::NET,
"disconnecting extra outbound peer=%d (last block announcement received at time %d)\n", pnode->
GetId(), oldest_block_announcement);
4346 LogPrint(
BCLog::NET,
"keeping outbound peer=%d chosen for eviction (connect time: %d, blocks_in_flight: %d)\n",
4363 void PeerManagerImpl::CheckForStaleTipAndEvictPeers()
4367 auto now{GetTime<std::chrono::seconds>()};
4369 EvictExtraOutboundPeers(now);
4371 if (now > m_stale_tip_check_time) {
4375 LogPrintf(
"Potential stale tip detected, will try using extra outbound peer (last tip update: %d seconds ago)\n",
4384 if (!m_initial_sync_finished && CanDirectFetch()) {
4386 m_initial_sync_finished =
true;
4390 void PeerManagerImpl::MaybeSendPing(
CNode& node_to, Peer& peer, std::chrono::microseconds now)
4393 peer.m_ping_nonce_sent &&
4404 bool pingSend =
false;
4406 if (peer.m_ping_queued) {
4411 if (peer.m_ping_nonce_sent == 0 && now > peer.m_ping_start.load() +
PING_INTERVAL) {
4418 while (
nonce == 0) {
4421 peer.m_ping_queued =
false;
4422 peer.m_ping_start = now;
4424 peer.m_ping_nonce_sent =
nonce;
4428 peer.m_ping_nonce_sent = 0;
4434 void PeerManagerImpl::MaybeSendAddr(
CNode&
node, Peer& peer, std::chrono::microseconds current_time)
4437 if (!peer.m_addr_relay_enabled)
return;
4439 LOCK(peer.m_addr_send_times_mutex);
4442 peer.m_next_local_addr_send < current_time) {
4449 if (peer.m_next_local_addr_send != 0us) {
4450 peer.m_addr_known->reset();
4454 PushAddress(peer, *local_addr, insecure_rand);
4460 if (current_time <= peer.m_next_addr_send)
return;
4472 auto addr_already_known = [&peer](
const CAddress& addr) {
4473 bool ret = peer.m_addr_known->contains(addr.
GetKey());
4474 if (!ret) peer.m_addr_known->insert(addr.
GetKey());
4477 peer.m_addrs_to_send.erase(std::remove_if(peer.m_addrs_to_send.begin(), peer.m_addrs_to_send.end(), addr_already_known),
4478 peer.m_addrs_to_send.end());
4481 if (peer.m_addrs_to_send.empty())
return;
4483 const char* msg_type;
4485 if (peer.m_wants_addrv2) {
4493 peer.m_addrs_to_send.clear();
4496 if (peer.m_addrs_to_send.capacity() > 40) {
4497 peer.m_addrs_to_send.shrink_to_fit();
4501 void PeerManagerImpl::MaybeSendFeefilter(
CNode& pto, std::chrono::microseconds current_time)
4505 if (m_ignore_incoming_txs)
return;
4520 if (pto.
m_tx_relay->lastSentFeeFilter == MAX_FILTER) {
4526 if (current_time > pto.
m_tx_relay->m_next_send_feefilter) {
4527 CAmount filterToSend = g_filter_rounder.round(currentFilter);
4530 if (filterToSend != pto.
m_tx_relay->lastSentFeeFilter) {
4532 pto.
m_tx_relay->lastSentFeeFilter = filterToSend;
4538 else if (current_time + MAX_FEEFILTER_CHANGE_DELAY < pto.m_tx_relay->m_next_send_feefilter &&
4539 (currentFilter < 3 * pto.m_tx_relay->lastSentFeeFilter / 4 || currentFilter > 4 * pto.
m_tx_relay->lastSentFeeFilter / 3)) {
4545 class CompareInvMempoolOrder
4550 explicit CompareInvMempoolOrder(
CTxMemPool *_mempool,
bool use_wtxid)
4553 m_wtxid_relay = use_wtxid;
4556 bool operator()(std::set<uint256>::iterator a, std::set<uint256>::iterator b)
4565 bool PeerManagerImpl::SetupAddressRelay(
const CNode&
node, Peer& peer)
4570 if (
node.IsBlockOnlyConn())
return false;
4572 if (!peer.m_addr_relay_enabled.exchange(
true)) {
4575 peer.m_addr_known = std::make_unique<CRollingBloomFilter>(5000, 0.001);
4581 bool PeerManagerImpl::SendMessages(
CNode* pto)
4583 PeerRef peer = GetPeerRef(pto->
GetId());
4584 if (!peer)
return false;
4589 if (MaybeDiscourageAndDisconnect(*pto, *peer))
return true;
4598 const auto current_time{GetTime<std::chrono::microseconds>()};
4606 MaybeSendPing(*pto, *peer, current_time);
4611 MaybeSendAddr(*pto, *peer, current_time);
4616 CNodeState &state = *State(pto->
GetId());
4621 bool fFetch = state.fPreferredDownload || (nPreferredDownload == 0 && !pto->
fClient && !pto->
IsAddrFetchConn());
4625 state.fSyncStarted =
true;
4642 if (pindexStart->
pprev)
4643 pindexStart = pindexStart->
pprev;
4660 LOCK(peer->m_block_inv_mutex);
4661 std::vector<CBlock> vHeaders;
4662 bool fRevertToInv = ((!state.fPreferHeaders &&
4663 (!state.fPreferHeaderAndIDs || peer->m_blocks_for_headers_relay.size() > 1)) ||
4666 ProcessBlockAvailability(pto->
GetId());
4668 if (!fRevertToInv) {
4669 bool fFoundStartingHeader =
false;
4673 for (
const uint256& hash : peer->m_blocks_for_headers_relay) {
4678 fRevertToInv =
true;
4681 if (pBestIndex !=
nullptr && pindex->
pprev != pBestIndex) {
4693 fRevertToInv =
true;
4696 pBestIndex = pindex;
4697 if (fFoundStartingHeader) {
4700 }
else if (PeerHasHeader(&state, pindex)) {
4702 }
else if (pindex->
pprev ==
nullptr || PeerHasHeader(&state, pindex->
pprev)) {
4705 fFoundStartingHeader =
true;
4710 fRevertToInv =
true;
4715 if (!fRevertToInv && !vHeaders.empty()) {
4716 if (vHeaders.size() == 1 && state.fPreferHeaderAndIDs) {
4720 vHeaders.front().GetHash().ToString(), pto->
GetId());
4724 bool fGotBlockFromCache =
false;
4727 if (most_recent_block_hash == pBestIndex->
GetBlockHash()) {
4728 if (state.fWantsCmpctWitness || !fWitnessesPresentInMostRecentCompactBlock)
4734 fGotBlockFromCache =
true;
4737 if (!fGotBlockFromCache) {
4744 state.pindexBestHeaderSent = pBestIndex;
4745 }
else if (state.fPreferHeaders) {
4746 if (vHeaders.size() > 1) {
4749 vHeaders.front().GetHash().ToString(),
4750 vHeaders.back().GetHash().ToString(), pto->
GetId());
4753 vHeaders.front().GetHash().ToString(), pto->
GetId());
4756 state.pindexBestHeaderSent = pBestIndex;
4758 fRevertToInv =
true;
4764 if (!peer->m_blocks_for_headers_relay.empty()) {
4765 const uint256& hashToAnnounce = peer->m_blocks_for_headers_relay.back();
4778 if (!PeerHasHeader(&state, pindex)) {
4779 peer->m_blocks_for_inv_relay.push_back(hashToAnnounce);
4785 peer->m_blocks_for_headers_relay.clear();
4791 std::vector<CInv> vInv;
4793 LOCK(peer->m_block_inv_mutex);
4797 for (
const uint256& hash : peer->m_blocks_for_inv_relay) {
4804 peer->m_blocks_for_inv_relay.clear();
4811 if (pto->
m_tx_relay->nNextInvSend < current_time) {
4812 fSendTrickle =
true;
4827 if (fSendTrickle && pto->
m_tx_relay->fSendMempool) {
4828 auto vtxinfo = m_mempool.
infoAll();
4834 for (
const auto& txinfo : vtxinfo) {
4835 const uint256& hash = state.m_wtxid_relay ? txinfo.tx->GetWitnessHash() : txinfo.tx->GetHash();
4837 pto->
m_tx_relay->setInventoryTxToSend.erase(hash);
4839 if (txinfo.fee < filterrate.GetFee(txinfo.vsize)) {
4843 if (!pto->
m_tx_relay->pfilter->IsRelevantAndUpdate(*txinfo.tx))
continue;
4845 pto->
m_tx_relay->filterInventoryKnown.insert(hash);
4847 vInv.push_back(inv);
4853 pto->
m_tx_relay->m_last_mempool_req = std::chrono::duration_cast<std::chrono::seconds>(current_time);
4859 std::vector<std::set<uint256>::iterator> vInvTx;
4860 vInvTx.reserve(pto->
m_tx_relay->setInventoryTxToSend.size());
4861 for (std::set<uint256>::iterator it = pto->
m_tx_relay->setInventoryTxToSend.begin(); it != pto->
m_tx_relay->setInventoryTxToSend.end(); it++) {
4862 vInvTx.push_back(it);
4867 CompareInvMempoolOrder compareInvMempoolOrder(&m_mempool, state.m_wtxid_relay);
4868 std::make_heap(vInvTx.begin(), vInvTx.end(), compareInvMempoolOrder);
4871 unsigned int nRelayedTransactions = 0;
4875 std::pop_heap(vInvTx.begin(), vInvTx.end(), compareInvMempoolOrder);
4876 std::set<uint256>::iterator it = vInvTx.back();
4881 pto->
m_tx_relay->setInventoryTxToSend.erase(it);
4883 if (pto->
m_tx_relay->filterInventoryKnown.contains(hash)) {
4891 auto txid = txinfo.tx->GetHash();
4892 auto wtxid = txinfo.tx->GetWitnessHash();
4894 if (txinfo.fee < filterrate.GetFee(txinfo.vsize)) {
4897 if (pto->
m_tx_relay->pfilter && !pto->
m_tx_relay->pfilter->IsRelevantAndUpdate(*txinfo.tx))
continue;
4899 State(pto->
GetId())->m_recently_announced_invs.insert(hash);
4900 vInv.push_back(inv);
4901 nRelayedTransactions++;
4904 while (!g_relay_expiration.empty() && g_relay_expiration.front().first < current_time)
4906 mapRelay.erase(g_relay_expiration.front().second);
4907 g_relay_expiration.pop_front();
4910 auto ret = mapRelay.emplace(txid, std::move(txinfo.tx));
4915 auto ret2 = mapRelay.emplace(wtxid, ret.first->second);
4924 pto->
m_tx_relay->filterInventoryKnown.insert(hash);
4931 pto->
m_tx_relay->filterInventoryKnown.insert(txid);
4944 LogPrintf(
"Peer=%d is stalling block download, disconnecting\n", pto->
GetId());
4953 if (state.vBlocksInFlight.size() > 0) {
4954 QueuedBlock &queuedBlock = state.vBlocksInFlight.front();
4955 int nOtherPeersWithValidatedDownloads = m_peers_downloading_from - 1;
4957 LogPrintf(
"Timeout downloading block %s from peer=%d, disconnecting\n", queuedBlock.pindex->GetBlockHash().ToString(), pto->
GetId());
4963 if (state.fSyncStarted && state.m_headers_sync_timeout < std::chrono::microseconds::max()) {
4966 if (current_time > state.m_headers_sync_timeout && nSyncStarted == 1 && (nPreferredDownload - state.fPreferredDownload >= 1)) {
4973 LogPrintf(
"Timeout downloading headers from peer=%d, disconnecting\n", pto->
GetId());
4977 LogPrintf(
"Timeout downloading headers from noban peer=%d, not disconnecting\n", pto->
GetId());
4983 state.fSyncStarted =
false;
4985 state.m_headers_sync_timeout = 0us;
4991 state.m_headers_sync_timeout = std::chrono::microseconds::max();
4997 ConsiderEviction(*pto, GetTime<std::chrono::seconds>());
5002 std::vector<CInv> vGetData;
5004 std::vector<const CBlockIndex*> vToDownload;
5010 BlockRequested(pto->
GetId(), *pindex);
5014 if (state.nBlocksInFlight == 0 && staller != -1) {
5015 if (State(staller)->m_stalling_since == 0us) {
5016 State(staller)->m_stalling_since = current_time;
5025 std::vector<std::pair<NodeId, GenTxid>> expired;
5026 auto requestable = m_txrequest.GetRequestable(pto->
GetId(), current_time, &expired);
5027 for (
const auto& entry : expired) {
5028 LogPrint(
BCLog::NET,
"timeout of inflight %s %s from peer=%d\n", entry.second.IsWtxid() ?
"wtx" :
"tx",
5029 entry.second.GetHash().ToString(), entry.first);
5031 for (
const GenTxid& gtxid : requestable) {
5032 if (!AlreadyHaveTx(gtxid)) {
5044 m_txrequest.ForgetTxHash(gtxid.
GetHash());
5049 if (!vGetData.empty())
5052 MaybeSendFeefilter(*pto, current_time);