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;
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;
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;
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;
2613 RelayAddress(addr, fReachable,
m_connman);
2617 vAddrOk.push_back(addr);
2620 if (vAddr.size() < 1000)
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;
2692 const bool fAlreadyHave = AlreadyHaveBlock(inv.
hash);
2695 UpdateBlockAvailability(pfrom.
GetId(), inv.
hash);
2702 best_block = &inv.
hash;
2706 const bool fAlreadyHave = AlreadyHaveTx(gtxid,
m_mempool);
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;
2775 LOCK(cs_most_recent_block);
2776 a_recent_block = most_recent_block;
2793 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());
2826 std::shared_ptr<const CBlock> recent_block;
2828 LOCK(cs_most_recent_block);
2829 if (most_recent_block_hash == req.blockhash)
2830 recent_block = most_recent_block;
2867 inv.hash = req.blockhash;
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());
2900 if (!BlockRequestAllowed(pindex,
m_chainparams.GetConsensus())) {
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;
2916 LogPrint(
BCLog::NET,
"getheaders %d to %s from peer=%d\n", (pindex ? pindex->nHeight : -1), hashStop.IsNull() ?
"end" : hashStop.ToString(), pfrom.
GetId());
2919 vHeaders.push_back(pindex->GetBlockHeader());
2920 if (--nLimit <= 0 || pindex->GetBlockHash() == hashStop)
2955 const uint256& txid = ptx->GetHash();
2956 const uint256& wtxid = ptx->GetWitnessHash();
2958 LOCK2(cs_main, g_cs_orphans);
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);
3030 AddToCompactExtraTransactions(removedTx);
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};
3067 if (!AlreadyHaveTx(gtxid,
m_mempool)) AddTxAnnouncement(pfrom, gtxid, current_time);
3069 AddOrphanTx(ptx, pfrom.
GetId());
3072 m_txrequest.ForgetTxHash(tx.
GetHash());
3077 unsigned int nEvicted = LimitOrphanTxSize(nMaxOrphanTx);
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());
3125 AddToCompactExtraTransactions(ptx);
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;
3210 LOCK2(cs_main, g_cs_orphans);
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);
3235 vInv[0] =
CInv(
MSG_BLOCK | GetFetchFlags(pfrom), cmpctblock.header.GetHash());
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)
3259 (*queuedBlockIt)->partialBlock.reset(
new PartiallyDownloadedBlock(&
m_mempool));
3267 PartiallyDownloadedBlock& partialBlock = *(*queuedBlockIt)->partialBlock;
3275 std::vector<CInv> vInv(1);
3276 vInv[0] =
CInv(
MSG_BLOCK | GetFetchFlags(pfrom), cmpctblock.header.GetHash());
3282 for (
size_t i = 0; i < cmpctblock.BlockTxCount(); i++) {
3289 txn.
blockhash = cmpctblock.header.GetHash();
3291 fProcessBLOCKTXN =
true;
3302 PartiallyDownloadedBlock tempBlock(&
m_mempool);
3303 ReadStatus status = tempBlock.InitData(cmpctblock, vExtraTxnForCompact);
3308 std::vector<CTransactionRef> dummy;
3309 status = tempBlock.FillBlock(*pblock, dummy);
3311 fBlockReconstructed =
true;
3315 if (fAlreadyInFlight) {
3318 std::vector<CInv> vInv(1);
3319 vInv[0] =
CInv(
MSG_BLOCK | GetFetchFlags(pfrom), cmpctblock.header.GetHash());
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()) {
3401 PartiallyDownloadedBlock& partialBlock = *it->second.second->partialBlock;
3404 MarkBlockAsReceived(resp.blockhash);
3405 Misbehaving(pfrom.
GetId(), 100,
"invalid compact block/non-matching block transactions");
3409 std::vector<CInv> invs;
3410 invs.push_back(
CInv(
MSG_BLOCK | GetFetchFlags(pfrom), resp.blockhash));
3430 MarkBlockAsReceived(resp.blockhash);
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) {
3666 if (!filter.IsWithinSizeConstraints())
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()) {
3827 LOCK2(cs_main, g_cs_orphans);
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;
3869 unsigned int nMessageSize = msg.m_message_size;
3872 ProcessMessage(*pfrom, msg_type, msg.m_recv, msg.m_time, interruptMsgProc);
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) {
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();
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) {
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>();
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;
4241 LOCK(cs_most_recent_block);
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();
4404 pto->
m_tx_relay->setInventoryTxToSend.erase(it);
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;
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;
4533 uint32_t nFetchFlags = GetFetchFlags(*pto);
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)) {
4618 class CNetProcessingCleanup
4621 CNetProcessingCleanup() {}
4622 ~CNetProcessingCleanup() {
4624 mapOrphanTransactions.clear();
4625 mapOrphanTransactionsByPrev.clear();
4626 g_orphans_by_wtxid.clear();
4629 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 ...