140 static constexpr
unsigned int AVG_FEEFILTER_BROADCAST_INTERVAL = 10 * 60;
142 static constexpr
unsigned int MAX_FEEFILTER_CHANGE_DELAY = 5 * 60;
144 static constexpr uint32_t MAX_GETCFILTERS_SIZE = 1000;
146 static constexpr uint32_t MAX_GETCFHEADERS_SIZE = 2000;
148 static constexpr
size_t MAX_PCT_ADDR_TO_SEND = 23;
162 std::map<uint256, COrphanTx> mapOrphanTransactions
GUARDED_BY(g_cs_orphans);
165 std::map<uint256, std::map<uint256, COrphanTx>::iterator> g_orphans_by_wtxid
GUARDED_BY(g_cs_orphans);
167 void EraseOrphansFor(
NodeId peer);
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);
273 std::vector<std::map<uint256, COrphanTx>::iterator> g_orphan_list
GUARDED_BY(g_cs_orphans);
278 static std::vector<std::pair<uint256, CTransactionRef>> vExtraTxnForCompact
GUARDED_BY(g_cs_orphans);
280 static size_t vExtraTxnForCompactIt
GUARDED_BY(g_cs_orphans) = 0;
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};
450 std::set<uint256> m_orphan_work_set
GUARDED_BY(g_cs_orphans);
453 Mutex m_getdata_requests_mutex;
455 std::deque<CInv> m_getdata_requests
GUARDED_BY(m_getdata_requests_mutex);
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);
795 void UpdateLastBlockAnnounceTime(
NodeId node, int64_t time_in_seconds)
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);
868 EraseOrphansFor(nodeid);
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);
958 AddToCompactExtraTransactions(tx);
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);
996 void EraseOrphansFor(
NodeId peer)
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)
1006 nErased += EraseOrphanTx(maybeErase->second.tx->GetHash());
1013 unsigned int LimitOrphanTxSize(
unsigned int nMaxOrphans)
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) {
1029 nErased += EraseOrphanTx(maybeErase->second.tx->GetHash());
1031 nMinExpTime = std::min(maybeErase->second.nTimeExpire, nMinExpTime);
1039 while (mapOrphanTransactions.size() > nMaxOrphans)
1042 size_t randompos = rng.
randrange(g_orphan_list.size());
1043 EraseOrphanTx(g_orphan_list[randompos]->first);
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});
1195 scheduler.
scheduleFromNow([&] { ReattemptInitialBroadcast(scheduler); }, delta);
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) {
1229 nErased += EraseOrphanTx(orphanHash);
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();
1270 static std::shared_ptr<const CBlock> most_recent_block
GUARDED_BY(cs_most_recent_block);
1271 static std::shared_ptr<const CBlockHeaderAndShortTxIDs> most_recent_compact_block
GUARDED_BY(cs_most_recent_block);
1273 static bool fWitnessesPresentInMostRecentCompactBlock
GUARDED_BY(cs_most_recent_block);
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());
1294 LOCK(cs_most_recent_block);
1295 most_recent_block_hash = hashBlock;
1296 most_recent_block = pblock;
1297 most_recent_compact_block = pcmpctblock;
1298 fWitnessesPresentInMostRecentCompactBlock = fWitnessEnabled;
1307 ProcessBlockAvailability(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",
1315 hashBlock.ToString(), pnode->
GetId());
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);
1439 if (state ==
nullptr)
return;
1440 if (state->m_wtxid_relay) {
1448 static void RelayAddress(
const CAddress& addr,
bool fReachable,
const CConnman& connman)
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;
1495 LOCK(cs_most_recent_block);
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) {
1527 send = BlockRequestAllowed(pindex, consensusParams);
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);
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();
1674 std::vector<CInv> vNotFound;
1677 const std::chrono::seconds now = GetTime<std::chrono::seconds>();
1679 const std::chrono::seconds mempool_req = pfrom.
m_tx_relay !=
nullptr ? pfrom.
m_tx_relay->m_last_mempool_req.load()
1680 : std::chrono::seconds::min();
1685 while (it != peer.m_getdata_requests.end() && it->IsGenTxMsg()) {
1686 if (interruptMsgProc)
return;
1691 const CInv &inv = *it++;
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) {
1727 vNotFound.push_back(inv);
1733 if (it != peer.m_getdata_requests.end() && !pfrom.
fPauseSend) {
1734 const CInv &inv = *it++;
1736 ProcessGetBlockData(pfrom, chainparams, inv, connman);
1742 peer.m_getdata_requests.erase(peer.m_getdata_requests.begin(),
it);
1744 if (!vNotFound.empty()) {
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;
1912 uint32_t nFetchFlags = GetFetchFlags(pfrom);
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);
2004 EraseOrphanTx(orphanHash);
2006 AddToCompactExtraTransactions(removedTx);
2013 orphan_it->second.fromPeer,
2035 assert(recentRejects);
2036 recentRejects->insert(porphanTx->GetWitnessHash());
2048 recentRejects->insert(porphanTx->GetHash());
2051 EraseOrphanTx(orphanHash);
2073 static bool PrepareBlockFilterRequest(
CNode& peer,
const CChainParams& chain_params,
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));
2094 if (!stop_index || !BlockRequestAllowed(stop_index, chain_params.
GetConsensus())) {
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;
2149 if (!PrepareBlockFilterRequest(peer, chain_params, filter_type, start_height, stop_hash,
2150 MAX_GETCFILTERS_SIZE, stop_index, filter_index)) {
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;
2191 if (!PrepareBlockFilterRequest(peer, chain_params, filter_type, start_height, stop_hash,
2192 MAX_GETCFHEADERS_SIZE, stop_index, filter_index)) {
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;
2245 if (!PrepareBlockFilterRequest(peer, chain_params, filter_type, 0, 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;
2331 vRecv >> addrFrom >> nNonce;
2332 if (!vRecv.
empty()) {
2333 std::string strSubVer;
2337 if (!vRecv.
empty()) {
2338 vRecv >> nStartingHeight;
2371 if (greatest_common_version >= 70016) {
2385 pfrom.cleanSubVer = cleanSubVer;
2409 UpdatePreferredDownload(pfrom,
State(pfrom.
GetId()));
2461 std::string remoteAddr;
2465 LogPrint(
BCLog::NET,
"receive version message: %s: version %d, blocks=%d, us=%s, peer=%d%s\n",
2470 int64_t nTimeOffset = nTime -
GetTime();
2475 if (greatest_common_version <= 70012) {
2476 CDataStream finalAlert(
ParseHex(
"60010000000000000000000000ffffff7f00000000ffffff7ffeffff7f01ffffff7f00000000ffffff7f00ffffff7f002f555247454e543a20416c657274206b657920636f6d70726f6d697365642c2075706772616465207265717569726564004630440220653febd6410f470f6bae11cad19c48413becb1ac2c17f908fd0fd53bdc3abd5202206d0e9c96fe88d4a0f01ed9dedae2b6f9e00da94cad0fecaae66ecf689bf71b50"),
SER_NETWORK,
PROTOCOL_VERSION);
2489 Misbehaving(pfrom.
GetId(), 1,
"non-version message before version handshake");
2502 State(pfrom.
GetId())->fCurrentlyConnected =
true;
2503 LogPrintf(
"New outbound peer connected: version: %d, blocks=%d, peer=%d%s (%s)\n",
2506 pfrom.
m_tx_relay ==
nullptr ?
"block-relay" :
"full-relay");
2522 bool fAnnounceUsingCMPCTBLOCK =
false;
2523 uint64_t nCMPCTBLOCKVersion = 2;
2526 nCMPCTBLOCKVersion = 1;
2546 g_wtxid_relay_peers++;
2577 std::vector<CAddress> vAddr;
2591 std::vector<CAddress> vAddrOk;
2593 int64_t nSince = nNow - 10 * 60;
2596 if (interruptMsgProc)
2605 if (addr.
nTime <= 100000000 || addr.
nTime > nNow + 10 * 60)
2606 addr.
nTime = nNow - 5 * 24 * 60 * 60;
2616 RelayAddress(addr, fReachable,
m_connman);
2620 vAddrOk.push_back(addr);
2623 if (vAddr.size() < 1000)
2637 bool fAnnounceUsingCMPCTBLOCK =
false;
2638 uint64_t nCMPCTBLOCKVersion = 0;
2639 vRecv >> fAnnounceUsingCMPCTBLOCK >> nCMPCTBLOCKVersion;
2643 if (!
State(pfrom.
GetId())->fProvidesHeaderAndIDs) {
2644 State(pfrom.
GetId())->fProvidesHeaderAndIDs =
true;
2645 State(pfrom.
GetId())->fWantsCmpctWitness = nCMPCTBLOCKVersion == 2;
2647 if (
State(pfrom.
GetId())->fWantsCmpctWitness == (nCMPCTBLOCKVersion == 2))
2648 State(pfrom.
GetId())->fPreferHeaderAndIDs = fAnnounceUsingCMPCTBLOCK;
2649 if (!
State(pfrom.
GetId())->fSupportsDesiredCmpctVersion) {
2651 State(pfrom.
GetId())->fSupportsDesiredCmpctVersion = (nCMPCTBLOCKVersion == 2);
2653 State(pfrom.
GetId())->fSupportsDesiredCmpctVersion = (nCMPCTBLOCKVersion == 1);
2660 std::vector<CInv> vInv;
2674 fBlocksOnly =
false;
2679 const auto current_time = GetTime<std::chrono::microseconds>();
2682 for (
CInv& inv : vInv) {
2683 if (interruptMsgProc)
return;
2695 const bool fAlreadyHave = AlreadyHaveBlock(inv.
hash);
2698 UpdateBlockAvailability(pfrom.
GetId(), inv.
hash);
2705 best_block = &inv.
hash;
2709 const bool fAlreadyHave = AlreadyHaveTx(gtxid,
m_mempool);
2718 AddTxAnnouncement(pfrom, gtxid, current_time);
2725 if (best_block !=
nullptr) {
2734 std::vector<CInv> vInv;
2744 if (vInv.size() > 0) {
2749 LOCK(peer->m_getdata_requests_mutex);
2750 peer->m_getdata_requests.insert(peer->m_getdata_requests.end(), vInv.begin(), vInv.end());
2760 vRecv >> locator >> hashStop;
2776 std::shared_ptr<const CBlock> a_recent_block;
2778 LOCK(cs_most_recent_block);
2779 a_recent_block = most_recent_block;
2796 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());
2829 std::shared_ptr<const CBlock> recent_block;
2831 LOCK(cs_most_recent_block);
2832 if (most_recent_block_hash == req.blockhash)
2833 recent_block = most_recent_block;
2870 inv.hash = req.blockhash;
2871 WITH_LOCK(peer->m_getdata_requests_mutex, peer->m_getdata_requests.push_back(inv));
2879 vRecv >> locator >> hashStop;
2889 LogPrint(
BCLog::NET,
"Ignoring getheaders from peer=%d because node is in initial block download\n", pfrom.
GetId());
2893 CNodeState *nodestate =
State(pfrom.
GetId());
2903 if (!BlockRequestAllowed(pindex,
m_chainparams.GetConsensus())) {
2904 LogPrint(
BCLog::NET,
"%s: ignoring request from peer=%i for old block header that isn't in the main chain\n", __func__, pfrom.
GetId());
2917 std::vector<CBlock> vHeaders;
2919 LogPrint(
BCLog::NET,
"getheaders %d to %s from peer=%d\n", (pindex ? pindex->nHeight : -1), hashStop.IsNull() ?
"end" : hashStop.ToString(), pfrom.
GetId());
2922 vHeaders.push_back(pindex->GetBlockHeader());
2923 if (--nLimit <= 0 || pindex->GetBlockHash() == hashStop)
2958 const uint256& txid = ptx->GetHash();
2959 const uint256& wtxid = ptx->GetWitnessHash();
2961 LOCK2(cs_main, g_cs_orphans);
2963 CNodeState* nodestate =
State(pfrom.
GetId());
2965 const uint256& hash = nodestate->m_wtxid_relay ? wtxid : txid;
2967 if (nodestate->m_wtxid_relay && txid != wtxid) {
2976 m_txrequest.ReceivedResponse(pfrom.
GetId(), txid);
2977 if (tx.
HasWitness()) m_txrequest.ReceivedResponse(pfrom.
GetId(), wtxid);
3007 std::list<CTransactionRef> lRemovedTxn;
3013 m_txrequest.ForgetTxHash(tx.
GetHash());
3016 for (
unsigned int i = 0; i < tx.
vout.size(); i++) {
3017 auto it_by_prev = mapOrphanTransactionsByPrev.find(
COutPoint(txid, i));
3018 if (it_by_prev != mapOrphanTransactionsByPrev.end()) {
3019 for (
const auto& elem : it_by_prev->second) {
3020 peer->m_orphan_work_set.insert(elem->first);
3033 AddToCompactExtraTransactions(removedTx);
3041 bool fRejectedParents =
false;
3045 std::vector<uint256> unique_parents;
3046 unique_parents.reserve(tx.
vin.size());
3051 std::sort(unique_parents.begin(), unique_parents.end());
3052 unique_parents.erase(std::unique(unique_parents.begin(), unique_parents.end()), unique_parents.end());
3053 for (
const uint256& parent_txid : unique_parents) {
3054 if (recentRejects->contains(parent_txid)) {
3055 fRejectedParents =
true;
3059 if (!fRejectedParents) {
3060 const auto current_time = GetTime<std::chrono::microseconds>();
3062 for (
const uint256& parent_txid : unique_parents) {
3068 const GenTxid gtxid{
false, parent_txid};
3070 if (!AlreadyHaveTx(gtxid,
m_mempool)) AddTxAnnouncement(pfrom, gtxid, current_time);
3072 AddOrphanTx(ptx, pfrom.
GetId());
3075 m_txrequest.ForgetTxHash(tx.
GetHash());
3080 unsigned int nEvicted = LimitOrphanTxSize(nMaxOrphanTx);
3092 recentRejects->insert(tx.
GetHash());
3094 m_txrequest.ForgetTxHash(tx.
GetHash());
3112 assert(recentRejects);
3124 recentRejects->insert(tx.
GetHash());
3125 m_txrequest.ForgetTxHash(tx.
GetHash());
3128 AddToCompactExtraTransactions(ptx);
3168 vRecv >> cmpctblock;
3170 bool received_new_header =
false;
3183 received_new_header =
true;
3200 bool fProcessBLOCKTXN =
false;
3205 bool fRevertToHeaderProcessing =
false;
3209 std::shared_ptr<CBlock> pblock = std::make_shared<CBlock>();
3210 bool fBlockReconstructed =
false;
3213 LOCK2(cs_main, g_cs_orphans);
3218 CNodeState *nodestate =
State(pfrom.
GetId());
3223 nodestate->m_last_block_announcement =
GetTime();
3226 std::map<uint256, std::pair<NodeId, std::list<QueuedBlock>::iterator> >::iterator blockInFlightIt = mapBlocksInFlight.find(pindex->
GetBlockHash());
3227 bool fAlreadyInFlight = blockInFlightIt != mapBlocksInFlight.end();
3234 if (fAlreadyInFlight) {
3237 std::vector<CInv> vInv(1);
3238 vInv[0] =
CInv(
MSG_BLOCK | GetFetchFlags(pfrom), cmpctblock.header.GetHash());
3245 if (!fAlreadyInFlight && !CanDirectFetch(
m_chainparams.GetConsensus()))
3258 (fAlreadyInFlight && blockInFlightIt->second.first == pfrom.
GetId())) {
3259 std::list<QueuedBlock>::iterator* queuedBlockIt =
nullptr;
3261 if (!(*queuedBlockIt)->partialBlock)
3262 (*queuedBlockIt)->partialBlock.reset(
new PartiallyDownloadedBlock(&
m_mempool));
3270 PartiallyDownloadedBlock& partialBlock = *(*queuedBlockIt)->partialBlock;
3278 std::vector<CInv> vInv(1);
3279 vInv[0] =
CInv(
MSG_BLOCK | GetFetchFlags(pfrom), cmpctblock.header.GetHash());
3285 for (
size_t i = 0; i < cmpctblock.BlockTxCount(); i++) {
3292 txn.
blockhash = cmpctblock.header.GetHash();
3294 fProcessBLOCKTXN =
true;
3305 PartiallyDownloadedBlock tempBlock(&
m_mempool);
3306 ReadStatus status = tempBlock.InitData(cmpctblock, vExtraTxnForCompact);
3311 std::vector<CTransactionRef> dummy;
3312 status = tempBlock.FillBlock(*pblock, dummy);
3314 fBlockReconstructed =
true;
3318 if (fAlreadyInFlight) {
3321 std::vector<CInv> vInv(1);
3322 vInv[0] =
CInv(
MSG_BLOCK | GetFetchFlags(pfrom), cmpctblock.header.GetHash());
3327 fRevertToHeaderProcessing =
true;
3332 if (fProcessBLOCKTXN) {
3336 if (fRevertToHeaderProcessing) {
3345 if (fBlockReconstructed) {
3350 mapBlockSource.emplace(pblock->GetHash(), std::make_pair(pfrom.
GetId(),
false));
3352 bool fNewBlock =
false;
3367 mapBlockSource.erase(pblock->GetHash());
3375 MarkBlockAsReceived(pblock->GetHash());
3392 std::shared_ptr<CBlock> pblock = std::make_shared<CBlock>();
3393 bool fBlockRead =
false;
3397 std::map<uint256, std::pair<NodeId, std::list<QueuedBlock>::iterator> >::iterator it = mapBlocksInFlight.find(resp.blockhash);
3398 if (it == mapBlocksInFlight.end() || !it->second.second->partialBlock ||
3399 it->second.first != pfrom.
GetId()) {
3404 PartiallyDownloadedBlock& partialBlock = *it->second.second->partialBlock;
3407 MarkBlockAsReceived(resp.blockhash);
3408 Misbehaving(pfrom.
GetId(), 100,
"invalid compact block/non-matching block transactions");
3412 std::vector<CInv> invs;
3413 invs.push_back(
CInv(
MSG_BLOCK | GetFetchFlags(pfrom), resp.blockhash));
3433 MarkBlockAsReceived(resp.blockhash);
3441 mapBlockSource.emplace(resp.blockhash, std::make_pair(pfrom.
GetId(),
false));
3445 bool fNewBlock =
false;
3457 mapBlockSource.erase(pblock->GetHash());
3471 std::vector<CBlockHeader> headers;
3479 headers.resize(nCount);
3480 for (
unsigned int n = 0; n < nCount; n++) {
3481 vRecv >> headers[n];
3496 std::shared_ptr<CBlock> pblock = std::make_shared<CBlock>();
3501 bool forceProcessing =
false;
3502 const uint256 hash(pblock->GetHash());
3507 forceProcessing |= MarkBlockAsReceived(hash);
3511 mapBlockSource.emplace(hash, std::make_pair(pfrom.
GetId(),
true));
3513 bool fNewBlock =
false;
3519 mapBlockSource.erase(pblock->GetHash());
3544 std::vector<CAddress> vAddr;
3551 for (
const CAddress &addr : vAddr) {
3606 const auto ping_end = time_received;
3609 bool bPingFinished =
false;
3610 std::string sProblem;
3612 if (nAvail >=
sizeof(nonce)) {
3619 bPingFinished =
true;
3620 const auto ping_time = ping_end - pfrom.
m_ping_start.load();
3621 if (ping_time.count() >= 0) {
3627 sProblem =
"Timing mishap";
3631 sProblem =
"Nonce mismatch";
3634 bPingFinished =
true;
3635 sProblem =
"Nonce zero";
3639 sProblem =
"Unsolicited pong without ping";
3643 bPingFinished =
true;
3644 sProblem =
"Short payload";
3647 if (!(sProblem.empty())) {
3655 if (bPingFinished) {
3669 if (!filter.IsWithinSizeConstraints())
3688 std::vector<unsigned char> vData;
3726 vRecv >> newFeeFilter;
3730 pfrom.
m_tx_relay->minFeeFilter = newFeeFilter;
3753 std::vector<CInv> vInv;
3757 for (
CInv &inv : vInv) {
3758 if (inv.IsGenTxMsg()) {
3761 m_txrequest.ReceivedResponse(pfrom.
GetId(), inv.hash);
3776 PeerRef peer = GetPeerRef(peer_id);
3777 if (peer ==
nullptr)
return false;
3780 LOCK(peer->m_misbehavior_mutex);
3783 if (!peer->m_should_discourage)
return false;
3785 peer->m_should_discourage =
false;
3790 LogPrintf(
"Warning: not punishing noban peer %d!\n", peer_id);
3796 LogPrintf(
"Warning: not punishing manually connected peer %d!\n", peer_id);
3803 LogPrintf(
"Warning: disconnecting but not discouraging local peer %d!\n", peer_id);
3809 LogPrintf(
"Disconnecting and discouraging peer %d!\n", peer_id);
3817 bool fMoreWork =
false;
3819 PeerRef peer = GetPeerRef(pfrom->
GetId());
3820 if (peer ==
nullptr)
return false;
3823 LOCK(peer->m_getdata_requests_mutex);
3824 if (!peer->m_getdata_requests.empty()) {
3830 LOCK2(cs_main, g_cs_orphans);
3831 if (!peer->m_orphan_work_set.empty()) {
3842 LOCK(peer->m_getdata_requests_mutex);
3843 if (!peer->m_getdata_requests.empty())
return true;
3848 if (!peer->m_orphan_work_set.empty())
return true;
3855 std::list<CNetMessage> msgs;
3858 if (pfrom->vProcessMsg.empty())
3861 msgs.splice(msgs.begin(), pfrom->vProcessMsg, pfrom->vProcessMsg.begin());
3864 fMoreWork = !pfrom->vProcessMsg.empty();
3869 const std::string& msg_type = msg.m_command;
3872 unsigned int nMessageSize = msg.m_message_size;
3875 ProcessMessage(*pfrom, msg_type, msg.m_recv, msg.m_time, interruptMsgProc);
3876 if (interruptMsgProc)
return false;
3878 LOCK(peer->m_getdata_requests_mutex);
3879 if (!peer->m_getdata_requests.empty()) fMoreWork =
true;
3881 }
catch (
const std::exception& e) {
3904 if (state.pindexBestKnownBlock !=
nullptr && state.pindexBestKnownBlock->nChainWork >= ::
ChainActive().
Tip()->
nChainWork) {
3905 if (state.m_chain_sync.m_timeout != 0) {
3906 state.m_chain_sync.m_timeout = 0;
3907 state.m_chain_sync.m_work_header =
nullptr;
3908 state.m_chain_sync.m_sent_getheaders =
false;
3910 }
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)) {
3917 state.m_chain_sync.m_sent_getheaders =
false;
3918 }
else if (state.m_chain_sync.m_timeout > 0 && time_in_seconds > state.m_chain_sync.m_timeout) {
3922 if (state.m_chain_sync.m_sent_getheaders) {
3924 LogPrintf(
"Disconnecting outbound peer %d for old chain, best known block = %s\n", pto.
GetId(), state.pindexBestKnownBlock !=
nullptr ? state.pindexBestKnownBlock->GetBlockHash().ToString() :
"<none>");
3927 assert(state.m_chain_sync.m_work_header);
3928 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());
3930 state.m_chain_sync.m_sent_getheaders =
true;
3931 constexpr int64_t HEADERS_RESPONSE_TIME = 120;
3937 state.m_chain_sync.m_timeout = time_in_seconds + HEADERS_RESPONSE_TIME;
3947 if (extra_peers > 0) {
3953 int64_t oldest_block_announcement = std::numeric_limits<int64_t>::max();
3961 if (state ==
nullptr)
return;
3963 if (state->m_chain_sync.m_protect)
return;
3966 if (state->m_last_block_announcement < oldest_block_announcement || (state->m_last_block_announcement == oldest_block_announcement && pnode->
GetId() > worst_peer)) {
3967 worst_peer = pnode->
GetId();
3968 oldest_block_announcement = state->m_last_block_announcement;
3971 if (worst_peer != -1) {
3982 LogPrint(
BCLog::NET,
"disconnecting extra outbound peer=%d (last block announcement received at time %d)\n", pnode->
GetId(), oldest_block_announcement);
4006 int64_t time_in_seconds =
GetTime();
4014 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);
4024 class CompareInvMempoolOrder
4029 explicit CompareInvMempoolOrder(
CTxMemPool *_mempool,
bool use_wtxid)
4032 m_wtxid_relay = use_wtxid;
4035 bool operator()(std::set<uint256>::iterator a, std::set<uint256>::iterator b)
4062 bool pingSend =
false;
4073 while (nonce == 0) {
4077 pto->
m_ping_start = GetTime<std::chrono::microseconds>();
4094 auto current_time = GetTime<std::chrono::microseconds>();
4106 std::vector<CAddress> vAddr;
4110 const char* msg_type;
4125 vAddr.push_back(addr);
4145 bool fFetch = state.fPreferredDownload || (nPreferredDownload == 0 && !pto->
fClient && !pto->
IsAddrFetchConn());
4149 state.fSyncStarted =
true;
4160 if (pindexStart->
pprev)
4161 pindexStart = pindexStart->
pprev;
4179 std::vector<CBlock> vHeaders;
4180 bool fRevertToInv = ((!state.fPreferHeaders &&
4181 (!state.fPreferHeaderAndIDs || pto->vBlockHashesToAnnounce.size() > 1)) ||
4184 ProcessBlockAvailability(pto->
GetId());
4186 if (!fRevertToInv) {
4187 bool fFoundStartingHeader =
false;
4191 for (
const uint256 &hash : pto->vBlockHashesToAnnounce) {
4196 fRevertToInv =
true;
4199 if (pBestIndex !=
nullptr && pindex->
pprev != pBestIndex) {
4211 fRevertToInv =
true;
4214 pBestIndex = pindex;
4215 if (fFoundStartingHeader) {
4218 }
else if (PeerHasHeader(&state, pindex)) {
4220 }
else if (pindex->
pprev ==
nullptr || PeerHasHeader(&state, pindex->
pprev)) {
4223 fFoundStartingHeader =
true;
4228 fRevertToInv =
true;
4233 if (!fRevertToInv && !vHeaders.empty()) {
4234 if (vHeaders.size() == 1 && state.fPreferHeaderAndIDs) {
4238 vHeaders.front().GetHash().ToString(), pto->
GetId());
4242 bool fGotBlockFromCache =
false;
4244 LOCK(cs_most_recent_block);
4245 if (most_recent_block_hash == pBestIndex->
GetBlockHash()) {
4246 if (state.fWantsCmpctWitness || !fWitnessesPresentInMostRecentCompactBlock)
4252 fGotBlockFromCache =
true;
4255 if (!fGotBlockFromCache) {
4262 state.pindexBestHeaderSent = pBestIndex;
4263 }
else if (state.fPreferHeaders) {
4264 if (vHeaders.size() > 1) {
4267 vHeaders.front().GetHash().ToString(),
4268 vHeaders.back().GetHash().ToString(), pto->
GetId());
4271 vHeaders.front().GetHash().ToString(), pto->
GetId());
4274 state.pindexBestHeaderSent = pBestIndex;
4276 fRevertToInv =
true;
4282 if (!pto->vBlockHashesToAnnounce.empty()) {
4283 const uint256 &hashToAnnounce = pto->vBlockHashesToAnnounce.back();
4296 if (!PeerHasHeader(&state, pindex)) {
4297 pto->vInventoryBlockToSend.push_back(hashToAnnounce);
4303 pto->vBlockHashesToAnnounce.clear();
4309 std::vector<CInv> vInv;
4315 for (
const uint256& hash : pto->vInventoryBlockToSend) {
4322 pto->vInventoryBlockToSend.clear();
4328 if (pto->
m_tx_relay->nNextInvSend < current_time) {
4329 fSendTrickle =
true;
4345 if (fSendTrickle && pto->
m_tx_relay->fSendMempool) {
4356 for (
const auto& txinfo : vtxinfo) {
4357 const uint256& hash = state.m_wtxid_relay ? txinfo.tx->GetWitnessHash() : txinfo.tx->GetHash();
4359 pto->
m_tx_relay->setInventoryTxToSend.erase(hash);
4361 if (txinfo.fee < filterrate.
GetFee(txinfo.vsize)) {
4365 if (!pto->
m_tx_relay->pfilter->IsRelevantAndUpdate(*txinfo.tx))
continue;
4367 pto->
m_tx_relay->filterInventoryKnown.insert(hash);
4369 vInv.push_back(inv);
4375 pto->
m_tx_relay->m_last_mempool_req = GetTime<std::chrono::seconds>();
4381 std::vector<std::set<uint256>::iterator> vInvTx;
4382 vInvTx.reserve(pto->
m_tx_relay->setInventoryTxToSend.size());
4383 for (std::set<uint256>::iterator it = pto->
m_tx_relay->setInventoryTxToSend.begin(); it != pto->
m_tx_relay->setInventoryTxToSend.end(); it++) {
4384 vInvTx.push_back(it);
4393 CompareInvMempoolOrder compareInvMempoolOrder(&
m_mempool, state.m_wtxid_relay);
4394 std::make_heap(vInvTx.begin(), vInvTx.end(), compareInvMempoolOrder);
4397 unsigned int nRelayedTransactions = 0;
4401 std::pop_heap(vInvTx.begin(), vInvTx.end(), compareInvMempoolOrder);
4402 std::set<uint256>::iterator it = vInvTx.back();
4407 pto->
m_tx_relay->setInventoryTxToSend.erase(it);
4409 if (pto->
m_tx_relay->filterInventoryKnown.contains(hash)) {
4417 auto txid = txinfo.tx->GetHash();
4418 auto wtxid = txinfo.tx->GetWitnessHash();
4420 if (txinfo.fee < filterrate.
GetFee(txinfo.vsize)) {
4423 if (pto->
m_tx_relay->pfilter && !pto->
m_tx_relay->pfilter->IsRelevantAndUpdate(*txinfo.tx))
continue;
4426 vInv.push_back(inv);
4427 nRelayedTransactions++;
4430 while (!vRelayExpiration.empty() && vRelayExpiration.front().first <
count_microseconds(current_time))
4432 mapRelay.erase(vRelayExpiration.front().second);
4433 vRelayExpiration.pop_front();
4436 auto ret = mapRelay.emplace(txid, std::move(txinfo.tx));
4441 auto ret2 = mapRelay.emplace(wtxid, ret.first->second);
4450 pto->
m_tx_relay->filterInventoryKnown.insert(hash);
4457 pto->
m_tx_relay->filterInventoryKnown.insert(txid);
4467 current_time = GetTime<std::chrono::microseconds>();
4472 LogPrintf(
"Peer=%d is stalling block download, disconnecting\n", pto->
GetId());
4481 if (state.vBlocksInFlight.size() > 0) {
4482 QueuedBlock &queuedBlock = state.vBlocksInFlight.front();
4483 int nOtherPeersWithValidatedDownloads = nPeersWithValidatedDownloads - (state.nBlocksInFlightValidHeaders > 0);
4485 LogPrintf(
"Timeout downloading block %s from peer=%d, disconnecting\n", queuedBlock.hash.ToString(), pto->
GetId());
4491 if (state.fSyncStarted && state.nHeadersSyncTimeout < std::numeric_limits<int64_t>::max()) {
4494 if (
count_microseconds(current_time) > state.nHeadersSyncTimeout && nSyncStarted == 1 && (nPreferredDownload - state.fPreferredDownload >= 1)) {
4501 LogPrintf(
"Timeout downloading headers from peer=%d, disconnecting\n", pto->
GetId());
4505 LogPrintf(
"Timeout downloading headers from noban peer=%d, not disconnecting\n", pto->
GetId());
4511 state.fSyncStarted =
false;
4513 state.nHeadersSyncTimeout = 0;
4519 state.nHeadersSyncTimeout = std::numeric_limits<int64_t>::max();
4530 std::vector<CInv> vGetData;
4532 std::vector<const CBlockIndex*> vToDownload;
4536 uint32_t nFetchFlags = GetFetchFlags(*pto);
4542 if (state.nBlocksInFlight == 0 && staller != -1) {
4543 if (
State(staller)->nStallingSince == 0) {
4553 std::vector<std::pair<NodeId, GenTxid>> expired;
4554 auto requestable = m_txrequest.GetRequestable(pto->
GetId(), current_time, &expired);
4555 for (
const auto& entry : expired) {
4556 LogPrint(
BCLog::NET,
"timeout of inflight %s %s from peer=%d\n", entry.second.IsWtxid() ?
"wtx" :
"tx",
4557 entry.second.GetHash().ToString(), entry.first);
4559 for (
const GenTxid& gtxid : requestable) {
4572 m_txrequest.ForgetTxHash(gtxid.
GetHash());
4577 if (!vGetData.empty())
4594 if (pto->
m_tx_relay->lastSentFeeFilter == MAX_FILTER) {
4601 CAmount filterToSend = g_filter_rounder.round(currentFilter);
4604 if (filterToSend != pto->
m_tx_relay->lastSentFeeFilter) {
4606 pto->
m_tx_relay->lastSentFeeFilter = filterToSend;
4613 (currentFilter < 3 * pto->m_tx_relay->lastSentFeeFilter / 4 || currentFilter > 4 * pto->
m_tx_relay->lastSentFeeFilter / 3)) {
4621 class CNetProcessingCleanup
4624 CNetProcessingCleanup() {}
4625 ~CNetProcessingCleanup() {
4627 mapOrphanTransactions.clear();
4628 mapOrphanTransactionsByPrev.clear();
4629 g_orphans_by_wtxid.clear();
4632 static CNetProcessingCleanup instance_of_cnetprocessingcleanup;
std::shared_ptr< const CTransaction > CTransactionRef
static constexpr unsigned int INVENTORY_BROADCAST_PER_SECOND
Maximum rate of inventory items to send per second.
const char * GETCFILTERS
getcfilters requests compact filters for a range of blocks.
arith_uint256 nChainWork
(memory only) Total amount of work (expected number of hashes) in the chain up to and including this ...
static int64_t GetTransactionWeight(const CTransaction &tx)
bool SendMessages(CNode *pto) override EXCLUSIVE_LOCKS_REQUIRED(pto-> cs_sendProcessing)
Send queued protocol messages to be sent to a give node.
static constexpr int64_t MINIMUM_CONNECT_TIME
Minimum time an outbound-peer-eviction candidate must be connected for, in order to evict...
static constexpr std::chrono::microseconds GETDATA_TX_INTERVAL
How long to wait (in microseconds) before downloading a transaction from an additional peer...
CAmount GetFeePerK() const
Return the fee in satoshis for a size of 1000 bytes.
std::string SanitizeString(const std::string &str, int rule)
Remove unsafe chars.
enum ReadStatus_t ReadStatus
const char * PING
The ping message is sent periodically to help confirm that the receiving peer is still connected...
static constexpr auto TXID_RELAY_DELAY
How long to delay requesting transactions via txids, if we have wtxid-relaying peers.
CFeeRate GetMinFee(size_t sizelimit) const
The minimum fee to get into the mempool, which may itself not be enough for larger-sized transactions...
bool MaybeDiscourageAndDisconnect(CNode &pnode)
Maybe disconnect a peer and discourage future connections from its address.
std::atomic< uint64_t > nPingNonceSent
BlockFilterIndex is used to store and retrieve block filters, hashes, and headers for a range of bloc...
bool HasPermission(NetPermissionFlags permission) const
bool IsReachable(enum Network net)
const char * FILTERLOAD
The filterload message tells the receiving peer to filter all relayed transactions and requested merk...
const char * MERKLEBLOCK
The merkleblock message is a reply to a getdata message which requested a block using the inventory t...
std::atomic_bool fPauseSend
uint64_t GetRand(uint64_t nMax) noexcept
Generate a uniform random integer in the range [0..range).
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...
invalid by consensus rules
int GetCommonVersion() const
Optional< txiter > GetIter(const uint256 &txid) const EXCLUSIVE_LOCKS_REQUIRED(cs)
Returns an iterator to the given hash, if found.
const char * BLOCKTXN
Contains a BlockTransactions.
bool fPruneMode
True if we're running in -prune mode.
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 constexpr unsigned int INVENTORY_BROADCAST_MAX
Maximum number of inventory items to send per transmission.
uint64_t GetLocalNonce() const
int64_t m_stale_tip_check_time
Next time to check for stale tip.
static const int MAX_BLOCKTXN_DEPTH
Maximum depth of blocks we're willing to respond to GETBLOCKTXN requests for.
void Discourage(const CNetAddr &net_addr)
const char * SENDADDRV2
The sendaddrv2 message signals support for receiving ADDRV2 messages (BIP155).
bool contains(const std::vector< unsigned char > &vKey) const
ReadStatus FillBlock(CBlock &block, const std::vector< CTransactionRef > &vtx_missing)
ServiceFlags
nServices flags
#define LogPrint(category,...)
unsigned int GetReceiveFloodSize() const
Describes a place in the block chain to another node such that if the other node doesn't have the sam...
void InitializeNode(CNode *pnode) override
Initialize a peer by adding it to mapNodeState and pushing a message requesting its version...
CBlockIndex * pprev
pointer to the index of the predecessor of this block
bool ProcessNewBlock(const CChainParams &chainparams, const std::shared_ptr< const CBlock > pblock, bool fForceProcessing, bool *fNewBlock) LOCKS_EXCLUDED(cs_main)
Process an incoming block.
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 ...
uint32_t nStatus
Verification status of this block. See enum BlockStatus.
void scheduleEvery(Function f, std::chrono::milliseconds delta)
Repeat f until the scheduler is stopped.
void SetIP(const CNetAddr &ip)
void WakeMessageHandler()
void SetServices(const CService &addr, ServiceFlags nServices)
bool GetBoolArg(const std::string &strArg, bool fDefault) const
Return boolean argument or default value.
We don't have the previous block the checked one is built on.
CChain & ChainActive()
Please prefer the identical ChainstateManager::ActiveChain.
void PushTxInventory(const uint256 &hash)
const char * GETADDR
The getaddr message requests an addr message from the receiving node, preferably one with lots of IP ...
uint64_t ReadCompactSize(Stream &is, bool range_check=true)
Decode a CompactSize-encoded variable-length integer.
static const unsigned int DEFAULT_MAX_MEMPOOL_SIZE
Default for -maxmempool, maximum megabytes of mempool memory usage.
static const CAmount MAX_MONEY
No amount larger than this (in satoshi) is valid.
bool SeenLocal(const CService &addr)
Provides an interface for creating and interacting with one or two chainstates: an IBD chainstate gen...
std::vector< uint16_t > indexes
int64_t count_microseconds(std::chrono::microseconds t)
bool IsMsgWitnessBlk() const
void ProcessOrphanTx(std::set< uint256 > &orphan_work_set) EXCLUSIVE_LOCKS_REQUIRED(cs_main
void insert(const std::vector< unsigned char > &vKey)
std::vector< CAddress > GetAddresses(size_t max_addresses, size_t max_pct)
reverse_range< T > reverse_iterate(T &x)
bool ReadRawBlockFromDisk(std::vector< uint8_t > &block, const FlatFilePos &pos, const CMessageHeader::MessageStartChars &message_start)
static void LogPrintf(const char *fmt, const Args &...args)
invalid proof of work or time too old
bool ReadBlockFromDisk(CBlock &block, const FlatFilePos &pos, const Consensus::Params &consensusParams)
Functions for disk access for blocks.
const char * SENDCMPCT
Contains a 1-byte bool and 8-byte LE version number.
BlockFilterIndex * GetBlockFilterIndex(BlockFilterType filter_type)
Get a block filter index by type.
static constexpr int STALE_RELAY_AGE_LIMIT
Age after which a stale block will no longer be served if requested as protection against fingerprint...
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...
constexpr auto GetRandMillis
const CBlockIndex * LastCommonAncestor(const CBlockIndex *pa, const CBlockIndex *pb)
Find the last common ancestor two blocks have.
transaction was missing some of its inputs
All parent headers found, difficulty matches, timestamp >= median previous, checkpoint.
bool MoneyRange(const CAmount &nValue)
bool exists(const GenTxid >xid) const
std::vector< unsigned char > ParseHex(const char *psz)
const Consensus::Params & GetConsensus() const
std::atomic_bool m_wants_addrv2
Whether the peer has signaled support for receiving ADDRv2 (BIP155) messages, implying a preference t...
BloomFilter is a probabilistic filter which SPV clients provide so that we can filter the transaction...
bool GetTryNewOutboundPeer()
const char * CFHEADERS
cfheaders is a response to a getcfheaders request containing a filter header and a vector of filter h...
Only first tx is coinbase, 2 <= coinbase input script length <= 100, transactions valid...
void SetCommonVersion(int greatest_common_version)
void ReattemptInitialBroadcast(CScheduler &scheduler) const
Retrieve unbroadcast transactions from the mempool and reattempt sending to peers.
static const int BIP0031_VERSION
BIP 0031, pong message, is enabled for all versions AFTER this one.
void PushMessage(CNode *pnode, CSerializedNetMsg &&msg)
CTransactionRef get(const uint256 &hash) const
RecursiveMutex cs_vProcessMsg
arith_uint256 nMinimumChainWork
Minimum work we will assume exists on some valid chain.
bool IsInitialBlockDownload() const
Check whether we are doing an initial block download (synchronizing from disk or network) ...
RecursiveMutex g_cs_orphans
bool CompareDepthAndScore(const uint256 &hasha, const uint256 &hashb, bool wtxid=false)
void SetServiceFlagsIBDCache(bool state)
Set the current IBD status in order to figure out the desirable service flags.
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...
RollingBloomFilter is a probabilistic "keep track of most recently inserted" set. ...
void ProcessHeadersMessage(CNode &pfrom, const std::vector< CBlockHeader > &headers, bool via_compact_block)
Process a single headers message from a peer.
static const int SENDHEADERS_VERSION
"sendheaders" command and announcing blocks with headers starts with this version ...
CChainParams defines various tweakable parameters of a given instance of the Bitcoin system...
void AdvertiseLocal(CNode *pnode)
size_t DynamicMemoryUsage() const
violated mempool's fee/size/descendant/RBF/etc limits
static constexpr auto NONPREF_PEER_TX_DELAY
How long to delay requesting transactions from non-preferred peers.
PeerManager(const CChainParams &chainparams, CConnman &connman, BanMan *banman, CScheduler &scheduler, ChainstateManager &chainman, CTxMemPool &pool)
Double ended buffer combining vector and stream-like interfaces.
inputs (covered by txid) failed policy rules
void SetTryNewOutboundPeer(bool flag)
const uint32_t MSG_WITNESS_FLAG
getdata message type flags
bool IsMsgCmpctBlk() const
std::vector< CAddress > vAddrToSend
void GetRandBytes(unsigned char *buf, int num) noexcept
Overall design of the RNG and entropy sources.
transaction spends a coinbase too early, or violates locktime/sequence locks
bool IsBlockOnlyConn() const
std::atomic< int > nStartingHeight
bool IsFeelerConn() const
const char * CFILTER
cfilter is a response to a getcfilters request containing a single compact filter.
static const unsigned int MAX_SCRIPT_ELEMENT_SIZE
void PushAddress(const CAddress &_addr, FastRandomContext &insecure_rand)
const char * PONG
The pong message replies to a ping message, proving to the pinging node that the ponging node is stil...
State
The various states a (txhash,peer) pair can be in.
static constexpr std::chrono::seconds RELAY_TX_CACHE_TIME
How long to cache transactions in mapRelay for normal relay.
initial value. Tx has not yet been rejected
const char * WTXIDRELAY
Indicates that a node prefers to relay transactions via wtxid, rather than txid.
const char * HEADERS
The headers message sends one or more block headers to a node which previously requested certain head...
const char * GETCFCHECKPT
getcfcheckpt requests evenly spaced compact filter headers, enabling parallelized download and valida...
std::atomic< ServiceFlags > nServices
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...
const std::vector< CTxIn > vin
void SetAddrLocal(const CService &addrLocalIn)
May not be called more than once.
std::vector< TxMempoolInfo > infoAll() const
const char * INV
The inv message (inventory message) transmits one or more inventories of objects known to the transmi...
bool ForNode(NodeId id, std::function< bool(CNode *pnode)> func)
std::string ToString() const
CTxMemPoolEntry stores data about the corresponding transaction, as well as data about all in-mempool...
bool DisconnectNode(const std::string &node)
bool RelayAddrsWithConn() const
int64_t CAmount
Amount in satoshis (Can be negative)
static constexpr int ADDRV2_FORMAT
A flag that is ORed into the protocol version to designate that addresses should be serialized in (un...
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...
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...
bool IsDiscouraged(const CNetAddr &net_addr)
Return whether net_addr is discouraged.
void CheckForStaleTipAndEvictPeers()
Evict extra outbound peers.
std::atomic< int64_t > nPingUsecTime
std::string ToString(const T &t)
Locale-independent version of std::to_string.
bool IsArgSet(const std::string &strArg) const
Return true if the given argument has been manually set.
CBlockIndex * Tip() const
Returns the index entry for the tip of this chain, or nullptr if none.
bool GetNodeStateStats(NodeId nodeid, CNodeStateStats &stats)
Get statistics from node state.
bool IsAddrFetchConn() const
std::atomic< int64_t > nMinPingUsecTime
GenTxid ToGenTxid(const CInv &inv)
Convert a TX/WITNESS_TX/WTX CInv to a GenTxid.
initial value. Block has not yet been rejected
static constexpr int64_t EXTRA_PEER_CHECK_INTERVAL
How frequently to check for extra outbound peers and disconnect, in seconds.
Outputs do not overspend inputs, no double spends, coinbase output ok, no immature coinbase spends...
void BlockConnected(const std::shared_ptr< const CBlock > &pblock, const CBlockIndex *pindexConnected) override
Overridden from CValidationInterface.
bool GetUseAddrmanOutgoing() const
int Height() const
Return the maximal height in the chain.
std::set< CTxMemPoolEntryRef, CompareIteratorByHash > Parents
void FinalizeNode(const CNode &node, bool &fUpdateConnectionTime) override
Handle removal of a peer by updating various state and removing it from mapNodeState.
Used to relay blocks as header + vector to filtered nodes.
const char * GETHEADERS
The getheaders message requests a headers message that provides block headers starting from a particu...
bool IsInboundConn() const
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...
Invalid by a change to consensus rules more recent than SegWit.
std::unique_ptr< CRollingBloomFilter > m_addr_known
static constexpr int64_t ORPHAN_TX_EXPIRE_TIME
Expiration time for orphan transactions in seconds.
void UpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload) override
Overridden from CValidationInterface.
Scripts & signatures ok. Implies all parents are also at least SCRIPTS.
CBlockHeader GetBlockHeader() const
Transaction might have a witness prior to SegWit activation, or witness may have been malleated (whic...
bool IsFullOutboundConn() const
CFeeRate minRelayTxFee
A fee rate smaller than this is considered zero fee (for relaying, mining and transaction creation) ...
CBlockIndex * pindexBestHeader
Best header we've seen so far (used for getheaders queries' starting points).
void BlockDisconnected(const std::shared_ptr< const CBlock > &block, const CBlockIndex *pindex) override
Notifies listeners of a block being disconnected.
this block was cached as being invalid and we didn't store the reason why
An input of a transaction.
static const unsigned int NODE_NETWORK_LIMITED_MIN_BLOCKS
Minimum blocks required to signal NODE_NETWORK_LIMITED.
static bool HasAllDesirableServiceFlags(ServiceFlags services)
A shortcut for (services & GetDesirableServiceFlags(services)) == GetDesirableServiceFlags(services)...
TxMempoolInfo info(const uint256 &hash) const
static constexpr std::chrono::minutes PING_INTERVAL
Time between pings automatically sent out for latency probing and keepalive.
const char * ADDRV2
The addrv2 message relays connection information for peers on the network just like the addr message...
bool IsPeerAddrLocalGood(CNode *pnode)
the block failed to meet one of our checkpoints
static const int INIT_PROTO_VERSION
initial proto version, to be increased after version/verack negotiation
CChainState & ActiveChainstate() const
The most-work chain.
bool IsTxAvailable(size_t index) const
AssertLockHeld(mempool.cs)
A combination of a network address (CNetAddr) and a (TCP) port.
Transport protocol agnostic message container.
bool ProcessMessages(CNode *pfrom, std::atomic< bool > &interrupt) override
Process protocol messages received from a given node.
static constexpr unsigned int INVENTORY_MAX_RECENT_RELAY
The number of most recently announced transactions a peer can request.
int64_t PoissonNextSendInbound(int64_t now, int average_interval_seconds)
Attempts to obfuscate tx time through exponentially distributed emitting.
bool OutboundTargetReached(bool historicalBlockServingLimit)
check if the outbound target is reached if param historicalBlockServingLimit is set true...
int64_t nPowTargetSpacing
static constexpr int64_t HEADERS_DOWNLOAD_TIMEOUT_BASE
Headers download timeout expressed in microseconds Timeout = base + per_header * (expected number of ...
const char * SENDHEADERS
Indicates that a node prefers to receive new block announcements via a "headers" message rather than ...
static constexpr int64_t HEADERS_DOWNLOAD_TIMEOUT_PER_HEADER
const char * MEMPOOL
The mempool message requests the TXIDs of transactions that the receiving node has verified as valid ...
static const unsigned int DEFAULT_MIN_RELAY_TX_FEE
Default for -minrelaytxfee, minimum relay fee for transactions.
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.
static const unsigned int MAX_HEADERS_RESULTS
Number of headers sent in one getheaders result.
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...
static const int SHORT_IDS_BLOCKS_VERSION
short-id-based block download starts with this version
void ForEachNodeThen(Callable &&pre, CallableAfter &&post)
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate...
uint64_t Finalize() const
Compute the 64-bit SipHash-2-4 of the data written so far.
bool IsProxy(const CNetAddr &addr)
static constexpr int64_t CHAIN_SYNC_TIMEOUT
Timeout for (unprotected) outbound peers to sync to our chainwork, in seconds.
const std::vector< CTxOut > vout
A CService with information about it as peer.
static const int64_t BLOCK_DOWNLOAD_TIMEOUT_PER_PEER
Additional block download timeout per parallel downloading peer (i.e.
std::string ToString() const
static constexpr uint64_t RANDOMIZER_ID_ADDRESS_RELAY
SHA256("main address relay")[0:8].
static const bool DEFAULT_FEEFILTER
Default for using fee filter.
const char * ADDR
The addr (IP address) message relays connection information for peers on the network.
const CMessageHeader::MessageStartChars & MessageStart() const
static const int DISCOURAGEMENT_THRESHOLD
Threshold for marking a node to be discouraged, e.g.
static const unsigned int INVENTORY_BROADCAST_INTERVAL
Average delay between trickled inventory transmissions in seconds.
const char * FILTERCLEAR
The filterclear message tells the receiving peer to remove a previously-set bloom filter...
std::atomic_bool fImporting
std::vector< uint256 > vHave
const char * NOTFOUND
The notfound message is a reply to a getdata message which requested an object the receiving node doe...
Parameters that influence chain consensus.
static const int MAX_CMPCTBLOCK_DEPTH
Maximum depth of blocks we're willing to serve as compact blocks to peers when requested.
An outpoint - a combination of a transaction hash and an index n into its vout.
bool AddNewAddresses(const std::vector< CAddress > &vAddr, const CAddress &addrFrom, int64_t nTimePenalty=0)
const char * BLOCK
The block message transmits a single serialized block.
std::atomic_bool fDisconnect
const char * FEEFILTER
The feefilter message tells the receiving peer not to inv us any txs which do not meet the specified ...
const char * GETCFHEADERS
getcfheaders requests a compact filter header and the filter hashes for a range of blocks...
int GetMyStartingHeight() const
const uint256 & GetWitnessHash() const
ServiceFlags GetLocalServices() const
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 SendBlockTransactions(CNode &pfrom, const CBlock &block, const BlockTransactionsRequest &req)
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
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.
static bool MayHaveUsefulAddressDB(ServiceFlags services)
Checks if a peer with the given service flags may be capable of having a robust address-storage DB...
bool GetNetworkActive() const
static const int MAX_UNCONNECTING_HEADERS
Maximum number of unconnecting headers announcements before DoS score.
void Misbehaving(const NodeId pnode, const int howmuch, const std::string &message)
Increment peer's misbehavior score.
const uint256 & GetHash() const
bool CheckIncomingNonce(uint64_t nonce)
bool IsAddrV1Compatible() const
Check if the current object can be serialized in pre-ADDRv2/BIP155 format.
const char * GETBLOCKS
The getblocks message requests an inv message that provides block header hashes starting from a parti...
static constexpr int32_t MAX_PEER_TX_ANNOUNCEMENTS
Maximum number of transactions to consider for requesting, per peer.
static constexpr int CFCHECKPT_INTERVAL
Interval between compact filter checkpoints.
const int64_t nTimeConnected
Transaction is missing a witness.
bool ProcessNewBlockHeaders(const std::vector< CBlockHeader > &block, BlockValidationState &state, const CChainParams &chainparams, const CBlockIndex **ppindex=nullptr) LOCKS_EXCLUDED(cs_main)
Process incoming block headers.
void RelayTransaction(const uint256 &txid, const uint256 &wtxid, const CConnman &connman) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Relay transaction to every node.
ChainstateManager & m_chainman
std::atomic_bool fReindex
const char * VERACK
The verack message acknowledges a previously-received version message, informing the connecting node ...
CAmount GetFee(size_t nBytes) const
Return the fee in satoshis for the given size in bytes.
CBlockIndex * LookupBlockIndex(const uint256 &hash)
std::atomic< bool > fPingQueued
invalid by consensus rules (excluding any below reasons)
bool ExpectServicesFromConn() const
CChainState & ChainstateActive()
Please prefer the identical ChainstateManager::ActiveChainstate.
static const unsigned int MAX_GETDATA_SZ
Limit to avoid sending big packets.
#define EXCLUSIVE_LOCKS_REQUIRED(...)
std::vector< CTransactionRef > vtx
const char * CMPCTBLOCK
Contains a CBlockHeaderAndShortTxIDs object - providing a header and list of "short txids"...
the block's data didn't match the data committed to by the PoW
CTxMemPool stores valid-according-to-the-current-best-chain transactions that may be included in the ...
std::string GetAddrName() const
void AddKnownTx(const uint256 &hash)
void check(const CCoinsViewCache *pcoins) const
If sanity-checking is turned on, check makes sure the pool is consistent (does not contain two transa...
std::atomic< int64_t > nLastTXTime
UNIX epoch time of the last transaction received from this peer that we had not yet seen (e...
#define LOCKS_EXCLUDED(...)
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.
static const int FEEFILTER_VERSION
"feefilter" tells peers to filter invs to you by fee starts with this version
const char * VERSION
The version message provides information about the transmitting node to the receiving node at the beg...
bool IsOutboundOrBlockRelayConn() const
std::vector< std::pair< unsigned int, uint256 > > vMatchedTxn
Public only for unit testing and relay testing (not relayed).
The block chain is a tree shaped structure starting with the genesis block at the root...
static const unsigned int BLOCK_DOWNLOAD_WINDOW
Size of the "block download window": how far ahead of our current height do we fetch? Larger windows tolerate larger download speed differences between peer, but increase the potential degree of disordering of blocks on disk (which make reindexing and pruning harder).
static const int MIN_PEER_PROTO_VERSION
disconnect from peers older than this proto version
static const unsigned int MAX_INV_SZ
The maximum number of entries in an 'inv' protocol message.
static const int PROTOCOL_VERSION
network protocol versioning
static const unsigned int MAX_STANDARD_TX_WEIGHT
The maximum weight for transactions we're willing to relay/mine.
std::string GetArg(const std::string &strArg, const std::string &strDefault) const
Return string argument or default value.
static const unsigned int DEFAULT_BLOCK_RECONSTRUCTION_EXTRA_TXN
Default number of orphan+recently-replaced txn to keep around for block reconstruction.
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.
A block this one builds on is invalid.
static constexpr size_t MAX_ADDR_TO_SEND
The maximum number of addresses from our addrman to return in response to a getaddr message...
std::set< uint256 > GetUnbroadcastTxs() const
Returns transactions in unbroadcast set.
CBlockIndex * FindForkInGlobalIndex(const CChain &chain, const CBlockLocator &locator)
Find the last common block between the parameter chain and a locator.
int64_t GetAdjustedTime()
ServiceFlags GetDesirableServiceFlags(ServiceFlags services)
Gets the set of service flags which are "desirable" for a given peer.
static const unsigned int BLOCK_STALLING_TIMEOUT
Timeout in seconds during which a peer must stall block download progress before being disconnected...
bool LookupFilterHeader(const CBlockIndex *block_index, uint256 &header_out)
Get a single filter header by block.
int64_t PoissonNextSend(int64_t now, int average_interval_seconds)
Return a timestamp in the future (in microseconds) for exponentially distributed events.
std::string ConnectionTypeAsString() const
void SetBestHeight(int height)
#define LIMITED_STRING(obj, n)
bool Contains(const CBlockIndex *pindex) const
Efficiently check whether a block is present in this chain.
std::atomic< int64_t > nTimeOffset
const char * GETDATA
The getdata message requests one or more data objects from another node.
Fee rate in satoshis per kilobyte: CAmount / kB.
static constexpr auto OVERLOADED_PEER_TX_DELAY
How long to delay requesting transactions from overloaded peers (see MAX_PEER_TX_REQUEST_IN_FLIGHT).
std::atomic_bool fSuccessfullyConnected
#define AssertLockNotHeld(cs)
std::string ToString() const
static const unsigned int MAX_SUBVERSION_LENGTH
Maximum length of the user agent string in version message.
std::atomic< int > nVersion
Invalid by a change to consensus rules more recent than SegWit.
bool IsValid(enum BlockStatus nUpTo=BLOCK_VALID_TRANSACTIONS) const
Check whether this block index entry is valid up to the passed validity level.
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...
static size_t RecursiveDynamicUsage(const CScript &script)
const char * CFCHECKPT
cfcheckpt is a response to a getcfcheckpt request containing a vector of evenly spaced filter headers...
ReadStatus InitData(const CBlockHeaderAndShortTxIDs &cmpctblock, const std::vector< std::pair< uint256, CTransactionRef >> &extra_txn)
const uint256 & GetHash() const
block timestamp was > 2 hours in the future (or our clock is bad)
static const unsigned int MAX_BLOCKS_TO_ANNOUNCE
Maximum number of headers to announce when relaying blocks with headers message.
int GetExtraOutboundCount()
void RemoveUnbroadcastTx(const uint256 &txid, const bool unchecked=false)
Removes a transaction from the unbroadcast set.
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 constexpr std::chrono::hours AVG_LOCAL_ADDRESS_BROADCAST_INTERVAL
Average delay between local address broadcasts.
CSipHasher GetDeterministicRandomizer(uint64_t id) const
Get a unique deterministic randomizer.
bool IsBanned(const CNetAddr &net_addr)
Return whether net_addr is banned.
std::string strSubVersion
Subversion as sent to the P2P network in version messages.
bool IsMsgFilteredBlk() const
const char * TX
The tx message transmits a single transaction.
static const unsigned int MAX_LOCATOR_SZ
The maximum number of entries in a locator.
The basic transaction that is broadcasted on the network and contained in blocks. ...
void MarkAddressGood(const CAddress &addr)
int nHeight
height of the entry in the chain. The genesis block has height 0
Information about a peer.
std::vector< int > vHeightInFlight
void ForEachNode(const NodeFn &func)
Simple class for background tasks that should be run periodically or once "after a while"...
static constexpr int32_t MAX_PEER_TX_REQUEST_IN_FLIGHT
Maximum number of in-flight transaction requests from a peer.
CBlockIndex * GetAncestor(int height)
Efficiently find an ancestor of this block.
full block available in blk*.dat
std::string ToString() const
void AddTimeData(const CNetAddr &ip, int64_t nOffsetSample)
int64_t GetBlockTime() const
bool IsManualConn() const
void AddAddressKnown(const CAddress &_addr)
void NewPoWValidBlock(const CBlockIndex *pindex, const std::shared_ptr< const CBlock > &pblock) override
Overridden from CValidationInterface.
int64_t GetTime()
Return system time (or mocked time, if set)
static const unsigned int DEFAULT_MAX_ORPHAN_TRANSACTIONS
Default for -maxorphantx, maximum number of orphan transactions kept in memory.
BanMan *const m_banman
Pointer to this node's banman.
static const int INVALID_CB_NO_BAN_VERSION
not banning for invalid compact blocks starts with this version
std::atomic_bool fPauseRecv
void BlockChecked(const CBlock &block, const BlockValidationState &state) override
Overridden from CValidationInterface.
static const int WTXID_RELAY_VERSION
"wtxidrelay" command for wtxid-based relay starts with this version
int GetRandInt(int nMax) noexcept
CAddress GetLocalAddress(const CNetAddr *paddrPeer, ServiceFlags nLocalServices)
static constexpr int HISTORICAL_BLOCK_AGE
Age after which a block is considered historical for purposes of rate limiting block relay...
std::atomic< int64_t > nLastBlockTime
UNIX epoch time of the last block received from this peer that we had not yet seen (e...
Tx already in mempool or conflicts with a tx in the chain (if it conflicts with another tx in mempool...
static constexpr int64_t STALE_CHECK_INTERVAL
How frequently to check for stale tips, in seconds.
otherwise didn't meet our local policy rules
A generic txid reference (txid or wtxid).
static constexpr int64_t ORPHAN_TX_EXPIRE_INTERVAL
Minimum time between orphan transactions expire time checks in seconds.
uint64_t randrange(uint64_t range) noexcept
Generate a random integer in the range [0..range).
unsigned int nTx
Number of transactions in this block.
void scheduleFromNow(Function f, std::chrono::milliseconds delta)
Call f once after the delta has passed.
static const int64_t BLOCK_DOWNLOAD_TIMEOUT_BASE
Block download timeout base, expressed in millionths of the block interval (i.e.
const char * FILTERADD
The filteradd message tells the receiving peer to add a single element to a previously-set bloom filt...
RecursiveMutex cs
This mutex needs to be locked when accessing mapTx or other members that are guarded by it...
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.
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...
std::atomic< std::chrono::microseconds > m_ping_start
When the last ping was sent, or 0 if no ping was ever sent.
bool IsRelayable() const
Whether this address should be relayed to other peers even if we can't reach it ourselves.
uint256 GetBlockHash() const
const std::string & BlockFilterTypeName(BlockFilterType filter_type)
Get the human-readable name for a filter type.
unsigned long size() const
const char * GETBLOCKTXN
Contains a BlockTransactionsRequest Peer should respond with "blocktxn" message.
std::vector< unsigned char > GetKey() const
std::unique_ptr< TxRelay > m_tx_relay
static constexpr std::chrono::seconds AVG_ADDRESS_BROADCAST_INTERVAL
Average delay between peer address broadcasts.
Span< A > constexpr MakeSpan(A(&a)[N])
MakeSpan for arrays:
bool HaveTxsDownloaded() const
Check whether this block's and all previous blocks' transactions have been downloaded (and stored to ...