224 Mutex g_cs_recent_confirmed_transactions;
225 std::unique_ptr<CRollingBloomFilter> g_recent_confirmed_transactions
GUARDED_BY(g_cs_recent_confirmed_transactions);
231 bool fValidatedHeaders;
232 std::unique_ptr<PartiallyDownloadedBlock> partialBlock;
234 std::map<uint256, std::pair<NodeId, std::list<QueuedBlock>::iterator> > mapBlocksInFlight
GUARDED_BY(
cs_main);
252 std::atomic<int64_t> g_last_tip_update(0);
255 typedef std::map<uint256, CTransactionRef> MapRelay;
258 std::deque<std::pair<int64_t, MapRelay::iterator>> vRelayExpiration
GUARDED_BY(
cs_main);
260 struct IteratorComparator
263 bool operator()(
const I& a,
const I& b)
const
265 return &(*a) < &(*b);
271 std::map<COutPoint, std::set<std::map<uint256, COrphanTx>::iterator, IteratorComparator>> mapOrphanTransactionsByPrev
GUARDED_BY(
g_cs_orphans);
294 bool fCurrentlyConnected;
304 int nUnconnectingHeaders;
308 int64_t nHeadersSyncTimeout;
310 int64_t nStallingSince;
311 std::list<QueuedBlock> vBlocksInFlight;
313 int64_t nDownloadingSince;
315 int nBlocksInFlightValidHeaders;
317 bool fPreferredDownload;
321 bool fPreferHeaderAndIDs;
327 bool fProvidesHeaderAndIDs;
331 bool fWantsCmpctWitness;
336 bool fSupportsDesiredCmpctVersion;
362 struct ChainSyncTimeoutState {
368 bool m_sent_getheaders;
373 ChainSyncTimeoutState m_chain_sync;
376 int64_t m_last_block_announcement;
382 bool m_is_manual_connection;
388 bool m_wtxid_relay{
false};
390 CNodeState(
CAddress addrIn,
bool is_inbound,
bool is_manual)
391 : address(addrIn), m_is_inbound(is_inbound), m_is_manual_connection(is_manual)
393 fCurrentlyConnected =
false;
394 pindexBestKnownBlock =
nullptr;
395 hashLastUnknownBlock.
SetNull();
396 pindexLastCommonBlock =
nullptr;
397 pindexBestHeaderSent =
nullptr;
398 nUnconnectingHeaders = 0;
399 fSyncStarted =
false;
400 nHeadersSyncTimeout = 0;
402 nDownloadingSince = 0;
404 nBlocksInFlightValidHeaders = 0;
405 fPreferredDownload =
false;
406 fPreferHeaders =
false;
407 fPreferHeaderAndIDs =
false;
408 fProvidesHeaderAndIDs =
false;
409 fHaveWitness =
false;
410 fWantsCmpctWitness =
false;
411 fSupportsDesiredCmpctVersion =
false;
412 m_chain_sync = { 0,
nullptr,
false,
false };
413 m_last_block_announcement = 0;
414 m_recently_announced_invs.
reset();
422 std::map<NodeId, CNodeState>::iterator
it = mapNodeState.find(pnode);
423 if (
it == mapNodeState.end())
443 Mutex m_misbehavior_mutex;
445 int m_misbehavior_score
GUARDED_BY(m_misbehavior_mutex){0};
447 bool m_should_discourage
GUARDED_BY(m_misbehavior_mutex){
false};
457 Peer(
NodeId id) : m_id(id) {}
460 using PeerRef = std::shared_ptr<Peer>;
469 static std::map<NodeId, PeerRef> g_peer_map
GUARDED_BY(g_peer_mutex);
473 static PeerRef GetPeerRef(
NodeId id)
476 auto it = g_peer_map.find(
id);
477 return it != g_peer_map.end() ?
it->second :
nullptr;
482 nPreferredDownload -= state->fPreferredDownload;
485 state->fPreferredDownload = (!node.IsInboundConn() || node.HasPermission(
PF_NOBAN)) && !node.IsAddrFetchConn() && !node.fClient;
487 nPreferredDownload += state->fPreferredDownload;
490 static void PushNodeVersion(
CNode& pnode,
CConnman& connman, int64_t nTime)
510 LogPrint(
BCLog::NET,
"send version message: version %d, blocks=%d, us=%s, them=%s, peer=%d\n",
PROTOCOL_VERSION, nNodeStartingHeight, addrMe.
ToString(), addrYou.
ToString(), nodeid);
519 std::map<uint256, std::pair<NodeId, std::list<QueuedBlock>::iterator> >::iterator itInFlight = mapBlocksInFlight.find(hash);
520 if (itInFlight != mapBlocksInFlight.end()) {
521 CNodeState *state = State(itInFlight->second.first);
522 assert(state !=
nullptr);
523 state->nBlocksInFlightValidHeaders -= itInFlight->second.second->fValidatedHeaders;
524 if (state->nBlocksInFlightValidHeaders == 0 && itInFlight->second.second->fValidatedHeaders) {
526 nPeersWithValidatedDownloads--;
528 if (state->vBlocksInFlight.begin() == itInFlight->second.second) {
530 state->nDownloadingSince = std::max(state->nDownloadingSince,
count_microseconds(GetTime<std::chrono::microseconds>()));
532 state->vBlocksInFlight.erase(itInFlight->second.second);
533 state->nBlocksInFlight--;
534 state->nStallingSince = 0;
535 mapBlocksInFlight.erase(itInFlight);
544 CNodeState *state = State(nodeid);
545 assert(state !=
nullptr);
548 std::map<uint256, std::pair<NodeId, std::list<QueuedBlock>::iterator> >::iterator itInFlight = mapBlocksInFlight.find(hash);
549 if (itInFlight != mapBlocksInFlight.end() && itInFlight->second.first == nodeid) {
551 *pit = &itInFlight->second.second;
557 MarkBlockAsReceived(hash);
559 std::list<QueuedBlock>::iterator
it = state->vBlocksInFlight.insert(state->vBlocksInFlight.end(),
560 {hash, pindex, pindex != nullptr, std::unique_ptr<PartiallyDownloadedBlock>(pit ? new PartiallyDownloadedBlock(&mempool) : nullptr)});
561 state->nBlocksInFlight++;
562 state->nBlocksInFlightValidHeaders +=
it->fValidatedHeaders;
563 if (state->nBlocksInFlight == 1) {
565 state->nDownloadingSince = GetTime<std::chrono::microseconds>().count();
567 if (state->nBlocksInFlightValidHeaders == 1 && pindex !=
nullptr) {
568 nPeersWithValidatedDownloads++;
570 itInFlight = mapBlocksInFlight.insert(std::make_pair(hash, std::make_pair(nodeid,
it))).first;
572 *pit = &itInFlight->second.second;
578 CNodeState *state = State(nodeid);
579 assert(state !=
nullptr);
581 if (!state->hashLastUnknownBlock.IsNull()) {
584 if (state->pindexBestKnownBlock ==
nullptr || pindex->
nChainWork >= state->pindexBestKnownBlock->nChainWork) {
585 state->pindexBestKnownBlock = pindex;
587 state->hashLastUnknownBlock.SetNull();
594 CNodeState *state = State(nodeid);
595 assert(state !=
nullptr);
597 ProcessBlockAvailability(nodeid);
602 if (state->pindexBestKnownBlock ==
nullptr || pindex->
nChainWork >= state->pindexBestKnownBlock->nChainWork) {
603 state->pindexBestKnownBlock = pindex;
607 state->hashLastUnknownBlock = hash;
620 CNodeState* nodestate = State(nodeid);
621 if (!nodestate || !nodestate->fSupportsDesiredCmpctVersion) {
625 if (nodestate->fProvidesHeaderAndIDs) {
626 for (std::list<NodeId>::iterator
it = lNodesAnnouncingHeaderAndIDs.begin();
it != lNodesAnnouncingHeaderAndIDs.end();
it++) {
628 lNodesAnnouncingHeaderAndIDs.erase(
it);
629 lNodesAnnouncingHeaderAndIDs.push_back(nodeid);
636 if (lNodesAnnouncingHeaderAndIDs.size() >= 3) {
639 connman.
ForNode(lNodesAnnouncingHeaderAndIDs.front(), [&connman, nCMPCTBLOCKVersion](
CNode* pnodeStop){
643 lNodesAnnouncingHeaderAndIDs.pop_front();
646 lNodesAnnouncingHeaderAndIDs.push_back(pfrom->
GetId());
655 if (g_last_tip_update == 0) {
658 return g_last_tip_update <
GetTime() - consensusParams.nPowTargetSpacing * 3 && mapBlocksInFlight.empty();
668 if (state->pindexBestKnownBlock && pindex == state->pindexBestKnownBlock->GetAncestor(pindex->
nHeight))
670 if (state->pindexBestHeaderSent && pindex == state->pindexBestHeaderSent->GetAncestor(pindex->
nHeight))
682 vBlocks.reserve(vBlocks.size() +
count);
683 CNodeState *state = State(nodeid);
684 assert(state !=
nullptr);
687 ProcessBlockAvailability(nodeid);
689 if (state->pindexBestKnownBlock ==
nullptr || state->pindexBestKnownBlock->nChainWork < ::
ChainActive().Tip()->nChainWork || state->pindexBestKnownBlock->nChainWork <
nMinimumChainWork) {
694 if (state->pindexLastCommonBlock ==
nullptr) {
697 state->pindexLastCommonBlock =
::ChainActive()[std::min(state->pindexBestKnownBlock->nHeight, ::
ChainActive().Height())];
702 state->pindexLastCommonBlock =
LastCommonAncestor(state->pindexLastCommonBlock, state->pindexBestKnownBlock);
703 if (state->pindexLastCommonBlock == state->pindexBestKnownBlock)
706 std::vector<const CBlockIndex*> vToFetch;
707 const CBlockIndex *pindexWalk = state->pindexLastCommonBlock;
712 int nMaxHeight = std::min<int>(state->pindexBestKnownBlock->nHeight, nWindowEnd + 1);
714 while (pindexWalk->
nHeight < nMaxHeight) {
718 int nToFetch = std::min(nMaxHeight - pindexWalk->
nHeight, std::max<int>(
count - vBlocks.size(), 128));
719 vToFetch.resize(nToFetch);
720 pindexWalk = state->pindexBestKnownBlock->
GetAncestor(pindexWalk->
nHeight + nToFetch);
721 vToFetch[nToFetch - 1] = pindexWalk;
722 for (
unsigned int i = nToFetch - 1; i > 0; i--) {
723 vToFetch[i - 1] = vToFetch[i]->
pprev;
741 state->pindexLastCommonBlock = pindex;
742 }
else if (mapBlocksInFlight.count(pindex->
GetBlockHash()) == 0) {
744 if (pindex->
nHeight > nWindowEnd) {
746 if (vBlocks.size() == 0 && waitingfor != nodeid) {
748 nodeStaller = waitingfor;
752 vBlocks.push_back(pindex);
753 if (vBlocks.size() ==
count) {
756 }
else if (waitingfor == -1) {
758 waitingfor = mapBlocksInFlight[pindex->
GetBlockHash()].first;
766 void PeerManager::AddTxAnnouncement(
const CNode& node,
const GenTxid& gtxid, std::chrono::microseconds current_time)
774 const CNodeState* state = State(nodeid);
783 auto delay = std::chrono::microseconds{0};
784 const bool preferred = state->fPreferredDownload;
790 m_txrequest.ReceivedInv(nodeid, gtxid, preferred, current_time + delay);
798 CNodeState *state = State(node);
799 if (state) state->m_last_block_announcement = time_in_seconds;
808 mapNodeState.emplace_hint(mapNodeState.end(), std::piecewise_construct, std::forward_as_tuple(nodeid), std::forward_as_tuple(addr, pnode->
IsInboundConn(), pnode->
IsManualConn()));
809 assert(m_txrequest.Count(nodeid) == 0);
812 PeerRef peer = std::make_shared<Peer>(nodeid);
814 g_peer_map.emplace_hint(g_peer_map.end(), nodeid, std::move(peer));
825 for (
const auto& txid : unbroadcast_txids) {
838 const std::chrono::milliseconds delta = std::chrono::minutes{10} +
GetRandMillis(std::chrono::minutes{5});
844 fUpdateConnectionTime =
false;
848 PeerRef peer = GetPeerRef(nodeid);
849 assert(peer !=
nullptr);
850 misbehavior =
WITH_LOCK(peer->m_misbehavior_mutex,
return peer->m_misbehavior_score);
852 g_peer_map.erase(nodeid);
854 CNodeState *state = State(nodeid);
855 assert(state !=
nullptr);
857 if (state->fSyncStarted)
860 if (misbehavior == 0 && state->fCurrentlyConnected && !node.
IsBlockOnlyConn()) {
862 fUpdateConnectionTime =
true;
865 for (
const QueuedBlock& entry : state->vBlocksInFlight) {
866 mapBlocksInFlight.erase(entry.hash);
869 m_txrequest.DisconnectedPeer(nodeid);
870 nPreferredDownload -= state->fPreferredDownload;
871 nPeersWithValidatedDownloads -= (state->nBlocksInFlightValidHeaders != 0);
872 assert(nPeersWithValidatedDownloads >= 0);
873 g_outbound_peers_with_protect_from_disconnect -= state->m_chain_sync.m_protect;
874 assert(g_outbound_peers_with_protect_from_disconnect >= 0);
875 g_wtxid_relay_peers -= state->m_wtxid_relay;
876 assert(g_wtxid_relay_peers >= 0);
878 mapNodeState.erase(nodeid);
880 if (mapNodeState.empty()) {
882 assert(mapBlocksInFlight.empty());
883 assert(nPreferredDownload == 0);
884 assert(nPeersWithValidatedDownloads == 0);
885 assert(g_outbound_peers_with_protect_from_disconnect == 0);
886 assert(g_wtxid_relay_peers == 0);
887 assert(m_txrequest.Size() == 0);
895 CNodeState* state = State(nodeid);
896 if (state ==
nullptr)
898 stats.
nSyncHeight = state->pindexBestKnownBlock ? state->pindexBestKnownBlock->nHeight : -1;
899 stats.
nCommonHeight = state->pindexLastCommonBlock ? state->pindexLastCommonBlock->nHeight : -1;
900 for (
const QueuedBlock& queue : state->vBlocksInFlight) {
906 PeerRef peer = GetPeerRef(nodeid);
907 if (peer ==
nullptr)
return false;
921 if (max_extra_txn <= 0)
923 if (!vExtraTxnForCompact.size())
924 vExtraTxnForCompact.resize(max_extra_txn);
925 vExtraTxnForCompact[vExtraTxnForCompactIt] = std::make_pair(tx->GetWitnessHash(), tx);
926 vExtraTxnForCompactIt = (vExtraTxnForCompactIt + 1) % max_extra_txn;
931 const uint256& hash = tx->GetHash();
932 if (mapOrphanTransactions.count(hash))
951 g_orphan_list.push_back(ret.first);
953 g_orphans_by_wtxid.emplace(tx->GetWitnessHash(), ret.first);
954 for (
const CTxIn& txin : tx->vin) {
955 mapOrphanTransactionsByPrev[txin.
prevout].insert(ret.first);
961 mapOrphanTransactions.size(), mapOrphanTransactionsByPrev.size());
967 std::map<uint256, COrphanTx>::iterator
it = mapOrphanTransactions.find(hash);
968 if (
it == mapOrphanTransactions.end())
970 for (
const CTxIn& txin :
it->second.tx->vin)
972 auto itPrev = mapOrphanTransactionsByPrev.find(txin.
prevout);
973 if (itPrev == mapOrphanTransactionsByPrev.end())
975 itPrev->second.erase(
it);
976 if (itPrev->second.empty())
977 mapOrphanTransactionsByPrev.erase(itPrev);
980 size_t old_pos =
it->second.list_pos;
981 assert(g_orphan_list[old_pos] ==
it);
982 if (old_pos + 1 != g_orphan_list.size()) {
985 auto it_last = g_orphan_list.back();
986 g_orphan_list[old_pos] = it_last;
987 it_last->second.list_pos = old_pos;
989 g_orphan_list.pop_back();
990 g_orphans_by_wtxid.erase(
it->second.tx->GetWitnessHash());
992 mapOrphanTransactions.erase(
it);
1000 std::map<uint256, COrphanTx>::iterator iter = mapOrphanTransactions.begin();
1001 while (iter != mapOrphanTransactions.end())
1003 std::map<uint256, COrphanTx>::iterator maybeErase = iter++;
1004 if (maybeErase->second.fromPeer == peer)
1017 unsigned int nEvicted = 0;
1018 static int64_t nNextSweep;
1020 if (nNextSweep <= nNow) {
1024 std::map<uint256, COrphanTx>::iterator iter = mapOrphanTransactions.begin();
1025 while (iter != mapOrphanTransactions.end())
1027 std::map<uint256, COrphanTx>::iterator maybeErase = iter++;
1028 if (maybeErase->second.nTimeExpire <= nNow) {
1031 nMinExpTime = std::min(maybeErase->second.nTimeExpire, nMinExpTime);
1039 while (mapOrphanTransactions.size() > nMaxOrphans)
1042 size_t randompos = rng.
randrange(g_orphan_list.size());
1051 assert(howmuch > 0);
1053 PeerRef peer = GetPeerRef(pnode);
1054 if (peer ==
nullptr)
return;
1056 LOCK(peer->m_misbehavior_mutex);
1057 peer->m_misbehavior_score += howmuch;
1058 const std::string message_prefixed = message.empty() ?
"" : (
": " + message);
1060 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);
1061 peer->m_should_discourage =
true;
1063 LogPrint(
BCLog::NET,
"Misbehaving: peer=%d (%d -> %d)%s\n", pnode, peer->m_misbehavior_score - howmuch, peer->m_misbehavior_score, message_prefixed);
1068 bool via_compact_block,
const std::string& message)
1076 if (!via_compact_block) {
1084 CNodeState *node_state = State(nodeid);
1085 if (node_state ==
nullptr) {
1091 if (!via_compact_block && !node_state->m_is_inbound && !node_state->m_is_manual_connection) {
1111 if (message !=
"") {
1138 if (message !=
"") {
1157 if (::
ChainActive().Contains(pindex))
return true;
1165 : m_chainparams(chainparams),
1168 m_chainman(chainman),
1170 m_stale_tip_check_time(0)
1194 const std::chrono::milliseconds delta = std::chrono::minutes{10} +
GetRandMillis(std::chrono::minutes{5});
1208 std::vector<uint256> vOrphanErase;
1214 for (
const auto& txin : tx.
vin) {
1215 auto itByPrev = mapOrphanTransactionsByPrev.find(txin.prevout);
1216 if (itByPrev == mapOrphanTransactionsByPrev.end())
continue;
1217 for (
auto mi = itByPrev->second.begin(); mi != itByPrev->second.end(); ++mi) {
1220 vOrphanErase.push_back(orphanHash);
1226 if (vOrphanErase.size()) {
1228 for (
const uint256& orphanHash : vOrphanErase) {
1234 g_last_tip_update =
GetTime();
1237 LOCK(g_cs_recent_confirmed_transactions);
1238 for (
const auto& ptx : pblock->vtx) {
1239 g_recent_confirmed_transactions->insert(ptx->GetHash());
1240 if (ptx->GetHash() != ptx->GetWitnessHash()) {
1241 g_recent_confirmed_transactions->insert(ptx->GetWitnessHash());
1247 for (
const auto& ptx : pblock->vtx) {
1248 m_txrequest.ForgetTxHash(ptx->GetHash());
1249 m_txrequest.ForgetTxHash(ptx->GetWitnessHash());
1264 LOCK(g_cs_recent_confirmed_transactions);
1265 g_recent_confirmed_transactions->reset();
1280 std::shared_ptr<const CBlockHeaderAndShortTxIDs> pcmpctblock = std::make_shared<const CBlockHeaderAndShortTxIDs> (*pblock,
true);
1285 static int nHighestFastAnnounce = 0;
1286 if (pindex->
nHeight <= nHighestFastAnnounce)
1288 nHighestFastAnnounce = pindex->
nHeight;
1291 uint256 hashBlock(pblock->GetHash());
1295 most_recent_block_hash = hashBlock;
1296 most_recent_block = pblock;
1297 most_recent_compact_block = pcmpctblock;
1298 fWitnessesPresentInMostRecentCompactBlock = fWitnessEnabled;
1307 ProcessBlockAvailability(pnode->
GetId());
1308 CNodeState &state = *State(pnode->
GetId());
1311 if (state.fPreferHeaderAndIDs && (!fWitnessEnabled || state.fWantsCmpctWitness) &&
1312 !PeerHasHeader(&state, pindex) && PeerHasHeader(&state, pindex->
pprev)) {
1314 LogPrint(
BCLog::NET,
"%s sending header-and-ids %s to peer=%d\n",
"PeerManager::NewPoWValidBlock",
1317 state.pindexBestHeaderSent = pindex;
1327 const int nNewHeight = pindexNew->
nHeight;
1331 if (!fInitialDownload) {
1333 std::vector<uint256> vHashes;
1335 while (pindexToAnnounce != pindexFork) {
1337 pindexToAnnounce = pindexToAnnounce->
pprev;
1349 pnode->vBlockHashesToAnnounce.push_back(hash);
1365 std::map<uint256, std::pair<NodeId, bool>>::iterator
it = mapBlockSource.find(hash);
1370 it != mapBlockSource.end() &&
1371 State(
it->second.first)) {
1382 mapBlocksInFlight.count(hash) == mapBlocksInFlight.size()) {
1383 if (
it != mapBlockSource.end()) {
1384 MaybeSetPeerAsAnnouncingHeaderAndIDs(
it->second.first,
m_connman);
1387 if (
it != mapBlockSource.end())
1388 mapBlockSource.erase(
it);
1399 assert(recentRejects);
1400 if (::
ChainActive().Tip()->GetBlockHash() != hashRecentRejectsChainTip) {
1406 recentRejects->reset();
1413 if (!gtxid.
IsWtxid() && mapOrphanTransactions.count(hash)) {
1415 }
else if (gtxid.
IsWtxid() && g_orphans_by_wtxid.count(hash)) {
1421 LOCK(g_cs_recent_confirmed_transactions);
1422 if (g_recent_confirmed_transactions->contains(hash))
return true;
1425 return recentRejects->contains(hash) || mempool.
exists(gtxid);
1438 CNodeState* state = State(pnode->
GetId());
1439 if (state ==
nullptr)
return;
1440 if (state->m_wtxid_relay) {
1455 uint64_t hashAddr = addr.
GetHash();
1460 unsigned int nRelayNodes = (fReachable || (hasher.
Finalize() & 1)) ? 2 : 1;
1462 std::array<std::pair<uint64_t, CNode*>,2> best{{{0,
nullptr}, {0,
nullptr}}};
1463 assert(nRelayNodes <= best.size());
1465 auto sortfunc = [&best, &hasher, nRelayNodes](
CNode* pnode) {
1468 for (
unsigned int i = 0; i < nRelayNodes; i++) {
1469 if (hashKey > best[i].first) {
1470 std::copy(best.begin() + i, best.begin() + nRelayNodes - 1, best.begin() + i + 1);
1471 best[i] = std::make_pair(hashKey, pnode);
1478 auto pushfunc = [&addr, &best, nRelayNodes, &insecure_rand] {
1479 for (
unsigned int i = 0; i < nRelayNodes && best[i].first != 0; i++) {
1480 best[i].second->PushAddress(addr, insecure_rand);
1490 std::shared_ptr<const CBlock> a_recent_block;
1491 std::shared_ptr<const CBlockHeaderAndShortTxIDs> a_recent_compact_block;
1492 bool fWitnessesPresentInARecentCompactBlock;
1496 a_recent_block = most_recent_block;
1497 a_recent_compact_block = most_recent_compact_block;
1498 fWitnessesPresentInARecentCompactBlock = fWitnessesPresentInMostRecentCompactBlock;
1501 bool need_activate_chain =
false;
1513 need_activate_chain =
true;
1517 if (need_activate_chain) {
1529 LogPrint(
BCLog::NET,
"%s: ignoring request from peer=%i for old block that isn't in the main chain\n", __func__, pfrom.
GetId());
1549 LogPrint(
BCLog::NET,
"Ignore block request below NODE_NETWORK_LIMITED threshold from peer=%d\n", pfrom.
GetId());
1559 std::shared_ptr<const CBlock> pblock;
1560 if (a_recent_block && a_recent_block->GetHash() == pindex->
GetBlockHash()) {
1561 pblock = a_recent_block;
1565 std::vector<uint8_t> block_data;
1567 assert(!
"cannot load block from disk");
1573 std::shared_ptr<CBlock> pblockRead = std::make_shared<CBlock>();
1575 assert(!
"cannot load block from disk");
1576 pblock = pblockRead;
1584 bool sendMerkleBlock =
false;
1589 sendMerkleBlock =
true;
1593 if (sendMerkleBlock) {
1601 typedef std::pair<unsigned int, uint256> PairType;
1612 bool fPeerWantsWitness = State(pfrom.
GetId())->fWantsCmpctWitness;
1615 if ((fPeerWantsWitness || !fWitnessesPresentInARecentCompactBlock) && a_recent_compact_block && a_recent_compact_block->header.GetHash() == pindex->
GetBlockHash()) {
1633 std::vector<CInv> vInv;
1644 auto txinfo = mempool.
info(gtxid);
1650 return std::move(txinfo.tx);
1657 if (State(peer.GetId())->m_recently_announced_invs.contains(gtxid.
GetHash())) {
1659 if (txinfo.tx)
return std::move(txinfo.tx);
1661 auto mi = mapRelay.find(gtxid.
GetHash());
1662 if (mi != mapRelay.end())
return mi->second;
1673 std::deque<CInv>::iterator
it = peer.m_getdata_requests.begin();
1677 const std::chrono::seconds
now = GetTime<std::chrono::seconds>();
1680 : std::chrono::seconds::min();
1685 while (
it != peer.m_getdata_requests.end() &&
it->IsGenTxMsg()) {
1686 if (interruptMsgProc)
return;
1705 std::vector<uint256> parent_ids_to_add;
1708 auto txiter = mempool.
GetIter(tx->GetHash());
1711 parent_ids_to_add.reserve(parents.size());
1714 parent_ids_to_add.push_back(parent.GetTx().GetHash());
1719 for (
const uint256& parent_txid : parent_ids_to_add) {
1723 State(pfrom.
GetId())->m_recently_announced_invs.insert(parent_txid);
1742 peer.m_getdata_requests.erase(peer.m_getdata_requests.begin(),
it);
1764 uint32_t nFetchFlags = 0;
1773 for (
size_t i = 0; i < req.
indexes.size(); i++) {
1775 Misbehaving(pfrom.
GetId(), 100,
"getblocktxn with out-of-bounds tx indices");
1789 size_t nCount = headers.size();
1796 bool received_new_header =
false;
1800 CNodeState *nodestate = State(pfrom.
GetId());
1811 nodestate->nUnconnectingHeaders++;
1813 LogPrint(
BCLog::NET,
"received header %s: missing prev block %s, sending getheaders (%d) to end (peer=%d, nUnconnectingHeaders=%d)\n",
1815 headers[0].hashPrevBlock.ToString(),
1817 pfrom.
GetId(), nodestate->nUnconnectingHeaders);
1821 UpdateBlockAvailability(pfrom.
GetId(), headers.back().GetHash());
1831 if (!hashLastBlock.
IsNull() && header.hashPrevBlock != hashLastBlock) {
1835 hashLastBlock = header.GetHash();
1841 received_new_header =
true;
1855 CNodeState *nodestate = State(pfrom.
GetId());
1856 if (nodestate->nUnconnectingHeaders > 0) {
1857 LogPrint(
BCLog::NET,
"peer=%d: resetting nUnconnectingHeaders (%d -> 0)\n", pfrom.
GetId(), nodestate->nUnconnectingHeaders);
1859 nodestate->nUnconnectingHeaders = 0;
1869 nodestate->m_last_block_announcement =
GetTime();
1880 bool fCanDirectFetch = CanDirectFetch(
m_chainparams.GetConsensus());
1884 std::vector<const CBlockIndex*> vToFetch;
1889 !mapBlocksInFlight.count(pindexWalk->
GetBlockHash()) &&
1892 vToFetch.push_back(pindexWalk);
1894 pindexWalk = pindexWalk->
pprev;
1905 std::vector<CInv> vGetData;
1918 if (vGetData.size() > 1) {
1922 if (vGetData.size() > 0) {
1923 if (nodestate->fSupportsDesiredCmpctVersion && vGetData.size() == 1 && mapBlocksInFlight.size() == 1 && pindexLast->
pprev->
IsValid(
BLOCK_VALID_CHAIN)) {
1936 if (nodestate->pindexBestKnownBlock && nodestate->pindexBestKnownBlock->nChainWork <
nMinimumChainWork) {
1946 LogPrintf(
"Disconnecting outbound peer %d -- headers chain has insufficient work\n", pfrom.
GetId());
1958 if (g_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) {
1960 nodestate->m_chain_sync.m_protect =
true;
1961 ++g_outbound_peers_with_protect_from_disconnect;
1982 while (!orphan_work_set.empty()) {
1984 orphan_work_set.erase(orphan_work_set.begin());
1986 auto orphan_it = mapOrphanTransactions.find(orphanHash);
1987 if (orphan_it == mapOrphanTransactions.end())
continue;
1991 std::list<CTransactionRef> removed_txn;
1996 for (
unsigned int i = 0; i < porphanTx->vout.size(); i++) {
1997 auto it_by_prev = mapOrphanTransactionsByPrev.find(
COutPoint(orphanHash, i));
1998 if (it_by_prev != mapOrphanTransactionsByPrev.end()) {
1999 for (
const auto& elem : it_by_prev->second) {
2000 orphan_work_set.insert(elem->first);
2013 orphan_it->second.fromPeer,
2035 assert(recentRejects);
2036 recentRejects->insert(porphanTx->GetWitnessHash());
2048 recentRejects->insert(porphanTx->GetHash());
2075 const uint256& stop_hash, uint32_t max_height_diff,
2079 const bool supported_filter_type =
2082 if (!supported_filter_type) {
2084 peer.
GetId(),
static_cast<uint8_t
>(filter_type));
2102 uint32_t stop_height = stop_index->
nHeight;
2103 if (start_height > stop_height) {
2105 "start height %d and stop height %d\n",
2106 peer.
GetId(), start_height, stop_height);
2110 if (stop_height - start_height >= max_height_diff) {
2112 peer.
GetId(), stop_height - start_height + 1, max_height_diff);
2118 if (!filter_index) {
2139 uint8_t filter_type_ser;
2140 uint32_t start_height;
2143 vRecv >> filter_type_ser >> start_height >> stop_hash;
2154 std::vector<BlockFilter> filters;
2156 LogPrint(
BCLog::NET,
"Failed to find block filter in index: filter_type=%s, start_height=%d, stop_hash=%s\n",
2161 for (
const auto& filter : filters) {
2181 uint8_t filter_type_ser;
2182 uint32_t start_height;
2185 vRecv >> filter_type_ser >> start_height >> stop_hash;
2197 if (start_height > 0) {
2199 stop_index->
GetAncestor(
static_cast<int>(start_height - 1));
2201 LogPrint(
BCLog::NET,
"Failed to find block filter header in index: filter_type=%s, block_hash=%s\n",
2207 std::vector<uint256> filter_hashes;
2209 LogPrint(
BCLog::NET,
"Failed to find block filter hashes in index: filter_type=%s, start_height=%d, stop_hash=%s\n",
2236 uint8_t filter_type_ser;
2239 vRecv >> filter_type_ser >> stop_hash;
2246 std::numeric_limits<uint32_t>::max(),
2247 stop_index, filter_index)) {
2255 for (
int i = headers.size() - 1; i >= 0; i--) {
2260 LogPrint(
BCLog::NET,
"Failed to find block filter header in index: filter_type=%s, block_hash=%s\n",
2275 const std::chrono::microseconds time_received,
2276 const std::atomic<bool>& interruptMsgProc)
2281 LogPrintf(
"dropmessagestest DROPPING RECV MESSAGE\n");
2285 PeerRef peer = GetPeerRef(pfrom.
GetId());
2286 if (peer ==
nullptr)
return;
2299 uint64_t nNonce = 1;
2300 uint64_t nServiceInt;
2303 std::string cleanSubVer;
2304 int nStartingHeight = -1;
2307 vRecv >> nVersion >> nServiceInt >> nTime >> addrMe;
2328 vRecv >> addrFrom >> nNonce;
2329 if (!vRecv.
empty()) {
2330 std::string strSubVer;
2334 if (!vRecv.
empty()) {
2335 vRecv >> nStartingHeight;
2368 if (greatest_common_version >= 70016) {
2382 pfrom.cleanSubVer = cleanSubVer;
2400 State(pfrom.
GetId())->fHaveWitness =
true;
2406 UpdatePreferredDownload(pfrom, State(pfrom.
GetId()));
2458 std::string remoteAddr;
2462 LogPrint(
BCLog::NET,
"receive version message: %s: version %d, blocks=%d, us=%s, peer=%d%s\n",
2467 int64_t nTimeOffset = nTime -
GetTime();
2472 if (greatest_common_version <= 70012) {
2473 CDataStream finalAlert(
ParseHex(
"60010000000000000000000000ffffff7f00000000ffffff7ffeffff7f01ffffff7f00000000ffffff7f00ffffff7f002f555247454e543a20416c657274206b657920636f6d70726f6d697365642c2075706772616465207265717569726564004630440220653febd6410f470f6bae11cad19c48413becb1ac2c17f908fd0fd53bdc3abd5202206d0e9c96fe88d4a0f01ed9dedae2b6f9e00da94cad0fecaae66ecf689bf71b50"),
SER_NETWORK,
PROTOCOL_VERSION);
2486 Misbehaving(pfrom.
GetId(), 1,
"non-version message before version handshake");
2499 State(pfrom.
GetId())->fCurrentlyConnected =
true;
2500 LogPrintf(
"New outbound peer connected: version: %d, blocks=%d, peer=%d%s (%s)\n",
2503 pfrom.
m_tx_relay ==
nullptr ?
"block-relay" :
"full-relay");
2519 bool fAnnounceUsingCMPCTBLOCK =
false;
2520 uint64_t nCMPCTBLOCKVersion = 2;
2523 nCMPCTBLOCKVersion = 1;
2541 if (!State(pfrom.
GetId())->m_wtxid_relay) {
2542 State(pfrom.
GetId())->m_wtxid_relay =
true;
2543 g_wtxid_relay_peers++;
2574 std::vector<CAddress> vAddr;
2588 std::vector<CAddress> vAddrOk;
2590 int64_t nSince = nNow - 10 * 60;
2593 if (interruptMsgProc)
2602 if (addr.
nTime <= 100000000 || addr.
nTime > nNow + 10 * 60)
2603 addr.
nTime = nNow - 5 * 24 * 60 * 60;
2617 vAddrOk.push_back(addr);
2620 if (vAddr.size() < 1000)
2629 State(pfrom.
GetId())->fPreferHeaders =
true;
2634 bool fAnnounceUsingCMPCTBLOCK =
false;
2635 uint64_t nCMPCTBLOCKVersion = 0;
2636 vRecv >> fAnnounceUsingCMPCTBLOCK >> nCMPCTBLOCKVersion;
2640 if (!State(pfrom.
GetId())->fProvidesHeaderAndIDs) {
2641 State(pfrom.
GetId())->fProvidesHeaderAndIDs =
true;
2642 State(pfrom.
GetId())->fWantsCmpctWitness = nCMPCTBLOCKVersion == 2;
2644 if (State(pfrom.
GetId())->fWantsCmpctWitness == (nCMPCTBLOCKVersion == 2))
2645 State(pfrom.
GetId())->fPreferHeaderAndIDs = fAnnounceUsingCMPCTBLOCK;
2646 if (!State(pfrom.
GetId())->fSupportsDesiredCmpctVersion) {
2648 State(pfrom.
GetId())->fSupportsDesiredCmpctVersion = (nCMPCTBLOCKVersion == 2);
2650 State(pfrom.
GetId())->fSupportsDesiredCmpctVersion = (nCMPCTBLOCKVersion == 1);
2657 std::vector<CInv> vInv;
2671 fBlocksOnly =
false;
2676 const auto current_time = GetTime<std::chrono::microseconds>();
2679 for (
CInv& inv : vInv) {
2680 if (interruptMsgProc)
return;
2685 if (State(pfrom.
GetId())->m_wtxid_relay) {
2686 if (inv.IsMsgTx())
continue;
2688 if (inv.IsMsgWtx())
continue;
2691 if (inv.IsMsgBlk()) {
2693 LogPrint(
BCLog::NET,
"got inv: %s %s peer=%d\n", inv.ToString(), fAlreadyHave ?
"have" :
"new", pfrom.
GetId());
2695 UpdateBlockAvailability(pfrom.
GetId(), inv.hash);
2696 if (!fAlreadyHave && !
fImporting && !
fReindex && !mapBlocksInFlight.count(inv.hash)) {
2702 best_block = &inv.hash;
2704 }
else if (inv.IsGenTxMsg()) {
2707 LogPrint(
BCLog::NET,
"got inv: %s %s peer=%d\n", inv.ToString(), fAlreadyHave ?
"have" :
"new", pfrom.
GetId());
2711 LogPrint(
BCLog::NET,
"transaction (%s) inv sent in violation of protocol, disconnecting peer=%d\n", inv.hash.ToString(), pfrom.
GetId());
2715 AddTxAnnouncement(pfrom, gtxid, current_time);
2722 if (best_block !=
nullptr) {
2731 std::vector<CInv> vInv;
2741 if (vInv.size() > 0) {
2746 LOCK(peer->m_getdata_requests_mutex);
2747 peer->m_getdata_requests.insert(peer->m_getdata_requests.end(), vInv.begin(), vInv.end());
2757 vRecv >> locator >> hashStop;
2773 std::shared_ptr<const CBlock> a_recent_block;
2776 a_recent_block = most_recent_block;
2826 std::shared_ptr<const CBlock> recent_block;
2829 if (most_recent_block_hash == req.
blockhash)
2830 recent_block = most_recent_block;
2868 WITH_LOCK(peer->m_getdata_requests_mutex, peer->m_getdata_requests.push_back(inv));
2876 vRecv >> locator >> hashStop;
2886 LogPrint(
BCLog::NET,
"Ignoring getheaders from peer=%d because node is in initial block download\n", pfrom.
GetId());
2890 CNodeState *nodestate = State(pfrom.
GetId());
2901 LogPrint(
BCLog::NET,
"%s: ignoring request from peer=%i for old block header that isn't in the main chain\n", __func__, pfrom.
GetId());
2914 std::vector<CBlock> vHeaders;
2920 if (--nLimit <= 0 || pindex->GetBlockHash() == hashStop)
2955 const uint256& txid = ptx->GetHash();
2956 const uint256& wtxid = ptx->GetWitnessHash();
2960 CNodeState* nodestate = State(pfrom.
GetId());
2962 const uint256& hash = nodestate->m_wtxid_relay ? wtxid : txid;
2964 if (nodestate->m_wtxid_relay && txid != wtxid) {
2973 m_txrequest.ReceivedResponse(pfrom.
GetId(), txid);
2974 if (tx.
HasWitness()) m_txrequest.ReceivedResponse(pfrom.
GetId(), wtxid);
3004 std::list<CTransactionRef> lRemovedTxn;
3010 m_txrequest.ForgetTxHash(tx.
GetHash());
3013 for (
unsigned int i = 0; i < tx.
vout.size(); i++) {
3014 auto it_by_prev = mapOrphanTransactionsByPrev.find(
COutPoint(txid, i));
3015 if (it_by_prev != mapOrphanTransactionsByPrev.end()) {
3016 for (
const auto& elem : it_by_prev->second) {
3017 peer->m_orphan_work_set.insert(elem->first);
3038 bool fRejectedParents =
false;
3042 std::vector<uint256> unique_parents;
3043 unique_parents.reserve(tx.
vin.size());
3048 std::sort(unique_parents.begin(), unique_parents.end());
3049 unique_parents.erase(std::unique(unique_parents.begin(), unique_parents.end()), unique_parents.end());
3050 for (
const uint256& parent_txid : unique_parents) {
3051 if (recentRejects->contains(parent_txid)) {
3052 fRejectedParents =
true;
3056 if (!fRejectedParents) {
3057 const auto current_time = GetTime<std::chrono::microseconds>();
3059 for (
const uint256& parent_txid : unique_parents) {
3065 const GenTxid gtxid{
false, parent_txid};
3072 m_txrequest.ForgetTxHash(tx.
GetHash());
3089 recentRejects->insert(tx.
GetHash());
3091 m_txrequest.ForgetTxHash(tx.
GetHash());
3109 assert(recentRejects);
3121 recentRejects->insert(tx.
GetHash());
3122 m_txrequest.ForgetTxHash(tx.
GetHash());
3165 vRecv >> cmpctblock;
3167 bool received_new_header =
false;
3180 received_new_header =
true;
3197 bool fProcessBLOCKTXN =
false;
3202 bool fRevertToHeaderProcessing =
false;
3206 std::shared_ptr<CBlock> pblock = std::make_shared<CBlock>();
3207 bool fBlockReconstructed =
false;
3215 CNodeState *nodestate = State(pfrom.
GetId());
3220 nodestate->m_last_block_announcement =
GetTime();
3223 std::map<uint256, std::pair<NodeId, std::list<QueuedBlock>::iterator> >::iterator blockInFlightIt = mapBlocksInFlight.find(pindex->
GetBlockHash());
3224 bool fAlreadyInFlight = blockInFlightIt != mapBlocksInFlight.end();
3231 if (fAlreadyInFlight) {
3234 std::vector<CInv> vInv(1);
3242 if (!fAlreadyInFlight && !CanDirectFetch(
m_chainparams.GetConsensus()))
3255 (fAlreadyInFlight && blockInFlightIt->second.first == pfrom.
GetId())) {
3256 std::list<QueuedBlock>::iterator* queuedBlockIt =
nullptr;
3258 if (!(*queuedBlockIt)->partialBlock)
3275 std::vector<CInv> vInv(1);
3282 for (
size_t i = 0; i < cmpctblock.
BlockTxCount(); i++) {
3291 fProcessBLOCKTXN =
true;
3308 std::vector<CTransactionRef> dummy;
3309 status = tempBlock.
FillBlock(*pblock, dummy);
3311 fBlockReconstructed =
true;
3315 if (fAlreadyInFlight) {
3318 std::vector<CInv> vInv(1);
3324 fRevertToHeaderProcessing =
true;
3329 if (fProcessBLOCKTXN) {
3333 if (fRevertToHeaderProcessing) {
3342 if (fBlockReconstructed) {
3347 mapBlockSource.emplace(pblock->GetHash(), std::make_pair(pfrom.
GetId(),
false));
3349 bool fNewBlock =
false;
3364 mapBlockSource.erase(pblock->GetHash());
3372 MarkBlockAsReceived(pblock->GetHash());
3389 std::shared_ptr<CBlock> pblock = std::make_shared<CBlock>();
3390 bool fBlockRead =
false;
3394 std::map<uint256, std::pair<NodeId, std::list<QueuedBlock>::iterator> >::iterator
it = mapBlocksInFlight.find(resp.
blockhash);
3395 if (
it == mapBlocksInFlight.end() || !
it->second.second->partialBlock ||
3396 it->second.first != pfrom.
GetId()) {
3405 Misbehaving(pfrom.
GetId(), 100,
"invalid compact block/non-matching block transactions");
3409 std::vector<CInv> invs;
3438 mapBlockSource.emplace(resp.
blockhash, std::make_pair(pfrom.
GetId(),
false));
3442 bool fNewBlock =
false;
3454 mapBlockSource.erase(pblock->GetHash());
3468 std::vector<CBlockHeader> headers;
3476 headers.resize(nCount);
3477 for (
unsigned int n = 0; n < nCount; n++) {
3478 vRecv >> headers[n];
3493 std::shared_ptr<CBlock> pblock = std::make_shared<CBlock>();
3498 bool forceProcessing =
false;
3499 const uint256 hash(pblock->GetHash());
3504 forceProcessing |= MarkBlockAsReceived(hash);
3508 mapBlockSource.emplace(hash, std::make_pair(pfrom.
GetId(),
true));
3510 bool fNewBlock =
false;
3516 mapBlockSource.erase(pblock->GetHash());
3541 std::vector<CAddress> vAddr;
3548 for (
const CAddress &addr : vAddr) {
3603 const auto ping_end = time_received;
3606 bool bPingFinished =
false;
3607 std::string sProblem;
3609 if (nAvail >=
sizeof(nonce)) {
3616 bPingFinished =
true;
3617 const auto ping_time = ping_end - pfrom.
m_ping_start.load();
3618 if (ping_time.count() >= 0) {
3624 sProblem =
"Timing mishap";
3628 sProblem =
"Nonce mismatch";
3631 bPingFinished =
true;
3632 sProblem =
"Nonce zero";
3636 sProblem =
"Unsolicited pong without ping";
3640 bPingFinished =
true;
3641 sProblem =
"Short payload";
3644 if (!(sProblem.empty())) {
3652 if (bPingFinished) {
3685 std::vector<unsigned char> vData;
3723 vRecv >> newFeeFilter;
3727 pfrom.
m_tx_relay->minFeeFilter = newFeeFilter;
3750 std::vector<CInv> vInv;
3754 for (
CInv &inv : vInv) {
3755 if (inv.IsGenTxMsg()) {
3758 m_txrequest.ReceivedResponse(pfrom.
GetId(), inv.hash);
3773 PeerRef peer = GetPeerRef(peer_id);
3774 if (peer ==
nullptr)
return false;
3777 LOCK(peer->m_misbehavior_mutex);
3780 if (!peer->m_should_discourage)
return false;
3782 peer->m_should_discourage =
false;
3787 LogPrintf(
"Warning: not punishing noban peer %d!\n", peer_id);
3793 LogPrintf(
"Warning: not punishing manually connected peer %d!\n", peer_id);
3800 LogPrintf(
"Warning: disconnecting but not discouraging local peer %d!\n", peer_id);
3806 LogPrintf(
"Disconnecting and discouraging peer %d!\n", peer_id);
3814 bool fMoreWork =
false;
3816 PeerRef peer = GetPeerRef(pfrom->
GetId());
3817 if (peer ==
nullptr)
return false;
3820 LOCK(peer->m_getdata_requests_mutex);
3821 if (!peer->m_getdata_requests.empty()) {
3828 if (!peer->m_orphan_work_set.empty()) {
3839 LOCK(peer->m_getdata_requests_mutex);
3840 if (!peer->m_getdata_requests.empty())
return true;
3845 if (!peer->m_orphan_work_set.empty())
return true;
3852 std::list<CNetMessage> msgs;
3855 if (pfrom->vProcessMsg.empty())
3858 msgs.splice(msgs.begin(), pfrom->vProcessMsg, pfrom->vProcessMsg.begin());
3861 fMoreWork = !pfrom->vProcessMsg.empty();
3866 const std::string& msg_type = msg.
m_command;
3873 if (interruptMsgProc)
return false;
3875 LOCK(peer->m_getdata_requests_mutex);
3876 if (!peer->m_getdata_requests.empty()) fMoreWork =
true;
3878 }
catch (
const std::exception& e) {
3891 CNodeState &state = *State(pto.
GetId());
3901 if (state.pindexBestKnownBlock !=
nullptr && state.pindexBestKnownBlock->nChainWork >= ::
ChainActive().Tip()->nChainWork) {
3902 if (state.m_chain_sync.m_timeout != 0) {
3903 state.m_chain_sync.m_timeout = 0;
3904 state.m_chain_sync.m_work_header =
nullptr;
3905 state.m_chain_sync.m_sent_getheaders =
false;
3907 }
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)) {
3914 state.m_chain_sync.m_sent_getheaders =
false;
3915 }
else if (state.m_chain_sync.m_timeout > 0 && time_in_seconds > state.m_chain_sync.m_timeout) {
3919 if (state.m_chain_sync.m_sent_getheaders) {
3921 LogPrintf(
"Disconnecting outbound peer %d for old chain, best known block = %s\n", pto.
GetId(), state.pindexBestKnownBlock !=
nullptr ? state.pindexBestKnownBlock->GetBlockHash().ToString() :
"<none>");
3924 assert(state.m_chain_sync.m_work_header);
3925 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());
3927 state.m_chain_sync.m_sent_getheaders =
true;
3928 constexpr int64_t HEADERS_RESPONSE_TIME = 120;
3934 state.m_chain_sync.m_timeout = time_in_seconds + HEADERS_RESPONSE_TIME;
3944 if (extra_peers > 0) {
3950 int64_t oldest_block_announcement = std::numeric_limits<int64_t>::max();
3957 CNodeState *state = State(pnode->
GetId());
3958 if (state ==
nullptr)
return;
3960 if (state->m_chain_sync.m_protect)
return;
3963 if (state->m_last_block_announcement < oldest_block_announcement || (state->m_last_block_announcement == oldest_block_announcement && pnode->
GetId() > worst_peer)) {
3964 worst_peer = pnode->
GetId();
3965 oldest_block_announcement = state->m_last_block_announcement;
3968 if (worst_peer != -1) {
3977 CNodeState &state = *State(pnode->
GetId());
3979 LogPrint(
BCLog::NET,
"disconnecting extra outbound peer=%d (last block announcement received at time %d)\n", pnode->
GetId(), oldest_block_announcement);
4003 int64_t time_in_seconds =
GetTime();
4011 LogPrintf(
"Potential stale tip detected, will try using extra outbound peer (last tip update: %d seconds ago)\n", time_in_seconds - g_last_tip_update);
4021 class CompareInvMempoolOrder
4026 explicit CompareInvMempoolOrder(
CTxMemPool *_mempool,
bool use_wtxid)
4029 m_wtxid_relay = use_wtxid;
4032 bool operator()(std::set<uint256>::iterator a, std::set<uint256>::iterator b)
4059 bool pingSend =
false;
4070 while (nonce == 0) {
4074 pto->
m_ping_start = GetTime<std::chrono::microseconds>();
4088 CNodeState &state = *State(pto->
GetId());
4091 auto current_time = GetTime<std::chrono::microseconds>();
4103 std::vector<CAddress> vAddr;
4107 const char* msg_type;
4122 vAddr.push_back(addr);
4142 bool fFetch = state.fPreferredDownload || (nPreferredDownload == 0 && !pto->
fClient && !pto->
IsAddrFetchConn());
4146 state.fSyncStarted =
true;
4157 if (pindexStart->
pprev)
4158 pindexStart = pindexStart->
pprev;
4176 std::vector<CBlock> vHeaders;
4177 bool fRevertToInv = ((!state.fPreferHeaders &&
4178 (!state.fPreferHeaderAndIDs || pto->vBlockHashesToAnnounce.size() > 1)) ||
4181 ProcessBlockAvailability(pto->
GetId());
4183 if (!fRevertToInv) {
4184 bool fFoundStartingHeader =
false;
4188 for (
const uint256 &hash : pto->vBlockHashesToAnnounce) {
4193 fRevertToInv =
true;
4196 if (pBestIndex !=
nullptr && pindex->
pprev != pBestIndex) {
4208 fRevertToInv =
true;
4211 pBestIndex = pindex;
4212 if (fFoundStartingHeader) {
4215 }
else if (PeerHasHeader(&state, pindex)) {
4217 }
else if (pindex->
pprev ==
nullptr || PeerHasHeader(&state, pindex->
pprev)) {
4220 fFoundStartingHeader =
true;
4225 fRevertToInv =
true;
4230 if (!fRevertToInv && !vHeaders.empty()) {
4231 if (vHeaders.size() == 1 && state.fPreferHeaderAndIDs) {
4235 vHeaders.front().GetHash().ToString(), pto->
GetId());
4239 bool fGotBlockFromCache =
false;
4242 if (most_recent_block_hash == pBestIndex->
GetBlockHash()) {
4243 if (state.fWantsCmpctWitness || !fWitnessesPresentInMostRecentCompactBlock)
4249 fGotBlockFromCache =
true;
4252 if (!fGotBlockFromCache) {
4259 state.pindexBestHeaderSent = pBestIndex;
4260 }
else if (state.fPreferHeaders) {
4261 if (vHeaders.size() > 1) {
4264 vHeaders.front().GetHash().ToString(),
4265 vHeaders.back().GetHash().ToString(), pto->
GetId());
4268 vHeaders.front().GetHash().ToString(), pto->
GetId());
4271 state.pindexBestHeaderSent = pBestIndex;
4273 fRevertToInv =
true;
4279 if (!pto->vBlockHashesToAnnounce.empty()) {
4280 const uint256 &hashToAnnounce = pto->vBlockHashesToAnnounce.back();
4293 if (!PeerHasHeader(&state, pindex)) {
4294 pto->vInventoryBlockToSend.push_back(hashToAnnounce);
4300 pto->vBlockHashesToAnnounce.clear();
4306 std::vector<CInv> vInv;
4312 for (
const uint256& hash : pto->vInventoryBlockToSend) {
4319 pto->vInventoryBlockToSend.clear();
4325 if (pto->
m_tx_relay->nNextInvSend < current_time) {
4326 fSendTrickle =
true;
4342 if (fSendTrickle && pto->
m_tx_relay->fSendMempool) {
4353 for (
const auto& txinfo : vtxinfo) {
4354 const uint256& hash = state.m_wtxid_relay ? txinfo.tx->GetWitnessHash() : txinfo.tx->GetHash();
4356 pto->
m_tx_relay->setInventoryTxToSend.erase(hash);
4358 if (txinfo.fee < filterrate.
GetFee(txinfo.vsize)) {
4362 if (!pto->
m_tx_relay->pfilter->IsRelevantAndUpdate(*txinfo.tx))
continue;
4364 pto->
m_tx_relay->filterInventoryKnown.insert(hash);
4366 vInv.push_back(inv);
4372 pto->
m_tx_relay->m_last_mempool_req = GetTime<std::chrono::seconds>();
4378 std::vector<std::set<uint256>::iterator> vInvTx;
4379 vInvTx.reserve(pto->
m_tx_relay->setInventoryTxToSend.size());
4380 for (std::set<uint256>::iterator
it = pto->
m_tx_relay->setInventoryTxToSend.begin();
it != pto->
m_tx_relay->setInventoryTxToSend.end();
it++) {
4381 vInvTx.push_back(
it);
4390 CompareInvMempoolOrder compareInvMempoolOrder(&
m_mempool, state.m_wtxid_relay);
4391 std::make_heap(vInvTx.begin(), vInvTx.end(), compareInvMempoolOrder);
4394 unsigned int nRelayedTransactions = 0;
4398 std::pop_heap(vInvTx.begin(), vInvTx.end(), compareInvMempoolOrder);
4399 std::set<uint256>::iterator
it = vInvTx.back();
4406 if (pto->
m_tx_relay->filterInventoryKnown.contains(hash)) {
4414 auto txid = txinfo.
tx->GetHash();
4415 auto wtxid = txinfo.tx->GetWitnessHash();
4417 if (txinfo.fee < filterrate.
GetFee(txinfo.vsize)) {
4420 if (pto->
m_tx_relay->pfilter && !pto->
m_tx_relay->pfilter->IsRelevantAndUpdate(*txinfo.tx))
continue;
4422 State(pto->
GetId())->m_recently_announced_invs.insert(hash);
4423 vInv.push_back(inv);
4424 nRelayedTransactions++;
4427 while (!vRelayExpiration.empty() && vRelayExpiration.front().first <
count_microseconds(current_time))
4429 mapRelay.erase(vRelayExpiration.front().second);
4430 vRelayExpiration.pop_front();
4433 auto ret = mapRelay.emplace(txid, std::move(txinfo.tx));
4438 auto ret2 = mapRelay.emplace(wtxid, ret.first->second);
4447 pto->
m_tx_relay->filterInventoryKnown.insert(hash);
4454 pto->
m_tx_relay->filterInventoryKnown.insert(txid);
4464 current_time = GetTime<std::chrono::microseconds>();
4469 LogPrintf(
"Peer=%d is stalling block download, disconnecting\n", pto->
GetId());
4478 if (state.vBlocksInFlight.size() > 0) {
4479 QueuedBlock &queuedBlock = state.vBlocksInFlight.front();
4480 int nOtherPeersWithValidatedDownloads = nPeersWithValidatedDownloads - (state.nBlocksInFlightValidHeaders > 0);
4482 LogPrintf(
"Timeout downloading block %s from peer=%d, disconnecting\n", queuedBlock.hash.ToString(), pto->
GetId());
4488 if (state.fSyncStarted && state.nHeadersSyncTimeout < std::numeric_limits<int64_t>::max()) {
4491 if (
count_microseconds(current_time) > state.nHeadersSyncTimeout && nSyncStarted == 1 && (nPreferredDownload - state.fPreferredDownload >= 1)) {
4498 LogPrintf(
"Timeout downloading headers from peer=%d, disconnecting\n", pto->
GetId());
4502 LogPrintf(
"Timeout downloading headers from noban peer=%d, not disconnecting\n", pto->
GetId());
4508 state.fSyncStarted =
false;
4510 state.nHeadersSyncTimeout = 0;
4516 state.nHeadersSyncTimeout = std::numeric_limits<int64_t>::max();
4527 std::vector<CInv> vGetData;
4529 std::vector<const CBlockIndex*> vToDownload;
4539 if (state.nBlocksInFlight == 0 && staller != -1) {
4540 if (State(staller)->nStallingSince == 0) {
4550 std::vector<std::pair<NodeId, GenTxid>> expired;
4551 auto requestable = m_txrequest.GetRequestable(pto->
GetId(), current_time, &expired);
4552 for (
const auto& entry : expired) {
4553 LogPrint(
BCLog::NET,
"timeout of inflight %s %s from peer=%d\n", entry.second.IsWtxid() ?
"wtx" :
"tx",
4554 entry.second.GetHash().ToString(), entry.first);
4556 for (
const GenTxid& gtxid : requestable) {
4569 m_txrequest.ForgetTxHash(gtxid.
GetHash());
4574 if (!vGetData.empty())
4591 if (pto->
m_tx_relay->lastSentFeeFilter == MAX_FILTER) {
4598 CAmount filterToSend = g_filter_rounder.round(currentFilter);
4601 if (filterToSend != pto->
m_tx_relay->lastSentFeeFilter) {
4603 pto->
m_tx_relay->lastSentFeeFilter = filterToSend;
4610 (currentFilter < 3 * pto->m_tx_relay->lastSentFeeFilter / 4 || currentFilter > 4 * pto->
m_tx_relay->lastSentFeeFilter / 3)) {
4624 mapOrphanTransactions.clear();
4625 mapOrphanTransactionsByPrev.clear();
4626 g_orphans_by_wtxid.clear();
bool MoneyRange(const CAmount &nValue)
int64_t CAmount
Amount in satoshis (Can be negative)
static const CAmount MAX_MONEY
No amount larger than this (in satoshi) is valid.
enum ReadStatus_t ReadStatus
const std::string & BlockFilterTypeName(BlockFilterType filter_type)
Get the human-readable name for a filter type.
BlockFilterIndex * GetBlockFilterIndex(BlockFilterType filter_type)
Get a block filter index by type.
static constexpr int CFCHECKPT_INTERVAL
Interval between compact filter checkpoints.
const CBlockIndex * LastCommonAncestor(const CBlockIndex *pa, const CBlockIndex *pb)
Find the last common ancestor two blocks have.
int64_t GetBlockProofEquivalentTime(const CBlockIndex &to, const CBlockIndex &from, const CBlockIndex &tip, const Consensus::Params ¶ms)
Return the time it would take to redo the work difference between from and to, assuming the current h...
@ BLOCK_VALID_CHAIN
Outputs do not overspend inputs, no double spends, coinbase output ok, no immature coinbase spends,...
@ BLOCK_VALID_TRANSACTIONS
Only first tx is coinbase, 2 <= coinbase input script length <= 100, transactions valid,...
@ BLOCK_VALID_SCRIPTS
Scripts & signatures ok. Implies all parents are also at least SCRIPTS.
@ BLOCK_VALID_TREE
All parent headers found, difficulty matches, timestamp >= median previous, checkpoint.
@ BLOCK_HAVE_DATA
full block available in blk*.dat
bool IsArgSet(const std::string &strArg) const
Return true if the given argument has been manually set.
std::string GetArg(const std::string &strArg, const std::string &strDefault) const
Return string argument or default value.
bool GetBoolArg(const std::string &strArg, bool fDefault) const
Return boolean argument or default value.
void Discourage(const CNetAddr &net_addr)
bool IsBanned(const CNetAddr &net_addr)
Return whether net_addr is banned.
bool IsDiscouraged(const CNetAddr &net_addr)
Return whether net_addr is discouraged.
BlockFilterIndex is used to store and retrieve block filters, hashes, and headers for a range of bloc...
bool LookupFilterRange(int start_height, const CBlockIndex *stop_index, std::vector< BlockFilter > &filters_out) const
Get a range of filters between two heights on a chain.
bool LookupFilterHeader(const CBlockIndex *block_index, uint256 &header_out)
Get a single filter header by block.
bool LookupFilterHashRange(int start_height, const CBlockIndex *stop_index, std::vector< uint256 > &hashes_out) const
Get a range of filter hashes between two heights on a chain.
std::vector< CTransactionRef > txn
std::vector< uint16_t > indexes
A CService with information about it as peer.
size_t BlockTxCount() const
std::vector< CTransactionRef > vtx
The block chain is a tree shaped structure starting with the genesis block at the root,...
CBlockIndex * pprev
pointer to the index of the predecessor of this block
CBlockHeader GetBlockHeader() const
arith_uint256 nChainWork
(memory only) Total amount of work (expected number of hashes) in the chain up to and including this ...
bool HaveTxsDownloaded() const
Check whether this block's and all previous blocks' transactions have been downloaded (and stored to ...
uint256 GetBlockHash() const
int64_t GetBlockTime() const
unsigned int nTx
Number of transactions in this block.
bool IsValid(enum BlockStatus nUpTo=BLOCK_VALID_TRANSACTIONS) const
Check whether this block index entry is valid up to the passed validity level.
CBlockIndex * GetAncestor(int height)
Efficiently find an ancestor of this block.
int nHeight
height of the entry in the chain. The genesis block has height 0
uint32_t nStatus
Verification status of this block. See enum BlockStatus.
BloomFilter is a probabilistic filter which SPV clients provide so that we can filter the transaction...
bool IsWithinSizeConstraints() const
True if the size is <= MAX_BLOOM_FILTER_SIZE and the number of hash functions is <= MAX_HASH_FUNCS (c...
CBlockIndex * Next(const CBlockIndex *pindex) const
Find the successor of a block in this chain, or nullptr if the given index is not found or is the tip...
CBlockIndex * Tip() const
Returns the index entry for the tip of this chain, or nullptr if none.
CChainParams defines various tweakable parameters of a given instance of the Bitcoin system.
const CMessageHeader::MessageStartChars & MessageStart() const
const Consensus::Params & GetConsensus() const
bool IsInitialBlockDownload() const
Check whether we are doing an initial block download (synchronizing from disk or network)
std::vector< CAddress > GetAddresses(size_t max_addresses, size_t max_pct)
void ForEachNode(const NodeFn &func)
bool GetTryNewOutboundPeer()
bool ForNode(NodeId id, std::function< bool(CNode *pnode)> func)
bool AddNewAddresses(const std::vector< CAddress > &vAddr, const CAddress &addrFrom, int64_t nTimePenalty=0)
bool GetNetworkActive() const
void SetTryNewOutboundPeer(bool flag)
unsigned int GetReceiveFloodSize() const
void SetBestHeight(int height)
void ForEachNodeThen(Callable &&pre, CallableAfter &&post)
void SetServices(const CService &addr, ServiceFlags nServices)
bool DisconnectNode(const std::string &node)
CSipHasher GetDeterministicRandomizer(uint64_t id) const
Get a unique deterministic randomizer.
void MarkAddressGood(const CAddress &addr)
void WakeMessageHandler()
bool OutboundTargetReached(bool historicalBlockServingLimit)
check if the outbound target is reached if param historicalBlockServingLimit is set true,...
int64_t PoissonNextSendInbound(int64_t now, int average_interval_seconds)
Attempts to obfuscate tx time through exponentially distributed emitting.
bool CheckIncomingNonce(uint64_t nonce)
int GetExtraOutboundCount()
void PushMessage(CNode *pnode, CSerializedNetMsg &&msg)
bool GetUseAddrmanOutgoing() const
Double ended buffer combining vector and stream-like interfaces.
Fee rate in satoshis per kilobyte: CAmount / kB.
CAmount GetFee(size_t nBytes) const
Return the fee in satoshis for the given size in bytes.
CAmount GetFeePerK() const
Return the fee in satoshis for a size of 1000 bytes.
bool IsMsgCmpctBlk() const
bool IsMsgFilteredBlk() const
bool IsMsgWitnessBlk() const
Used to relay blocks as header + vector<merkle branch> to filtered nodes.
std::vector< std::pair< unsigned int, uint256 > > vMatchedTxn
Public only for unit testing and relay testing (not relayed).
bool IsRelayable() const
Whether this address should be relayed to other peers even if we can't reach it ourselves.
void SetIP(const CNetAddr &ip)
bool IsAddrV1Compatible() const
Check if the current object can be serialized in pre-ADDRv2/BIP155 format.
Transport protocol agnostic message container.
uint32_t m_message_size
size of the payload
std::chrono::microseconds m_time
time of message receipt
CDataStream m_recv
received message data
void SetVersion(int nVersionIn)
CSerializedNetMsg Make(int nFlags, std::string msg_type, Args &&... args) const
Information about a peer.
RecursiveMutex cs_vProcessMsg
bool IsFeelerConn() const
bool ExpectServicesFromConn() const
std::atomic< int > nVersion
bool IsInboundConn() const
bool HasPermission(NetPermissionFlags permission) const
std::atomic_bool fPauseRecv
bool IsOutboundOrBlockRelayConn() const
bool IsManualConn() const
void PushTxInventory(const uint256 &hash)
std::atomic< int64_t > nTimeOffset
void PushAddress(const CAddress &_addr, FastRandomContext &insecure_rand)
std::atomic< bool > fPingQueued
std::string ConnectionTypeAsString() const
void SetCommonVersion(int greatest_common_version)
void SetAddrLocal(const CService &addrLocalIn)
May not be called more than once.
std::atomic_bool fSuccessfullyConnected
bool IsAddrFetchConn() const
uint64_t GetLocalNonce() const
std::atomic< ServiceFlags > nServices
const int64_t nTimeConnected
std::string GetAddrName() const
int GetMyStartingHeight() const
bool IsBlockOnlyConn() const
int GetCommonVersion() const
bool IsFullOutboundConn() const
std::atomic< int > nStartingHeight
std::unique_ptr< CRollingBloomFilter > m_addr_known
std::atomic_bool fPauseSend
std::unique_ptr< TxRelay > m_tx_relay
std::atomic< std::chrono::microseconds > m_ping_start
When the last ping was sent, or 0 if no ping was ever sent.
void AddAddressKnown(const CAddress &_addr)
std::atomic< int64_t > nLastTXTime
UNIX epoch time of the last transaction received from this peer that we had not yet seen (e....
std::atomic< int64_t > nMinPingUsecTime
std::atomic< uint64_t > nPingNonceSent
std::vector< CAddress > vAddrToSend
ServiceFlags GetLocalServices() const
std::atomic< int64_t > nPingUsecTime
void AddKnownTx(const uint256 &hash)
std::atomic< int64_t > nLastBlockTime
UNIX epoch time of the last block received from this peer that we had not yet seen (e....
std::atomic_bool m_wants_addrv2
Whether the peer has signaled support for receiving ADDRv2 (BIP155) messages, implying a preference t...
bool RelayAddrsWithConn() const
std::atomic_bool fDisconnect
An outpoint - a combination of a transaction hash and an index n into its vout.
RollingBloomFilter is a probabilistic "keep track of most recently inserted" set.
Simple class for background tasks that should be run periodically or once "after a while".
void scheduleFromNow(Function f, std::chrono::milliseconds delta)
Call f once after the delta has passed.
void scheduleEvery(Function f, std::chrono::milliseconds delta)
Repeat f until the scheduler is stopped.
A combination of a network address (CNetAddr) and a (TCP) port.
std::string ToString() const
std::vector< unsigned char > GetKey() const
uint64_t Finalize() const
Compute the 64-bit SipHash-2-4 of the data written so far.
CSipHasher & Write(uint64_t data)
Hash a 64-bit integer worth of data It is treated as if this was the little-endian interpretation of ...
The basic transaction that is broadcasted on the network and contained in blocks.
const std::vector< CTxOut > vout
const uint256 & GetHash() const
const std::vector< CTxIn > vin
const uint256 & GetWitnessHash() const
An input of a transaction.
CTxMemPoolEntry stores data about the corresponding transaction, as well as data about all in-mempool...
std::set< CTxMemPoolEntryRef, CompareIteratorByHash > Parents
CTxMemPool stores valid-according-to-the-current-best-chain transactions that may be included in the ...
void RemoveUnbroadcastTx(const uint256 &txid, const bool unchecked=false)
Removes a transaction from the unbroadcast set.
RecursiveMutex cs
This mutex needs to be locked when accessing mapTx or other members that are guarded by it.
CFeeRate GetMinFee(size_t sizelimit) const
The minimum fee to get into the mempool, which may itself not be enough for larger-sized transactions...
CTransactionRef get(const uint256 &hash) const
size_t DynamicMemoryUsage() const
std::vector< TxMempoolInfo > infoAll() const
Optional< txiter > GetIter(const uint256 &txid) const EXCLUSIVE_LOCKS_REQUIRED(cs)
Returns an iterator to the given hash, if found.
std::set< uint256 > GetUnbroadcastTxs() const
Returns transactions in unbroadcast set.
void check(const CCoinsViewCache *pcoins) const
If sanity-checking is turned on, check makes sure the pool is consistent (does not contain two transa...
bool exists(const GenTxid >xid) const
TxMempoolInfo info(const uint256 &hash) const
bool CompareDepthAndScore(const uint256 &hasha, const uint256 &hashb, bool wtxid=false)
unsigned long size() const
Provides an interface for creating and interacting with one or two chainstates: an IBD chainstate gen...
bool ProcessNewBlock(const CChainParams &chainparams, const std::shared_ptr< const CBlock > pblock, bool fForceProcessing, bool *fNewBlock) LOCKS_EXCLUDED(cs_main)
Process an incoming block.
CChainState & ActiveChainstate() const
The most-work chain.
bool ProcessNewBlockHeaders(const std::vector< CBlockHeader > &block, BlockValidationState &state, const CChainParams &chainparams, const CBlockIndex **ppindex=nullptr) LOCKS_EXCLUDED(cs_main)
Process incoming block headers.
uint64_t randrange(uint64_t range) noexcept
Generate a random integer in the range [0..range).
A generic txid reference (txid or wtxid).
const uint256 & GetHash() const
ReadStatus InitData(const CBlockHeaderAndShortTxIDs &cmpctblock, const std::vector< std::pair< uint256, CTransactionRef >> &extra_txn)
bool IsTxAvailable(size_t index) const
ReadStatus FillBlock(CBlock &block, const std::vector< CTransactionRef > &vtx_missing)
bool SendMessages(CNode *pto) override EXCLUSIVE_LOCKS_REQUIRED(pto -> cs_sendProcessing)
Send queued protocol messages to be sent to a give node.
bool ProcessMessages(CNode *pfrom, std::atomic< bool > &interrupt) override
Process protocol messages received from a given node.
void BlockChecked(const CBlock &block, const BlockValidationState &state) override
Overridden from CValidationInterface.
void CheckForStaleTipAndEvictPeers()
Evict extra outbound peers.
bool MaybeDiscourageAndDisconnect(CNode &pnode)
Maybe disconnect a peer and discourage future connections from its address.
PeerManager(const CChainParams &chainparams, CConnman &connman, BanMan *banman, CScheduler &scheduler, ChainstateManager &chainman, CTxMemPool &pool)
void ProcessOrphanTx(std::set< uint256 > &orphan_work_set) EXCLUSIVE_LOCKS_REQUIRED(cs_main
Reconsider orphan transactions after a parent has been accepted to the mempool.
void BlockConnected(const std::shared_ptr< const CBlock > &pblock, const CBlockIndex *pindexConnected) override
Overridden from CValidationInterface.
void InitializeNode(CNode *pnode) override
Initialize a peer by adding it to mapNodeState and pushing a message requesting its version.
void ReattemptInitialBroadcast(CScheduler &scheduler) const
Retrieve unbroadcast transactions from the mempool and reattempt sending to peers.
void ProcessHeadersMessage(CNode &pfrom, const std::vector< CBlockHeader > &headers, bool via_compact_block)
Process a single headers message from a peer.
BanMan *const m_banman
Pointer to this node's banman.
void AddTxAnnouncement(const CNode &node, const GenTxid >xid, std::chrono::microseconds current_time) EXCLUSIVE_LOCKS_REQUIRED(const CChainParams & m_chainparams
Register with TxRequestTracker that an INV has been received from a peer.
void EvictExtraOutboundPeers(int64_t time_in_seconds) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
If we have extra outbound peers, try to disconnect the one with the oldest block announcement.
void Misbehaving(const NodeId pnode, const int howmuch, const std::string &message)
Increment peer's misbehavior score.
void ConsiderEviction(CNode &pto, int64_t time_in_seconds) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Consider evicting an outbound peer based on the amount of time they've been behind our tip.
void NewPoWValidBlock(const CBlockIndex *pindex, const std::shared_ptr< const CBlock > &pblock) override
Overridden from CValidationInterface.
ChainstateManager & m_chainman
void BlockDisconnected(const std::shared_ptr< const CBlock > &block, const CBlockIndex *pindex) override
Notifies listeners of a block being disconnected.
void SendBlockTransactions(CNode &pfrom, const CBlock &block, const BlockTransactionsRequest &req)
bool MaybePunishNodeForTx(NodeId nodeid, const TxValidationState &state, const std::string &message="")
Potentially disconnect and discourage a node based on the contents of a TxValidationState object.
void FinalizeNode(const CNode &node, bool &fUpdateConnectionTime) override
Handle removal of a peer by updating various state and removing it from mapNodeState.
void ProcessMessage(CNode &pfrom, const std::string &msg_type, CDataStream &vRecv, const std::chrono::microseconds time_received, const std::atomic< bool > &interruptMsgProc)
Process a single message from a peer.
void UpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload) override
Overridden from CValidationInterface.
bool MaybePunishNodeForBlock(NodeId nodeid, const BlockValidationState &state, bool via_compact_block, const std::string &message="")
Potentially mark a node discouraged based on the contents of a BlockValidationState object.
int64_t m_stale_tip_check_time
Next time to check for stale tip.
std::string ToString() const
std::string ToString() const
static int64_t GetTransactionWeight(const CTransaction &tx)
@ BLOCK_CHECKPOINT
the block failed to meet one of our checkpoints
@ BLOCK_RECENT_CONSENSUS_CHANGE
Invalid by a change to consensus rules more recent than SegWit.
@ BLOCK_INVALID_HEADER
invalid proof of work or time too old
@ BLOCK_CACHED_INVALID
this block was cached as being invalid and we didn't store the reason why
@ BLOCK_CONSENSUS
invalid by consensus rules (excluding any below reasons)
@ BLOCK_MISSING_PREV
We don't have the previous block the checked one is built on.
@ BLOCK_INVALID_PREV
A block this one builds on is invalid.
@ BLOCK_MUTATED
the block's data didn't match the data committed to by the PoW
@ BLOCK_TIME_FUTURE
block timestamp was > 2 hours in the future (or our clock is bad)
@ BLOCK_RESULT_UNSET
initial value. Block has not yet been rejected
@ TX_MISSING_INPUTS
transaction was missing some of its inputs
@ TX_MEMPOOL_POLICY
violated mempool's fee/size/descendant/RBF/etc limits
@ TX_PREMATURE_SPEND
transaction spends a coinbase too early, or violates locktime/sequence locks
@ TX_INPUTS_NOT_STANDARD
inputs (covered by txid) failed policy rules
@ TX_WITNESS_STRIPPED
Transaction is missing a witness.
@ TX_CONFLICT
Tx already in mempool or conflicts with a tx in the chain (if it conflicts with another tx in mempool...
@ TX_RECENT_CONSENSUS_CHANGE
Invalid by a change to consensus rules more recent than SegWit.
@ TX_NOT_STANDARD
otherwise didn't meet our local policy rules
@ TX_WITNESS_MUTATED
Transaction might have a witness prior to SegWit activation, or witness may have been malleated (whic...
@ TX_RESULT_UNSET
initial value. Tx has not yet been rejected
@ TX_CONSENSUS
invalid by consensus rules
static size_t RecursiveDynamicUsage(const CScript &script)
static void LogPrintf(const char *fmt, const Args &... args)
#define LogPrint(category,...)
const char * FILTERLOAD
The filterload message tells the receiving peer to filter all relayed transactions and requested merk...
const char * CFHEADERS
cfheaders is a response to a getcfheaders request containing a filter header and a vector of filter h...
const char * CFILTER
cfilter is a response to a getcfilters request containing a single compact filter.
const char * BLOCK
The block message transmits a single serialized block.
const char * FILTERCLEAR
The filterclear message tells the receiving peer to remove a previously-set bloom filter.
const char * HEADERS
The headers message sends one or more block headers to a node which previously requested certain head...
const char * ADDRV2
The addrv2 message relays connection information for peers on the network just like the addr message,...
const char * SENDHEADERS
Indicates that a node prefers to receive new block announcements via a "headers" message rather than ...
const char * PONG
The pong message replies to a ping message, proving to the pinging node that the ponging node is stil...
const char * SENDCMPCT
Contains a 1-byte bool and 8-byte LE version number.
const char * GETADDR
The getaddr message requests an addr message from the receiving node, preferably one with lots of IP ...
const char * GETCFCHECKPT
getcfcheckpt requests evenly spaced compact filter headers, enabling parallelized download and valida...
const char * NOTFOUND
The notfound message is a reply to a getdata message which requested an object the receiving node doe...
const char * CMPCTBLOCK
Contains a CBlockHeaderAndShortTxIDs object - providing a header and list of "short txids".
const char * MEMPOOL
The mempool message requests the TXIDs of transactions that the receiving node has verified as valid ...
const char * GETCFILTERS
getcfilters requests compact filters for a range of blocks.
const char * TX
The tx message transmits a single transaction.
const char * FILTERADD
The filteradd message tells the receiving peer to add a single element to a previously-set bloom filt...
const char * ADDR
The addr (IP address) message relays connection information for peers on the network.
const char * VERSION
The version message provides information about the transmitting node to the receiving node at the beg...
const char * GETBLOCKS
The getblocks message requests an inv message that provides block header hashes starting from a parti...
const char * FEEFILTER
The feefilter message tells the receiving peer not to inv us any txs which do not meet the specified ...
const char * GETHEADERS
The getheaders message requests a headers message that provides block headers starting from a particu...
const char * GETDATA
The getdata message requests one or more data objects from another node.
const char * VERACK
The verack message acknowledges a previously-received version message, informing the connecting node ...
const char * BLOCKTXN
Contains a BlockTransactions.
const char * GETCFHEADERS
getcfheaders requests a compact filter header and the filter hashes for a range of blocks,...
const char * SENDADDRV2
The sendaddrv2 message signals support for receiving ADDRV2 messages (BIP155).
const char * WTXIDRELAY
Indicates that a node prefers to relay transactions via wtxid, rather than txid.
const char * PING
The ping message is sent periodically to help confirm that the receiving peer is still connected.
const char * MERKLEBLOCK
The merkleblock message is a reply to a getdata message which requested a block using the inventory t...
const char * CFCHECKPT
cfcheckpt is a response to a getcfcheckpt request containing a vector of evenly spaced filter headers...
const char * GETBLOCKTXN
Contains a BlockTransactionsRequest Peer should respond with "blocktxn" message.
const char * INV
The inv message (inventory message) transmits one or more inventories of objects known to the transmi...
CAddress GetLocalAddress(const CNetAddr *paddrPeer, ServiceFlags nLocalServices)
bool IsPeerAddrLocalGood(CNode *pnode)
void AdvertiseLocal(CNode *pnode)
std::string strSubVersion
Subversion as sent to the P2P network in version messages.
int64_t PoissonNextSend(int64_t now, int average_interval_seconds)
Return a timestamp in the future (in microseconds) for exponentially distributed events.
bool IsReachable(enum Network net)
bool SeenLocal(const CService &addr)
vote for a local address
static constexpr size_t MAX_ADDR_TO_SEND
The maximum number of addresses from our addrman to return in response to a getaddr message.
static const unsigned int MAX_SUBVERSION_LENGTH
Maximum length of the user agent string in version message.
const std::chrono::seconds now
unsigned int LimitOrphanTxSize(unsigned int nMaxOrphans)
static constexpr int64_t HEADERS_DOWNLOAD_TIMEOUT_BASE
Headers download timeout expressed in microseconds Timeout = base + per_header * (expected number of ...
RecursiveMutex g_cs_orphans
Guards orphan transactions and extra txs for compact blocks.
static const unsigned int BLOCK_STALLING_TIMEOUT
Timeout in seconds during which a peer must stall block download progress before being disconnected.
static int EraseOrphanTx(uint256 hash) EXCLUSIVE_LOCKS_REQUIRED(g_cs_orphans)
static void RelayAddress(const CAddress &addr, bool fReachable, const CConnman &connman)
static CTransactionRef FindTxForGetData(const CTxMemPool &mempool, const CNode &peer, const GenTxid >xid, const std::chrono::seconds mempool_req, const std::chrono::seconds now) LOCKS_EXCLUDED(cs_main)
Determine whether or not a peer can request a transaction, and return it (or nullptr if not found or ...
static bool BlockRequestAllowed(const CBlockIndex *pindex, const Consensus::Params &consensusParams) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
static const int MAX_BLOCKS_IN_TRANSIT_PER_PEER
Number of blocks that can be requested at any given time from a single peer.
static bool AlreadyHaveBlock(const uint256 &block_hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
static void ProcessGetBlockData(CNode &pfrom, const CChainParams &chainparams, const CInv &inv, CConnman &connman)
static const unsigned int BLOCK_DOWNLOAD_WINDOW
Size of the "block download window": how far ahead of our current height do we fetch?...
static const int MAX_UNCONNECTING_HEADERS
Maximum number of unconnecting headers announcements before DoS score.
static constexpr int STALE_RELAY_AGE_LIMIT
Age after which a stale block will no longer be served if requested as protection against fingerprint...
std::vector< CInv > vNotFound
static constexpr int HISTORICAL_BLOCK_AGE
Age after which a block is considered historical for purposes of rate limiting block relay.
void EraseOrphansFor(NodeId peer)
static const unsigned int NODE_NETWORK_LIMITED_MIN_BLOCKS
Minimum blocks required to signal NODE_NETWORK_LIMITED.
static constexpr std::chrono::seconds UNCONDITIONAL_RELAY_DELAY
How long a transaction has to be in the mempool before it can unconditionally be relayed (even when n...
static void ProcessGetCFCheckPt(CNode &peer, CDataStream &vRecv, const CChainParams &chain_params, CConnman &connman)
Handle a getcfcheckpt request.
static void ProcessGetCFilters(CNode &peer, CDataStream &vRecv, const CChainParams &chain_params, CConnman &connman)
Handle a cfilters request.
const std::chrono::seconds mempool_req
static void peer m_getdata_requests_mutex
static const int MAX_BLOCKTXN_DEPTH
Maximum depth of blocks we're willing to respond to GETBLOCKTXN requests for.
static constexpr int32_t MAX_PEER_TX_REQUEST_IN_FLIGHT
Maximum number of in-flight transaction requests from a peer.
static constexpr auto OVERLOADED_PEER_TX_DELAY
How long to delay requesting transactions from overloaded peers (see MAX_PEER_TX_REQUEST_IN_FLIGHT).
static RecursiveMutex cs_most_recent_block
static constexpr int32_t MAX_OUTBOUND_PEERS_TO_PROTECT_FROM_DISCONNECT
Protect at least this many outbound peers from disconnection due to slow/ behind headers chain.
static constexpr std::chrono::microseconds GETDATA_TX_INTERVAL
How long to wait (in microseconds) before downloading a transaction from an additional peer.
static void ProcessGetCFHeaders(CNode &peer, CDataStream &vRecv, const CChainParams &chain_params, CConnman &connman)
Handle a cfheaders request.
static bool PrepareBlockFilterRequest(CNode &peer, const CChainParams &chain_params, BlockFilterType filter_type, uint32_t start_height, const uint256 &stop_hash, uint32_t max_height_diff, const CBlockIndex *&stop_index, BlockFilterIndex *&filter_index)
Validation logic for compact filters request handling.
static bool AlreadyHaveTx(const GenTxid >xid, const CTxMemPool &mempool) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
static const int64_t BLOCK_DOWNLOAD_TIMEOUT_BASE
Block download timeout base, expressed in millionths of the block interval (i.e.
void RelayTransaction(const uint256 &txid, const uint256 &wtxid, const CConnman &connman)
Relay transaction to every node.
static constexpr int64_t HEADERS_DOWNLOAD_TIMEOUT_PER_HEADER
static uint32_t GetFetchFlags(const CNode &pfrom) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
static constexpr uint32_t MAX_GETCFILTERS_SIZE
Maximum number of compact filters that may be requested with one getcfilters.
static const unsigned int MAX_GETDATA_SZ
Limit to avoid sending big packets.
static void AddToCompactExtraTransactions(const CTransactionRef &tx) EXCLUSIVE_LOCKS_REQUIRED(g_cs_orphans)
static constexpr int64_t STALE_CHECK_INTERVAL
How frequently to check for stale tips, in seconds.
static const int64_t BLOCK_DOWNLOAD_TIMEOUT_PER_PEER
Additional block download timeout per parallel downloading peer (i.e.
void UpdateLastBlockAnnounceTime(NodeId node, int64_t time_in_seconds)
static constexpr std::chrono::minutes PING_INTERVAL
Time between pings automatically sent out for latency probing and keepalive.
static constexpr int64_t MINIMUM_CONNECT_TIME
Minimum time an outbound-peer-eviction candidate must be connected for, in order to evict,...
static constexpr unsigned int INVENTORY_MAX_RECENT_RELAY
The number of most recently announced transactions a peer can request.
const CNetMsgMaker msgMaker(pfrom.GetCommonVersion())
static constexpr unsigned int AVG_FEEFILTER_BROADCAST_INTERVAL
Verify that INVENTORY_MAX_RECENT_RELAY is enough to cache everything typically relayed before uncondi...
static const unsigned int INVENTORY_BROADCAST_INTERVAL
Average delay between trickled inventory transmissions in seconds.
static constexpr int64_t EXTRA_PEER_CHECK_INTERVAL
How frequently to check for extra outbound peers and disconnect, in seconds.
static constexpr std::chrono::seconds RELAY_TX_CACHE_TIME
How long to cache transactions in mapRelay for normal relay.
static const unsigned int MAX_LOCATOR_SZ
The maximum number of entries in a locator.
static constexpr int32_t MAX_PEER_TX_ANNOUNCEMENTS
Maximum number of transactions to consider for requesting, per peer.
static constexpr auto TXID_RELAY_DELAY
How long to delay requesting transactions via txids, if we have wtxid-relaying peers.
bool AddOrphanTx(const CTransactionRef &tx, NodeId peer) EXCLUSIVE_LOCKS_REQUIRED(g_cs_orphans)
static void ProcessGetData(CNode &pfrom, Peer &peer, const CChainParams &chainparams, CConnman &connman, CTxMemPool &mempool, const std::atomic< bool > &interruptMsgProc) EXCLUSIVE_LOCKS_REQUIRED(!cs_main
static constexpr unsigned int MAX_FEEFILTER_CHANGE_DELAY
Maximum feefilter broadcast delay after significant change.
static constexpr std::chrono::hours AVG_LOCAL_ADDRESS_BROADCAST_INTERVAL
Average delay between local address broadcasts.
static CNetProcessingCleanup instance_of_cnetprocessingcleanup
static const int MAX_CMPCTBLOCK_DEPTH
Maximum depth of blocks we're willing to serve as compact blocks to peers when requested.
std::deque< CInv >::iterator it
static const unsigned int MAX_BLOCKS_TO_ANNOUNCE
Maximum number of headers to announce when relaying blocks with headers message.
static constexpr int64_t ORPHAN_TX_EXPIRE_INTERVAL
Minimum time between orphan transactions expire time checks in seconds.
static constexpr uint32_t MAX_GETCFHEADERS_SIZE
Maximum number of cf hashes that may be requested with one getcfheaders.
static constexpr uint64_t RANDOMIZER_ID_ADDRESS_RELAY
SHA256("main address relay")[0:8].
static constexpr unsigned int INVENTORY_BROADCAST_MAX
Maximum number of inventory items to send per transmission.
static const unsigned int MAX_HEADERS_RESULTS
Number of headers sent in one getheaders result.
static constexpr int64_t ORPHAN_TX_EXPIRE_TIME
Expiration time for orphan transactions in seconds.
static constexpr size_t MAX_PCT_ADDR_TO_SEND
the maximum percentage of addresses from our addrman to return in response to a getaddr message.
bool GetNodeStateStats(NodeId nodeid, CNodeStateStats &stats)
Get statistics from node state.
static constexpr std::chrono::seconds AVG_ADDRESS_BROADCAST_INTERVAL
Average delay between peer address broadcasts.
static const unsigned int MAX_INV_SZ
The maximum number of entries in an 'inv' protocol message.
static constexpr auto NONPREF_PEER_TX_DELAY
How long to delay requesting transactions from non-preferred peers.
std::map< uint256, COrphanTx > mapOrphanTransactions GUARDED_BY(g_cs_orphans)
Map from txid to orphan transaction record.
static constexpr unsigned int INVENTORY_BROADCAST_PER_SECOND
Maximum rate of inventory items to send per second.
static constexpr int64_t CHAIN_SYNC_TIMEOUT
Timeout for (unprotected) outbound peers to sync to our chainwork, in seconds.
static const unsigned int DEFAULT_BLOCK_RECONSTRUCTION_EXTRA_TXN
Default number of orphan+recently-replaced txn to keep around for block reconstruction.
static const unsigned int DEFAULT_MAX_ORPHAN_TRANSACTIONS
Default for -maxorphantx, maximum number of orphan transactions kept in memory.
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate.
static const int DISCOURAGEMENT_THRESHOLD
Threshold for marking a node to be discouraged, e.g.
static constexpr int ADDRV2_FORMAT
A flag that is ORed into the protocol version to designate that addresses should be serialized in (un...
bool IsProxy(const CNetAddr &addr)
static const unsigned int MAX_STANDARD_TX_WEIGHT
The maximum weight for transactions we're willing to relay/mine.
static const unsigned int DEFAULT_MAX_MEMPOOL_SIZE
Default for -maxmempool, maximum megabytes of mempool memory usage.
static const int SERIALIZE_TRANSACTION_NO_WITNESS
A flag that is ORed into the protocol version to designate that a transaction should be (un)serialize...
std::shared_ptr< const CTransaction > CTransactionRef
void SetServiceFlagsIBDCache(bool state)
Set the current IBD status in order to figure out the desirable service flags.
GenTxid ToGenTxid(const CInv &inv)
Convert a TX/WITNESS_TX/WTX CInv to a GenTxid.
ServiceFlags GetDesirableServiceFlags(ServiceFlags services)
Gets the set of service flags which are "desirable" for a given peer.
static bool HasAllDesirableServiceFlags(ServiceFlags services)
A shortcut for (services & GetDesirableServiceFlags(services)) == GetDesirableServiceFlags(services),...
const uint32_t MSG_WITNESS_FLAG
getdata message type flags
@ MSG_WTX
Defined in BIP 339.
@ MSG_CMPCT_BLOCK
Defined in BIP152.
@ MSG_WITNESS_BLOCK
Defined in BIP144.
ServiceFlags
nServices flags
static bool MayHaveUsefulAddressDB(ServiceFlags services)
Checks if a peer with the given service flags may be capable of having a robust address-storage DB.
void GetRandBytes(unsigned char *buf, int num) noexcept
Overall design of the RNG and entropy sources.
uint64_t GetRand(uint64_t nMax) noexcept
Generate a uniform random integer in the range [0..range).
int GetRandInt(int nMax) noexcept
constexpr auto GetRandMillis
reverse_range< T > reverse_iterate(T &x)
static const unsigned int MAX_SCRIPT_ELEMENT_SIZE
#define LIMITED_STRING(obj, n)
uint64_t ReadCompactSize(Stream &is, bool range_check=true)
Decode a CompactSize-encoded variable-length integer.
constexpr Span< A > MakeSpan(A(&a)[N])
MakeSpan for arrays:
std::vector< unsigned char > ParseHex(const char *psz)
std::string SanitizeString(const std::string &str, int rule)
Remove unsafe chars.
std::string ToString(const T &t)
Locale-independent version of std::to_string.
Describes a place in the block chain to another node such that if the other node doesn't have the sam...
std::vector< uint256 > vHave
std::vector< int > vHeightInFlight
Parameters that influence chain consensus.
int64_t nPowTargetSpacing
CTransactionRef tx
The transaction itself.
#define AssertLockNotHeld(cs)
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
#define EXCLUSIVE_LOCKS_REQUIRED(...)
#define LOCKS_EXCLUDED(...)
int64_t GetTime()
DEPRECATED Use either GetSystemTimeInSeconds (not mockable) or GetTime<T> (mockable)
int64_t count_microseconds(std::chrono::microseconds t)
int64_t GetAdjustedTime()
void AddTimeData(const CNetAddr &ip, int64_t nOffsetSample)
arith_uint256 nMinimumChainWork
Minimum work we will assume exists on some valid chain.
CFeeRate minRelayTxFee
A fee rate smaller than this is considered zero fee (for relaying, mining and transaction creation)
CChain & ChainActive()
Please prefer the identical ChainstateManager::ActiveChain.
bool ReadRawBlockFromDisk(std::vector< uint8_t > &block, const FlatFilePos &pos, const CMessageHeader::MessageStartChars &message_start)
CChainState & ChainstateActive()
Please prefer the identical ChainstateManager::ActiveChainstate.
bool ReadBlockFromDisk(CBlock &block, const FlatFilePos &pos, const Consensus::Params &consensusParams)
Functions for disk access for blocks.
AssertLockHeld(mempool.cs)
CBlockIndex * LookupBlockIndex(const uint256 &hash)
bool fPruneMode
True if we're running in -prune mode.
bool ActivateBestChain(BlockValidationState &state, const CChainParams &chainparams, std::shared_ptr< const CBlock > pblock)
Find the best known block, and make it the tip of the block chain.
bool IsWitnessEnabled(const CBlockIndex *pindexPrev, const Consensus::Params ¶ms)
Check whether witness commitments are required for a block, and whether to enforce NULLDUMMY (BIP 147...
CBlockIndex * pindexBestHeader
Best header we've seen so far (used for getheaders queries' starting points).
CBlockIndex * FindForkInGlobalIndex(const CChain &chain, const CBlockLocator &locator)
Find the last common block between the parameter chain and a locator.
bool AcceptToMemoryPool(CTxMemPool &pool, TxValidationState &state, const CTransactionRef &tx, std::list< CTransactionRef > *plTxnReplaced, bool bypass_limits, bool test_accept, CAmount *fee_out)
(try to) add transaction to memory pool plTxnReplaced will be appended to with all transactions repla...
std::atomic_bool fReindex
std::atomic_bool fImporting
static const unsigned int MIN_BLOCKS_TO_KEEP
Block files containing a block-height within MIN_BLOCKS_TO_KEEP of ChainActive().Tip() will not be pr...
static const unsigned int DEFAULT_MIN_RELAY_TX_FEE
Default for -minrelaytxfee, minimum relay fee for transactions.
static const bool DEFAULT_FEEFILTER
Default for using fee filter.
static const int WTXID_RELAY_VERSION
"wtxidrelay" command for wtxid-based relay starts with this version
static const int INIT_PROTO_VERSION
initial proto version, to be increased after version/verack negotiation
static const int SHORT_IDS_BLOCKS_VERSION
short-id-based block download starts with this version
static const int SENDHEADERS_VERSION
"sendheaders" command and announcing blocks with headers starts with this version
static const int PROTOCOL_VERSION
network protocol versioning
static const int FEEFILTER_VERSION
"feefilter" tells peers to filter invs to you by fee starts with this version
static const int MIN_PEER_PROTO_VERSION
disconnect from peers older than this proto version
static const int INVALID_CB_NO_BAN_VERSION
not banning for invalid compact blocks starts with this version
static const int BIP0031_VERSION
BIP 0031, pong message, is enabled for all versions AFTER this one.