35 # error "BSHA3 cannot be compiled without assertions." 39 static constexpr int64_t ORPHAN_TX_EXPIRE_TIME = 20 * 60;
41 static constexpr int64_t ORPHAN_TX_EXPIRE_INTERVAL = 5 * 60;
44 static constexpr int64_t HEADERS_DOWNLOAD_TIMEOUT_BASE = 15 * 60 * 1000000;
45 static constexpr int64_t HEADERS_DOWNLOAD_TIMEOUT_PER_HEADER = 1000;
49 static constexpr int32_t MAX_OUTBOUND_PEERS_TO_PROTECT_FROM_DISCONNECT = 4;
51 static constexpr int64_t CHAIN_SYNC_TIMEOUT = 20 * 60;
53 static constexpr int64_t STALE_CHECK_INTERVAL = 10 * 60;
55 static constexpr int64_t EXTRA_PEER_CHECK_INTERVAL = 45;
57 static constexpr int64_t MINIMUM_CONNECT_TIME = 30;
59 static constexpr uint64_t RANDOMIZER_ID_ADDRESS_RELAY = 0x3cac0035b5866b90ULL;
62 static constexpr
int STALE_RELAY_AGE_LIMIT = 30 * 24 * 60 * 60;
65 static constexpr
int HISTORICAL_BLOCK_AGE = 7 * 24 * 60 * 60;
82 static constexpr
unsigned int AVG_LOCAL_ADDRESS_BROADCAST_INTERVAL = 24 * 60 * 60;
84 static const
unsigned int AVG_ADDRESS_BROADCAST_INTERVAL = 30;
87 static const
unsigned int INVENTORY_BROADCAST_INTERVAL = 5;
90 static constexpr
unsigned int INVENTORY_BROADCAST_MAX = 7 * INVENTORY_BROADCAST_INTERVAL;
92 static constexpr
unsigned int AVG_FEEFILTER_BROADCAST_INTERVAL = 10 * 60;
94 static constexpr
unsigned int MAX_FEEFILTER_CHANGE_DELAY = 5 * 60;
135 bool fValidatedHeaders;
136 std::unique_ptr<PartiallyDownloadedBlock> partialBlock;
138 std::map<uint256, std::pair<NodeId, std::list<QueuedBlock>::iterator> > mapBlocksInFlight
GUARDED_BY(
cs_main);
153 std::atomic<int64_t> g_last_tip_update(0);
156 typedef std::map<uint256, CTransactionRef> MapRelay;
159 std::deque<std::pair<int64_t, MapRelay::iterator>> vRelayExpiration
GUARDED_BY(
cs_main);
161 std::atomic<int64_t> nTimeBestReceived(0);
163 struct IteratorComparator
166 bool operator()(
const I& a,
const I& b)
const 168 return &(*a) < &(*b);
171 std::map<COutPoint, std::set<std::map<uint256, COrphanTx>::iterator, IteratorComparator>> mapOrphanTransactionsByPrev
GUARDED_BY(
g_cs_orphans);
178 struct CBlockReject {
179 unsigned char chRejectCode;
180 std::string strRejectReason;
194 bool fCurrentlyConnected;
200 const std::string
name;
202 std::vector<CBlockReject> rejects;
212 int nUnconnectingHeaders;
216 int64_t nHeadersSyncTimeout;
218 int64_t nStallingSince;
219 std::list<QueuedBlock> vBlocksInFlight;
221 int64_t nDownloadingSince;
223 int nBlocksInFlightValidHeaders;
225 bool fPreferredDownload;
229 bool fPreferHeaderAndIDs;
235 bool fProvidesHeaderAndIDs;
239 bool fWantsCmpctWitness;
244 bool fSupportsDesiredCmpctVersion;
260 struct ChainSyncTimeoutState {
266 bool m_sent_getheaders;
271 ChainSyncTimeoutState m_chain_sync;
274 int64_t m_last_block_announcement;
276 CNodeState(
CAddress addrIn, std::string addrNameIn) : address(addrIn),
name(addrNameIn) {
277 fCurrentlyConnected =
false;
280 pindexBestKnownBlock =
nullptr;
281 hashLastUnknownBlock.
SetNull();
282 pindexLastCommonBlock =
nullptr;
283 pindexBestHeaderSent =
nullptr;
284 nUnconnectingHeaders = 0;
285 fSyncStarted =
false;
286 nHeadersSyncTimeout = 0;
288 nDownloadingSince = 0;
290 nBlocksInFlightValidHeaders = 0;
291 fPreferredDownload =
false;
292 fPreferHeaders =
false;
293 fPreferHeaderAndIDs =
false;
294 fProvidesHeaderAndIDs =
false;
295 fHaveWitness =
false;
296 fWantsCmpctWitness =
false;
297 fSupportsDesiredCmpctVersion =
false;
298 m_chain_sync = { 0,
nullptr,
false,
false };
299 m_last_block_announcement = 0;
307 std::map<NodeId, CNodeState>::iterator it = mapNodeState.find(pnode);
308 if (it == mapNodeState.end())
315 nPreferredDownload -= state->fPreferredDownload;
318 state->fPreferredDownload = (!node->fInbound || node->fWhitelisted) && !node->fOneShot && !node->fClient;
320 nPreferredDownload += state->fPreferredDownload;
323 static void PushNodeVersion(
CNode *pnode,
CConnman* connman, int64_t nTime)
338 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);
340 LogPrint(
BCLog::NET,
"send version message: version %d, blocks=%d, us=%s, peer=%d\n", PROTOCOL_VERSION, nNodeStartingHeight, addrMe.
ToString(), nodeid);
347 std::map<uint256, std::pair<NodeId, std::list<QueuedBlock>::iterator> >::iterator itInFlight = mapBlocksInFlight.find(hash);
348 if (itInFlight != mapBlocksInFlight.end()) {
349 CNodeState *state = State(itInFlight->second.first);
350 assert(state !=
nullptr);
351 state->nBlocksInFlightValidHeaders -= itInFlight->second.second->fValidatedHeaders;
352 if (state->nBlocksInFlightValidHeaders == 0 && itInFlight->second.second->fValidatedHeaders) {
354 nPeersWithValidatedDownloads--;
356 if (state->vBlocksInFlight.begin() == itInFlight->second.second) {
358 state->nDownloadingSince = std::max(state->nDownloadingSince,
GetTimeMicros());
360 state->vBlocksInFlight.erase(itInFlight->second.second);
361 state->nBlocksInFlight--;
362 state->nStallingSince = 0;
363 mapBlocksInFlight.erase(itInFlight);
372 CNodeState *state = State(nodeid);
373 assert(state !=
nullptr);
376 std::map<uint256, std::pair<NodeId, std::list<QueuedBlock>::iterator> >::iterator itInFlight = mapBlocksInFlight.find(hash);
377 if (itInFlight != mapBlocksInFlight.end() && itInFlight->second.first == nodeid) {
379 *pit = &itInFlight->second.second;
385 MarkBlockAsReceived(hash);
387 std::list<QueuedBlock>::iterator it = state->vBlocksInFlight.insert(state->vBlocksInFlight.end(),
389 state->nBlocksInFlight++;
390 state->nBlocksInFlightValidHeaders += it->fValidatedHeaders;
391 if (state->nBlocksInFlight == 1) {
395 if (state->nBlocksInFlightValidHeaders == 1 && pindex !=
nullptr) {
396 nPeersWithValidatedDownloads++;
398 itInFlight = mapBlocksInFlight.insert(std::make_pair(hash, std::make_pair(nodeid, it))).first;
400 *pit = &itInFlight->second.second;
406 CNodeState *state = State(nodeid);
407 assert(state !=
nullptr);
409 if (!state->hashLastUnknownBlock.IsNull()) {
412 if (state->pindexBestKnownBlock ==
nullptr || pindex->
nChainWork >= state->pindexBestKnownBlock->nChainWork) {
413 state->pindexBestKnownBlock = pindex;
415 state->hashLastUnknownBlock.SetNull();
422 CNodeState *state = State(nodeid);
423 assert(state !=
nullptr);
425 ProcessBlockAvailability(nodeid);
430 if (state->pindexBestKnownBlock ==
nullptr || pindex->
nChainWork >= state->pindexBestKnownBlock->nChainWork) {
431 state->pindexBestKnownBlock = pindex;
435 state->hashLastUnknownBlock = hash;
448 CNodeState* nodestate = State(nodeid);
449 if (!nodestate || !nodestate->fSupportsDesiredCmpctVersion) {
453 if (nodestate->fProvidesHeaderAndIDs) {
454 for (std::list<NodeId>::iterator it = lNodesAnnouncingHeaderAndIDs.begin(); it != lNodesAnnouncingHeaderAndIDs.end(); it++) {
456 lNodesAnnouncingHeaderAndIDs.erase(it);
457 lNodesAnnouncingHeaderAndIDs.push_back(nodeid);
464 if (lNodesAnnouncingHeaderAndIDs.size() >= 3) {
467 connman->
ForNode(lNodesAnnouncingHeaderAndIDs.front(), [connman, nCMPCTBLOCKVersion](
CNode* pnodeStop){
472 lNodesAnnouncingHeaderAndIDs.pop_front();
475 lNodesAnnouncingHeaderAndIDs.push_back(pfrom->
GetId());
484 if (g_last_tip_update == 0) {
487 return g_last_tip_update <
GetTime() - consensusParams.nPowTargetSpacing * 3 && mapBlocksInFlight.empty();
497 if (state->pindexBestKnownBlock && pindex == state->pindexBestKnownBlock->GetAncestor(pindex->
nHeight))
499 if (state->pindexBestHeaderSent && pindex == state->pindexBestHeaderSent->GetAncestor(pindex->
nHeight))
511 vBlocks.reserve(vBlocks.size() + count);
512 CNodeState *state = State(nodeid);
513 assert(state !=
nullptr);
516 ProcessBlockAvailability(nodeid);
523 if (state->pindexLastCommonBlock ==
nullptr) {
531 state->pindexLastCommonBlock =
LastCommonAncestor(state->pindexLastCommonBlock, state->pindexBestKnownBlock);
532 if (state->pindexLastCommonBlock == state->pindexBestKnownBlock)
535 std::vector<const CBlockIndex*> vToFetch;
536 const CBlockIndex *pindexWalk = state->pindexLastCommonBlock;
540 int nWindowEnd = state->pindexLastCommonBlock->nHeight + BLOCK_DOWNLOAD_WINDOW;
541 int nMaxHeight = std::min<int>(state->pindexBestKnownBlock->nHeight, nWindowEnd + 1);
543 while (pindexWalk->
nHeight < nMaxHeight) {
547 int nToFetch = std::min(nMaxHeight - pindexWalk->
nHeight, std::max<int>(count - vBlocks.size(), 128));
548 vToFetch.resize(nToFetch);
549 pindexWalk = state->pindexBestKnownBlock->GetAncestor(pindexWalk->
nHeight + nToFetch);
550 vToFetch[nToFetch - 1] = pindexWalk;
551 for (
unsigned int i = nToFetch - 1; i > 0; i--) {
552 vToFetch[i - 1] = vToFetch[i]->
pprev;
570 state->pindexLastCommonBlock = pindex;
571 }
else if (mapBlocksInFlight.count(pindex->
GetBlockHash()) == 0) {
573 if (pindex->
nHeight > nWindowEnd) {
575 if (vBlocks.size() == 0 && waitingfor != nodeid) {
577 nodeStaller = waitingfor;
581 vBlocks.push_back(pindex);
582 if (vBlocks.size() == count) {
585 }
else if (waitingfor == -1) {
587 waitingfor = mapBlocksInFlight[pindex->
GetBlockHash()].first;
600 CNodeState *state = State(node);
601 if (state) state->m_last_block_announcement = time_in_seconds;
606 static bool IsOutboundDisconnectionCandidate(
const CNode *node)
617 mapNodeState.emplace_hint(mapNodeState.end(), std::piecewise_construct, std::forward_as_tuple(nodeid), std::forward_as_tuple(addr, std::move(addrName)));
624 fUpdateConnectionTime =
false;
626 CNodeState *state = State(nodeid);
627 assert(state !=
nullptr);
629 if (state->fSyncStarted)
632 if (state->nMisbehavior == 0 && state->fCurrentlyConnected) {
633 fUpdateConnectionTime =
true;
636 for (
const QueuedBlock& entry : state->vBlocksInFlight) {
637 mapBlocksInFlight.erase(entry.hash);
640 nPreferredDownload -= state->fPreferredDownload;
641 nPeersWithValidatedDownloads -= (state->nBlocksInFlightValidHeaders != 0);
642 assert(nPeersWithValidatedDownloads >= 0);
643 g_outbound_peers_with_protect_from_disconnect -= state->m_chain_sync.m_protect;
644 assert(g_outbound_peers_with_protect_from_disconnect >= 0);
646 mapNodeState.erase(nodeid);
648 if (mapNodeState.empty()) {
650 assert(mapBlocksInFlight.empty());
651 assert(nPreferredDownload == 0);
652 assert(nPeersWithValidatedDownloads == 0);
653 assert(g_outbound_peers_with_protect_from_disconnect == 0);
655 LogPrint(
BCLog::NET,
"Cleared nodestate for peer=%d\n", nodeid);
660 CNodeState *state = State(nodeid);
661 if (state ==
nullptr)
664 stats.
nSyncHeight = state->pindexBestKnownBlock ? state->pindexBestKnownBlock->nHeight : -1;
665 stats.
nCommonHeight = state->pindexLastCommonBlock ? state->pindexLastCommonBlock->nHeight : -1;
666 for (
const QueuedBlock& queue : state->vBlocksInFlight) {
680 size_t max_extra_txn =
gArgs.
GetArg(
"-blockreconstructionextratxn", DEFAULT_BLOCK_RECONSTRUCTION_EXTRA_TXN);
681 if (max_extra_txn <= 0)
683 if (!vExtraTxnForCompact.size())
684 vExtraTxnForCompact.resize(max_extra_txn);
685 vExtraTxnForCompact[vExtraTxnForCompactIt] = std::make_pair(tx->GetWitnessHash(), tx);
686 vExtraTxnForCompactIt = (vExtraTxnForCompactIt + 1) % max_extra_txn;
691 const uint256& hash = tx->GetHash();
692 if (mapOrphanTransactions.count(hash))
702 unsigned int sz = GetTransactionWeight(*tx);
703 if (sz > MAX_STANDARD_TX_WEIGHT)
709 auto ret = mapOrphanTransactions.emplace(hash,
COrphanTx{tx, peer,
GetTime() + ORPHAN_TX_EXPIRE_TIME});
711 for (
const CTxIn& txin : tx->vin) {
712 mapOrphanTransactionsByPrev[txin.
prevout].insert(
ret.first);
715 AddToCompactExtraTransactions(tx);
718 mapOrphanTransactions.size(), mapOrphanTransactionsByPrev.size());
724 std::map<uint256, COrphanTx>::iterator it = mapOrphanTransactions.find(hash);
725 if (it == mapOrphanTransactions.end())
727 for (
const CTxIn& txin : it->second.tx->vin)
729 auto itPrev = mapOrphanTransactionsByPrev.find(txin.
prevout);
730 if (itPrev == mapOrphanTransactionsByPrev.end())
732 itPrev->second.erase(it);
733 if (itPrev->second.empty())
734 mapOrphanTransactionsByPrev.erase(itPrev);
736 mapOrphanTransactions.erase(it);
744 std::map<uint256, COrphanTx>::iterator iter = mapOrphanTransactions.begin();
745 while (iter != mapOrphanTransactions.end())
747 std::map<uint256, COrphanTx>::iterator maybeErase = iter++;
748 if (maybeErase->second.fromPeer == peer)
750 nErased += EraseOrphanTx(maybeErase->second.tx->GetHash());
753 if (nErased > 0) LogPrint(
BCLog::MEMPOOL,
"Erased %d orphan tx from peer=%d\n", nErased, peer);
761 unsigned int nEvicted = 0;
762 static int64_t nNextSweep;
764 if (nNextSweep <= nNow) {
767 int64_t nMinExpTime = nNow + ORPHAN_TX_EXPIRE_TIME - ORPHAN_TX_EXPIRE_INTERVAL;
768 std::map<uint256, COrphanTx>::iterator iter = mapOrphanTransactions.begin();
769 while (iter != mapOrphanTransactions.end())
771 std::map<uint256, COrphanTx>::iterator maybeErase = iter++;
772 if (maybeErase->second.nTimeExpire <= nNow) {
773 nErased += EraseOrphanTx(maybeErase->second.tx->GetHash());
775 nMinExpTime = std::min(maybeErase->second.nTimeExpire, nMinExpTime);
779 nNextSweep = nMinExpTime + ORPHAN_TX_EXPIRE_INTERVAL;
780 if (nErased > 0) LogPrint(
BCLog::MEMPOOL,
"Erased %d orphan tx due to expiration\n", nErased);
782 while (mapOrphanTransactions.size() > nMaxOrphans)
786 std::map<uint256, COrphanTx>::iterator it = mapOrphanTransactions.lower_bound(randomhash);
787 if (it == mapOrphanTransactions.end())
788 it = mapOrphanTransactions.begin();
789 EraseOrphanTx(it->first);
803 CNodeState *state = State(pnode);
804 if (state ==
nullptr)
807 state->nMisbehavior += howmuch;
808 int banscore =
gArgs.
GetArg(
"-banscore", DEFAULT_BANSCORE_THRESHOLD);
809 std::string message_prefixed = message.empty() ?
"" : (
": " + message);
810 if (state->nMisbehavior >= banscore && state->nMisbehavior - howmuch < banscore)
812 LogPrint(
BCLog::NET,
"%s: %s peer=%d (%d -> %d) BAN THRESHOLD EXCEEDED%s\n", __func__, state->name, pnode, state->nMisbehavior-howmuch, state->nMisbehavior, message_prefixed);
813 state->fShouldBan =
true;
815 LogPrint(
BCLog::NET,
"%s: %s peer=%d (%d -> %d)%s\n", __func__, state->name, pnode, state->nMisbehavior-howmuch, state->nMisbehavior, message_prefixed);
844 : connman(connmanIn), m_stale_tip_check_time(0), m_enable_bip61(enable_bip61) {
854 static_assert(EXTRA_PEER_CHECK_INTERVAL < STALE_CHECK_INTERVAL,
"peer eviction timer should be less than stale tip check timer");
865 std::vector<uint256> vOrphanErase;
871 for (
const auto& txin : tx.
vin) {
872 auto itByPrev = mapOrphanTransactionsByPrev.find(txin.
prevout);
873 if (itByPrev == mapOrphanTransactionsByPrev.end())
continue;
874 for (
auto mi = itByPrev->second.begin(); mi != itByPrev->second.end(); ++mi) {
877 vOrphanErase.push_back(orphanHash);
883 if (vOrphanErase.size()) {
885 for (
const uint256& orphanHash : vOrphanErase) {
886 nErased += EraseOrphanTx(orphanHash);
888 LogPrint(
BCLog::MEMPOOL,
"Erased %d orphan tx included or conflicted by block\n", nErased);
896 static std::shared_ptr<const CBlock> most_recent_block
GUARDED_BY(cs_most_recent_block);
897 static std::shared_ptr<const CBlockHeaderAndShortTxIDs> most_recent_compact_block
GUARDED_BY(cs_most_recent_block);
899 static bool fWitnessesPresentInMostRecentCompactBlock
GUARDED_BY(cs_most_recent_block);
906 std::shared_ptr<const CBlockHeaderAndShortTxIDs> pcmpctblock = std::make_shared<const CBlockHeaderAndShortTxIDs> (*pblock,
true);
911 static int nHighestFastAnnounce = 0;
912 if (pindex->
nHeight <= nHighestFastAnnounce)
914 nHighestFastAnnounce = pindex->
nHeight;
917 uint256 hashBlock(pblock->GetHash());
920 LOCK(cs_most_recent_block);
921 most_recent_block_hash = hashBlock;
922 most_recent_block = pblock;
923 most_recent_compact_block = pcmpctblock;
924 fWitnessesPresentInMostRecentCompactBlock = fWitnessEnabled;
933 ProcessBlockAvailability(pnode->
GetId());
934 CNodeState &state = *State(pnode->
GetId());
937 if (state.fPreferHeaderAndIDs && (!fWitnessEnabled || state.fWantsCmpctWitness) &&
938 !PeerHasHeader(&state, pindex) && PeerHasHeader(&state, pindex->
pprev)) {
940 LogPrint(
BCLog::NET,
"%s sending header-and-ids %s to peer=%d\n",
"PeerLogicValidation::NewPoWValidBlock",
941 hashBlock.ToString(), pnode->
GetId());
943 state.pindexBestHeaderSent = pindex;
953 const int nNewHeight = pindexNew->
nHeight;
957 if (!fInitialDownload) {
959 std::vector<uint256> vHashes;
961 while (pindexToAnnounce != pindexFork) {
963 pindexToAnnounce = pindexToAnnounce->
pprev;
964 if (vHashes.size() == MAX_BLOCKS_TO_ANNOUNCE) {
973 for (const uint256& hash : reverse_iterate(vHashes)) {
974 pnode->PushBlockHash(hash);
992 std::map<uint256, std::pair<NodeId, bool>>::iterator it = mapBlockSource.find(hash);
997 if (it != mapBlockSource.end() && State(it->second.first) && state.
GetRejectCode() > 0 && state.
GetRejectCode() < REJECT_INTERNAL) {
999 State(it->second.first)->rejects.push_back(reject);
1000 if (nDoS > 0 && it->second.second)
1012 mapBlocksInFlight.count(hash) == mapBlocksInFlight.size()) {
1013 if (it != mapBlockSource.end()) {
1014 MaybeSetPeerAsAnnouncingHeaderAndIDs(it->second.first,
connman);
1017 if (it != mapBlockSource.end())
1018 mapBlockSource.erase(it);
1034 assert(recentRejects);
1042 recentRejects->reset();
1047 if (mapOrphanTransactions.count(inv.hash))
return true;
1050 return recentRejects->contains(inv.hash) ||
1072 static void RelayAddress(
const CAddress& addr,
bool fReachable,
CConnman* connman)
1074 unsigned int nRelayNodes = fReachable ? 2 : 1;
1079 uint64_t hashAddr = addr.
GetHash();
1083 std::array<std::pair<uint64_t, CNode*>,2> best{{{0,
nullptr}, {0,
nullptr}}};
1084 assert(nRelayNodes <= best.size());
1086 auto sortfunc = [&best, &hasher, nRelayNodes](
CNode* pnode) {
1087 if (pnode->
nVersion >= CADDR_TIME_VERSION) {
1089 for (
unsigned int i = 0; i < nRelayNodes; i++) {
1090 if (hashKey > best[i].first) {
1091 std::copy(best.begin() + i, best.begin() + nRelayNodes - 1, best.begin() + i + 1);
1092 best[i] = std::make_pair(hashKey, pnode);
1099 auto pushfunc = [&addr, &best, nRelayNodes, &insecure_rand] {
1100 for (
unsigned int i = 0; i < nRelayNodes && best[i].first != 0; i++) {
1101 best[i].second->PushAddress(addr, insecure_rand);
1111 std::shared_ptr<const CBlock> a_recent_block;
1112 std::shared_ptr<const CBlockHeaderAndShortTxIDs> a_recent_compact_block;
1113 bool fWitnessesPresentInARecentCompactBlock;
1116 LOCK(cs_most_recent_block);
1117 a_recent_block = most_recent_block;
1118 a_recent_compact_block = most_recent_compact_block;
1119 fWitnessesPresentInARecentCompactBlock = fWitnessesPresentInMostRecentCompactBlock;
1122 bool need_activate_chain =
false;
1134 need_activate_chain =
true;
1138 if (need_activate_chain) {
1148 send = BlockRequestAllowed(pindex, consensusParams);
1150 LogPrint(
BCLog::NET,
"%s: ignoring request from peer=%i for old block that isn't in the main chain\n", __func__, pfrom->
GetId());
1158 LogPrint(
BCLog::NET,
"historical block serving limit reached, disconnect peer=%d\n", pfrom->
GetId());
1168 LogPrint(
BCLog::NET,
"Ignore block request below NODE_NETWORK_LIMITED threshold from peer=%d\n", pfrom->
GetId());
1178 std::shared_ptr<const CBlock> pblock;
1179 if (a_recent_block && a_recent_block->GetHash() == pindex->
GetBlockHash()) {
1180 pblock = a_recent_block;
1184 std::vector<uint8_t> block_data;
1186 assert(!
"cannot load block from disk");
1192 std::shared_ptr<CBlock> pblockRead = std::make_shared<CBlock>();
1194 assert(!
"cannot load block from disk");
1195 pblock = pblockRead;
1204 bool sendMerkleBlock =
false;
1209 sendMerkleBlock =
true;
1213 if (sendMerkleBlock) {
1221 typedef std::pair<unsigned int, uint256> PairType;
1234 bool fPeerWantsWitness = State(pfrom->
GetId())->fWantsCmpctWitness;
1235 int nSendFlags = fPeerWantsWitness ? 0 : SERIALIZE_TRANSACTION_NO_WITNESS;
1237 if ((fPeerWantsWitness || !fWitnessesPresentInARecentCompactBlock) && a_recent_compact_block && a_recent_compact_block->header.GetHash() == pindex->
GetBlockHash()) {
1255 std::vector<CInv> vInv;
1267 std::deque<CInv>::iterator it = pfrom->
vRecvGetData.begin();
1268 std::vector<CInv> vNotFound;
1274 if (interruptMsgProc)
1280 const CInv &inv = *it;
1285 auto mi = mapRelay.find(inv.
hash);
1286 int nSendFlags = (inv.
type ==
MSG_TX ? SERIALIZE_TRANSACTION_NO_WITNESS : 0);
1287 if (mi != mapRelay.end()) {
1300 vNotFound.push_back(inv);
1306 const CInv &inv = *it;
1309 ProcessGetBlockData(pfrom, chainparams, inv, connman);
1315 if (!vNotFound.empty()) {
1328 uint32_t nFetchFlags = 0;
1337 for (
size_t i = 0; i < req.
indexes.size(); i++) {
1347 int nSendFlags = State(pfrom->
GetId())->fWantsCmpctWitness ? 0 : SERIALIZE_TRANSACTION_NO_WITNESS;
1351 bool static ProcessHeadersMessage(
CNode *pfrom,
CConnman *connman,
const std::vector<CBlockHeader>& headers,
const CChainParams& chainparams,
bool punish_duplicate_invalid)
1354 size_t nCount = headers.size();
1361 bool received_new_header =
false;
1365 CNodeState *nodestate = State(pfrom->
GetId());
1375 if (!
LookupBlockIndex(headers[0].hashPrevBlock) && nCount < MAX_BLOCKS_TO_ANNOUNCE) {
1376 nodestate->nUnconnectingHeaders++;
1378 LogPrint(
BCLog::NET,
"received header %s: missing prev block %s, sending getheaders (%d) to end (peer=%d, nUnconnectingHeaders=%d)\n",
1379 headers[0].GetHash().ToString(),
1380 headers[0].hashPrevBlock.ToString(),
1382 pfrom->
GetId(), nodestate->nUnconnectingHeaders);
1386 UpdateBlockAvailability(pfrom->
GetId(), headers.back().GetHash());
1388 if (nodestate->nUnconnectingHeaders % MAX_UNCONNECTING_HEADERS == 0) {
1396 if (!hashLastBlock.
IsNull() && header.hashPrevBlock != hashLastBlock) {
1400 hashLastBlock = header.GetHash();
1406 received_new_header =
true;
1419 LogPrint(
BCLog::NET,
"peer=%d: invalid header received\n", pfrom->
GetId());
1461 CNodeState *nodestate = State(pfrom->
GetId());
1462 if (nodestate->nUnconnectingHeaders > 0) {
1463 LogPrint(
BCLog::NET,
"peer=%d: resetting nUnconnectingHeaders (%d -> 0)\n", pfrom->
GetId(), nodestate->nUnconnectingHeaders);
1465 nodestate->nUnconnectingHeaders = 0;
1468 if (!pindexLast)
return true;
1476 nodestate->m_last_block_announcement =
GetTime();
1479 if (nCount == MAX_HEADERS_RESULTS) {
1487 bool fCanDirectFetch = CanDirectFetch(chainparams.
GetConsensus());
1491 std::vector<const CBlockIndex*> vToFetch;
1494 while (pindexWalk && !
chainActive.
Contains(pindexWalk) && vToFetch.size() <= MAX_BLOCKS_IN_TRANSIT_PER_PEER) {
1496 !mapBlocksInFlight.count(pindexWalk->
GetBlockHash()) &&
1499 vToFetch.push_back(pindexWalk);
1501 pindexWalk = pindexWalk->
pprev;
1508 LogPrint(
BCLog::NET,
"Large reorg, won't direct fetch to %s (%d)\n",
1512 std::vector<CInv> vGetData;
1515 if (nodestate->nBlocksInFlight >= MAX_BLOCKS_IN_TRANSIT_PER_PEER) {
1519 uint32_t nFetchFlags = GetFetchFlags(pfrom);
1522 LogPrint(
BCLog::NET,
"Requesting block %s from peer=%d\n",
1525 if (vGetData.size() > 1) {
1526 LogPrint(
BCLog::NET,
"Downloading blocks toward %s (%d) via headers direct fetch\n",
1529 if (vGetData.size() > 0) {
1530 if (nodestate->fSupportsDesiredCmpctVersion && vGetData.size() == 1 && mapBlocksInFlight.size() == 1 && pindexLast->
pprev->
IsValid(
BLOCK_VALID_CHAIN)) {
1543 if (nodestate->pindexBestKnownBlock && nodestate->pindexBestKnownBlock->nChainWork <
nMinimumChainWork) {
1552 if (IsOutboundDisconnectionCandidate(pfrom)) {
1553 LogPrintf(
"Disconnecting outbound peer %d -- headers chain has insufficient work\n", pfrom->
GetId());
1559 if (!pfrom->
fDisconnect && IsOutboundDisconnectionCandidate(pfrom) && nodestate->pindexBestKnownBlock !=
nullptr) {
1562 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) {
1563 LogPrint(
BCLog::NET,
"Protecting outbound peer=%d from eviction\n", pfrom->
GetId());
1564 nodestate->m_chain_sync.m_protect =
true;
1565 ++g_outbound_peers_with_protect_from_disconnect;
1573 bool static ProcessMessage(
CNode* pfrom,
const std::string& strCommand,
CDataStream& vRecv, int64_t nTimeReceived,
const CChainParams& chainparams,
CConnman* connman,
const std::atomic<bool>& interruptMsgProc,
bool enable_bip61)
1578 LogPrintf(
"dropmessagestest DROPPING RECV MESSAGE\n");
1587 if (pfrom->
nVersion >= NO_BLOOM_VERSION) {
1601 std::string strMsg;
unsigned char ccode; std::string strReason;
1604 std::ostringstream ss;
1605 ss << strMsg <<
" code " <<
itostr(ccode) <<
": " << strReason;
1611 ss <<
": hash " << hash.
ToString();
1614 }
catch (
const std::ios_base::failure&) {
1616 LogPrint(
BCLog::NET,
"Unparseable reject message received\n");
1637 uint64_t nNonce = 1;
1638 uint64_t nServiceInt;
1642 std::string strSubVer;
1643 std::string cleanSubVer;
1644 int nStartingHeight = -1;
1647 vRecv >> nVersion >> nServiceInt >> nTime >> addrMe;
1648 nSendVersion = std::min(nVersion, PROTOCOL_VERSION);
1665 if (nVersion < MIN_PEER_PROTO_VERSION) {
1667 LogPrint(
BCLog::NET,
"peer=%d using obsolete version %i; disconnecting\n", pfrom->
GetId(), nVersion);
1670 strprintf(
"Version must be %d or greater", MIN_PEER_PROTO_VERSION)));
1677 vRecv >> addrFrom >> nNonce;
1678 if (!vRecv.
empty()) {
1682 if (!vRecv.
empty()) {
1683 vRecv >> nStartingHeight;
1690 LogPrintf(
"connected to self at %s, disconnecting\n", pfrom->
addr.
ToString());
1695 if (pfrom->
fInbound && addrMe.IsRoutable())
1733 State(pfrom->
GetId())->fHaveWitness =
true;
1739 UpdatePreferredDownload(pfrom, State(pfrom->
GetId()));
1769 std::string remoteAddr;
1773 LogPrint(
BCLog::NET,
"receive version message: %s: version %d, blocks=%d, us=%s, peer=%d%s\n",
1778 int64_t nTimeOffset = nTime -
GetTime();
1784 CDataStream finalAlert(
ParseHex(
"60010000000000000000000000ffffff7f00000000ffffff7ffeffff7f01ffffff7f00000000ffffff7f00ffffff7f002f555247454e543a20416c657274206b657920636f6d70726f6d697365642c2075706772616465207265717569726564004630440220653febd6410f470f6bae11cad19c48413becb1ac2c17f908fd0fd53bdc3abd5202206d0e9c96fe88d4a0f01ed9dedae2b6f9e00da94cad0fecaae66ecf689bf71b50"),
SER_NETWORK, PROTOCOL_VERSION);
1813 State(pfrom->
GetId())->fCurrentlyConnected =
true;
1814 LogPrintf(
"New outbound peer connected: version: %d, blocks=%d, peer=%d%s\n",
1819 if (pfrom->
nVersion >= SENDHEADERS_VERSION) {
1826 if (pfrom->
nVersion >= SHORT_IDS_BLOCKS_VERSION) {
1832 bool fAnnounceUsingCMPCTBLOCK =
false;
1833 uint64_t nCMPCTBLOCKVersion = 2;
1836 nCMPCTBLOCKVersion = 1;
1851 std::vector<CAddress> vAddr;
1857 if (vAddr.size() > 1000)
1865 std::vector<CAddress> vAddrOk;
1867 int64_t nSince = nNow - 10 * 60;
1870 if (interruptMsgProc)
1876 if (!MayHaveUsefulAddressDB(addr.
nServices) && !HasAllDesirableServiceFlags(addr.
nServices))
1879 if (addr.
nTime <= 100000000 || addr.
nTime > nNow + 10 * 60)
1880 addr.
nTime = nNow - 5 * 24 * 60 * 60;
1886 RelayAddress(addr, fReachable, connman);
1890 vAddrOk.push_back(addr);
1893 if (vAddr.size() < 1000)
1902 State(pfrom->
GetId())->fPreferHeaders =
true;
1907 bool fAnnounceUsingCMPCTBLOCK =
false;
1908 uint64_t nCMPCTBLOCKVersion = 0;
1909 vRecv >> fAnnounceUsingCMPCTBLOCK >> nCMPCTBLOCKVersion;
1913 if (!State(pfrom->
GetId())->fProvidesHeaderAndIDs) {
1914 State(pfrom->
GetId())->fProvidesHeaderAndIDs =
true;
1915 State(pfrom->
GetId())->fWantsCmpctWitness = nCMPCTBLOCKVersion == 2;
1917 if (State(pfrom->
GetId())->fWantsCmpctWitness == (nCMPCTBLOCKVersion == 2))
1918 State(pfrom->
GetId())->fPreferHeaderAndIDs = fAnnounceUsingCMPCTBLOCK;
1919 if (!State(pfrom->
GetId())->fSupportsDesiredCmpctVersion) {
1921 State(pfrom->
GetId())->fSupportsDesiredCmpctVersion = (nCMPCTBLOCKVersion == 2);
1923 State(pfrom->
GetId())->fSupportsDesiredCmpctVersion = (nCMPCTBLOCKVersion == 1);
1930 std::vector<CInv> vInv;
1932 if (vInv.size() > MAX_INV_SZ)
1943 fBlocksOnly =
false;
1947 uint32_t nFetchFlags = GetFetchFlags(pfrom);
1949 for (
CInv &inv : vInv)
1951 if (interruptMsgProc)
1954 bool fAlreadyHave = AlreadyHave(inv);
1955 LogPrint(
BCLog::NET,
"got inv: %s %s peer=%d\n", inv.
ToString(), fAlreadyHave ?
"have" :
"new", pfrom->
GetId());
1958 inv.
type |= nFetchFlags;
1962 UpdateBlockAvailability(pfrom->
GetId(), inv.
hash);
1987 std::vector<CInv> vInv;
1989 if (vInv.size() > MAX_INV_SZ)
1996 LogPrint(
BCLog::NET,
"received getdata (%u invsz) peer=%d\n", vInv.size(), pfrom->
GetId());
1998 if (vInv.size() > 0) {
1999 LogPrint(
BCLog::NET,
"received getdata for: %s peer=%d\n", vInv[0].ToString(), pfrom->
GetId());
2003 ProcessGetData(pfrom, chainparams, connman, interruptMsgProc);
2010 vRecv >> locator >> hashStop;
2012 if (locator.
vHave.size() > MAX_LOCATOR_SZ) {
2013 LogPrint(
BCLog::NET,
"getblocks locator size %lld > %d, disconnect peer=%d\n", locator.
vHave.size(), MAX_LOCATOR_SZ, pfrom->
GetId());
2026 std::shared_ptr<const CBlock> a_recent_block;
2028 LOCK(cs_most_recent_block);
2029 a_recent_block = most_recent_block;
2046 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());
2079 std::shared_ptr<const CBlock> recent_block;
2081 LOCK(cs_most_recent_block);
2082 if (most_recent_block_hash == req.blockhash)
2083 recent_block = most_recent_block;
2087 SendBlockTransactions(*recent_block, req, pfrom, connman);
2095 LogPrint(
BCLog::NET,
"Peer %d sent us a getblocktxn for a block we don't have\n", pfrom->
GetId());
2107 LogPrint(
BCLog::NET,
"Peer %d sent us a getblocktxn for a block > %i deep\n", pfrom->
GetId(), MAX_BLOCKTXN_DEPTH);
2110 inv.hash = req.blockhash;
2120 SendBlockTransactions(block, req, pfrom, connman);
2127 vRecv >> locator >> hashStop;
2129 if (locator.
vHave.size() > MAX_LOCATOR_SZ) {
2130 LogPrint(
BCLog::NET,
"getheaders locator size %lld > %d, disconnect peer=%d\n", locator.
vHave.size(), MAX_LOCATOR_SZ, pfrom->
GetId());
2137 LogPrint(
BCLog::NET,
"Ignoring getheaders from peer=%d because node is in initial block download\n", pfrom->
GetId());
2141 CNodeState *nodestate = State(pfrom->
GetId());
2151 if (!BlockRequestAllowed(pindex, chainparams.
GetConsensus())) {
2152 LogPrint(
BCLog::NET,
"%s: ignoring request from peer=%i for old block header that isn't in the main chain\n", __func__, pfrom->
GetId());
2165 std::vector<CBlock> vHeaders;
2166 int nLimit = MAX_HEADERS_RESULTS;
2167 LogPrint(
BCLog::NET,
"getheaders %d to %s from peer=%d\n", (pindex ? pindex->nHeight : -1), hashStop.IsNull() ?
"end" : hashStop.ToString(), pfrom->
GetId());
2170 vHeaders.push_back(pindex->GetBlockHeader());
2171 if (--nLimit <= 0 || pindex->GetBlockHash() == hashStop)
2186 nodestate->pindexBestHeaderSent = pindex ? pindex :
chainActive.
Tip();
2196 LogPrint(
BCLog::NET,
"transaction sent in violation of protocol peer=%d\n", pfrom->
GetId());
2200 std::deque<COutPoint> vWorkQueue;
2201 std::vector<uint256> vEraseQueue;
2211 bool fMissingInputs =
false;
2217 std::list<CTransactionRef> lRemovedTxn;
2219 if (!AlreadyHave(inv) &&
2222 RelayTransaction(tx, connman);
2223 for (
unsigned int i = 0; i < tx.
vout.size(); i++) {
2224 vWorkQueue.emplace_back(inv.hash, i);
2229 LogPrint(
BCLog::MEMPOOL,
"AcceptToMemoryPool: peer=%d: accepted %s (poolsz %u txn, %u kB)\n",
2235 std::set<NodeId> setMisbehaving;
2236 while (!vWorkQueue.empty()) {
2237 auto itByPrev = mapOrphanTransactionsByPrev.find(vWorkQueue.front());
2238 vWorkQueue.pop_front();
2239 if (itByPrev == mapOrphanTransactionsByPrev.end())
2241 for (
auto mi = itByPrev->second.begin();
2242 mi != itByPrev->second.end();
2248 NodeId fromPeer = (*mi)->second.fromPeer;
2249 bool fMissingInputs2 =
false;
2256 if (setMisbehaving.count(fromPeer))
2260 RelayTransaction(orphanTx, connman);
2261 for (
unsigned int i = 0; i < orphanTx.
vout.size(); i++) {
2262 vWorkQueue.emplace_back(orphanHash, i);
2264 vEraseQueue.push_back(orphanHash);
2266 else if (!fMissingInputs2)
2269 if (stateDummy.
IsInvalid(nDos) && nDos > 0)
2273 setMisbehaving.insert(fromPeer);
2279 vEraseQueue.push_back(orphanHash);
2284 assert(recentRejects);
2285 recentRejects->insert(orphanHash);
2292 for (
const uint256& hash : vEraseQueue)
2293 EraseOrphanTx(hash);
2295 else if (fMissingInputs)
2297 bool fRejectedParents =
false;
2300 fRejectedParents =
true;
2304 if (!fRejectedParents) {
2305 uint32_t nFetchFlags = GetFetchFlags(pfrom);
2309 if (!AlreadyHave(_inv)) pfrom->
AskFor(_inv);
2314 unsigned int nMaxOrphanTx = (
unsigned int)std::max((int64_t)0,
gArgs.
GetArg(
"-maxorphantx", DEFAULT_MAX_ORPHAN_TRANSACTIONS));
2317 LogPrint(
BCLog::MEMPOOL,
"mapOrphan overflow, removed %u tx\n", nEvicted);
2323 recentRejects->insert(tx.
GetHash());
2330 assert(recentRejects);
2331 recentRejects->insert(tx.
GetHash());
2332 if (RecursiveDynamicUsage(*ptx) < 100000) {
2333 AddToCompactExtraTransactions(ptx);
2335 }
else if (tx.
HasWitness() && RecursiveDynamicUsage(*ptx) < 100000) {
2336 AddToCompactExtraTransactions(ptx);
2349 if (!state.
IsInvalid(nDoS) || nDoS == 0) {
2350 LogPrintf(
"Force relaying tx %s from whitelisted peer=%d\n", tx.
GetHash().
ToString(), pfrom->
GetId());
2351 RelayTransaction(tx, connman);
2359 AddToCompactExtraTransactions(removedTx);
2369 state.
GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), inv.hash));
2381 vRecv >> cmpctblock;
2383 bool received_new_header =
false;
2396 received_new_header =
true;
2409 LogPrint(
BCLog::NET,
"Peer %d sent us invalid header via cmpctblock\n", pfrom->
GetId());
2419 bool fProcessBLOCKTXN =
false;
2424 bool fRevertToHeaderProcessing =
false;
2428 std::shared_ptr<CBlock> pblock = std::make_shared<CBlock>();
2429 bool fBlockReconstructed =
false;
2437 CNodeState *nodestate = State(pfrom->
GetId());
2442 nodestate->m_last_block_announcement =
GetTime();
2445 std::map<uint256, std::pair<NodeId, std::list<QueuedBlock>::iterator> >::iterator blockInFlightIt = mapBlocksInFlight.find(pindex->
GetBlockHash());
2446 bool fAlreadyInFlight = blockInFlightIt != mapBlocksInFlight.end();
2453 if (fAlreadyInFlight) {
2456 std::vector<CInv> vInv(1);
2457 vInv[0] =
CInv(
MSG_BLOCK | GetFetchFlags(pfrom), cmpctblock.header.GetHash());
2464 if (!fAlreadyInFlight && !CanDirectFetch(chainparams.GetConsensus()))
2467 if (
IsWitnessEnabled(pindex->
pprev, chainparams.GetConsensus()) && !nodestate->fSupportsDesiredCmpctVersion) {
2476 if ((!fAlreadyInFlight && nodestate->nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER) ||
2477 (fAlreadyInFlight && blockInFlightIt->second.first == pfrom->
GetId())) {
2478 std::list<QueuedBlock>::iterator* queuedBlockIt =
nullptr;
2479 if (!MarkBlockAsInFlight(pfrom->
GetId(), pindex->
GetBlockHash(), pindex, &queuedBlockIt)) {
2480 if (!(*queuedBlockIt)->partialBlock)
2484 LogPrint(
BCLog::NET,
"Peer sent us compact block we were already syncing!\n");
2497 std::vector<CInv> vInv(1);
2498 vInv[0] =
CInv(
MSG_BLOCK | GetFetchFlags(pfrom), cmpctblock.header.GetHash());
2504 for (
size_t i = 0; i < cmpctblock.BlockTxCount(); i++) {
2511 txn.
blockhash = cmpctblock.header.GetHash();
2513 fProcessBLOCKTXN =
true;
2525 ReadStatus status = tempBlock.InitData(cmpctblock, vExtraTxnForCompact);
2530 std::vector<CTransactionRef> dummy;
2531 status = tempBlock.FillBlock(*pblock, dummy);
2533 fBlockReconstructed =
true;
2537 if (fAlreadyInFlight) {
2540 std::vector<CInv> vInv(1);
2541 vInv[0] =
CInv(
MSG_BLOCK | GetFetchFlags(pfrom), cmpctblock.header.GetHash());
2546 fRevertToHeaderProcessing =
true;
2551 if (fProcessBLOCKTXN)
2552 return ProcessMessage(pfrom,
NetMsgType::BLOCKTXN, blockTxnMsg, nTimeReceived, chainparams, connman, interruptMsgProc, enable_bip61);
2554 if (fRevertToHeaderProcessing) {
2560 return ProcessHeadersMessage(pfrom, connman, {cmpctblock.header}, chainparams,
false);
2563 if (fBlockReconstructed) {
2568 mapBlockSource.emplace(pblock->GetHash(), std::make_pair(pfrom->
GetId(),
false));
2570 bool fNewBlock =
false;
2585 mapBlockSource.erase(pblock->GetHash());
2593 MarkBlockAsReceived(pblock->GetHash());
2604 std::shared_ptr<CBlock> pblock = std::make_shared<CBlock>();
2605 bool fBlockRead =
false;
2609 std::map<uint256, std::pair<NodeId, std::list<QueuedBlock>::iterator> >::iterator it = mapBlocksInFlight.find(resp.blockhash);
2610 if (it == mapBlocksInFlight.end() || !it->second.second->partialBlock ||
2611 it->second.first != pfrom->
GetId()) {
2612 LogPrint(
BCLog::NET,
"Peer %d sent us block transactions for block we weren't expecting\n", pfrom->
GetId());
2619 MarkBlockAsReceived(resp.blockhash);
2624 std::vector<CInv> invs;
2625 invs.push_back(
CInv(
MSG_BLOCK | GetFetchFlags(pfrom), resp.blockhash));
2645 MarkBlockAsReceived(resp.blockhash);
2652 mapBlockSource.emplace(resp.blockhash, std::make_pair(pfrom->
GetId(),
false));
2656 bool fNewBlock =
false;
2668 mapBlockSource.erase(pblock->GetHash());
2676 std::vector<CBlockHeader> headers;
2680 if (nCount > MAX_HEADERS_RESULTS) {
2685 headers.resize(nCount);
2686 for (
unsigned int n = 0; n < nCount; n++) {
2687 vRecv >> headers[n];
2696 return ProcessHeadersMessage(pfrom, connman, headers, chainparams, should_punish);
2701 std::shared_ptr<CBlock> pblock = std::make_shared<CBlock>();
2704 LogPrint(
BCLog::NET,
"received block %s peer=%d\n", pblock->GetHash().ToString(), pfrom->
GetId());
2706 bool forceProcessing =
false;
2707 const uint256 hash(pblock->GetHash());
2712 forceProcessing |= MarkBlockAsReceived(hash);
2715 mapBlockSource.emplace(hash, std::make_pair(pfrom->
GetId(),
true));
2717 bool fNewBlock =
false;
2723 mapBlockSource.erase(pblock->GetHash());
2735 LogPrint(
BCLog::NET,
"Ignoring \"getaddr\" from outbound connection. peer=%d\n", pfrom->
GetId());
2742 LogPrint(
BCLog::NET,
"Ignoring repeated \"getaddr\". peer=%d\n", pfrom->
GetId());
2758 LogPrint(
BCLog::NET,
"mempool request with bloom filters disabled, disconnect peer=%d\n", pfrom->
GetId());
2765 LogPrint(
BCLog::NET,
"mempool request with bandwidth limit reached, disconnect peer=%d\n", pfrom->
GetId());
2776 if (pfrom->
nVersion > BIP0031_VERSION)
2797 int64_t pingUsecEnd = nTimeReceived;
2800 bool bPingFinished =
false;
2801 std::string sProblem;
2803 if (nAvail >=
sizeof(nonce)) {
2810 bPingFinished =
true;
2812 if (pingUsecTime > 0) {
2818 sProblem =
"Timing mishap";
2822 sProblem =
"Nonce mismatch";
2825 bPingFinished =
true;
2826 sProblem =
"Nonce zero";
2830 sProblem =
"Unsolicited pong without ping";
2834 bPingFinished =
true;
2835 sProblem =
"Short payload";
2838 if (!(sProblem.empty())) {
2839 LogPrint(
BCLog::NET,
"pong peer=%d: %s, %x expected, %x received, %u bytes\n",
2846 if (bPingFinished) {
2856 if (!
filter.IsWithinSizeConstraints())
2866 pfrom->
pfilter->UpdateEmptyFull();
2873 std::vector<unsigned char> vData;
2879 if (vData.size() > MAX_SCRIPT_ELEMENT_SIZE) {
2884 pfrom->
pfilter->insert(vData);
2907 vRecv >> newFeeFilter;
2913 LogPrint(
BCLog::NET,
"received: feefilter of %s from peer=%d\n",
CFeeRate(newFeeFilter).ToString(), pfrom->
GetId());
2932 CNodeState &state = *State(pnode->
GetId());
2935 for (
const CBlockReject& reject : state.rejects) {
2939 state.rejects.clear();
2941 if (state.fShouldBan) {
2942 state.fShouldBan =
false;
2944 LogPrintf(
"Warning: not punishing whitelisted peer %s!\n", pnode->
addr.
ToString());
2946 LogPrintf(
"Warning: not punishing manually-connected peer %s!\n", pnode->
addr.
ToString());
2950 LogPrintf(
"Warning: not banning local peer %s!\n", pnode->
addr.
ToString());
2972 bool fMoreWork =
false;
2975 ProcessGetData(pfrom, chainparams,
connman, interruptMsgProc);
2987 std::list<CNetMessage> msgs;
3022 const uint256& hash = msg.GetMessageHash();
3025 LogPrint(
BCLog::NET,
"%s(%s, %u bytes): CHECKSUM ERROR expected %s was %s\n", __func__,
3036 fRet = ProcessMessage(pfrom, strCommand, vRecv, msg.nTime, chainparams,
connman, interruptMsgProc,
m_enable_bip61);
3037 if (interruptMsgProc)
3042 catch (
const std::ios_base::failure& e)
3047 if (strstr(e.what(),
"end of data"))
3050 LogPrint(
BCLog::NET,
"%s(%s, %u bytes): Exception '%s' caught, normally caused by a message being shorter than its stated length\n", __func__,
SanitizeString(strCommand), nMessageSize, e.what());
3052 else if (strstr(e.what(),
"size too large"))
3055 LogPrint(
BCLog::NET,
"%s(%s, %u bytes): Exception '%s' caught\n", __func__,
SanitizeString(strCommand), nMessageSize, e.what());
3057 else if (strstr(e.what(),
"non-canonical ReadCompactSize()"))
3060 LogPrint(
BCLog::NET,
"%s(%s, %u bytes): Exception '%s' caught\n", __func__,
SanitizeString(strCommand), nMessageSize, e.what());
3067 catch (
const std::exception& e) {
3087 CNodeState &state = *State(pto->
GetId());
3090 if (!state.m_chain_sync.m_protect && IsOutboundDisconnectionCandidate(pto) && state.fSyncStarted) {
3097 if (state.pindexBestKnownBlock !=
nullptr && state.pindexBestKnownBlock->nChainWork >=
chainActive.
Tip()->
nChainWork) {
3098 if (state.m_chain_sync.m_timeout != 0) {
3099 state.m_chain_sync.m_timeout = 0;
3100 state.m_chain_sync.m_work_header =
nullptr;
3101 state.m_chain_sync.m_sent_getheaders =
false;
3103 }
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)) {
3108 state.m_chain_sync.m_timeout = time_in_seconds + CHAIN_SYNC_TIMEOUT;
3110 state.m_chain_sync.m_sent_getheaders =
false;
3111 }
else if (state.m_chain_sync.m_timeout > 0 && time_in_seconds > state.m_chain_sync.m_timeout) {
3115 if (state.m_chain_sync.m_sent_getheaders) {
3117 LogPrintf(
"Disconnecting outbound peer %d for old chain, best known block = %s\n", pto->
GetId(), state.pindexBestKnownBlock !=
nullptr ? state.pindexBestKnownBlock->GetBlockHash().ToString() :
"<none>");
3120 assert(state.m_chain_sync.m_work_header);
3121 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());
3123 state.m_chain_sync.m_sent_getheaders =
true;
3124 constexpr int64_t HEADERS_RESPONSE_TIME = 120;
3130 state.m_chain_sync.m_timeout = time_in_seconds + HEADERS_RESPONSE_TIME;
3140 if (extra_peers > 0) {
3146 int64_t oldest_block_announcement = std::numeric_limits<int64_t>::max();
3152 if (!IsOutboundDisconnectionCandidate(pnode) || pnode->
fDisconnect)
return;
3153 CNodeState *state = State(pnode->
GetId());
3154 if (state ==
nullptr)
return;
3156 if (state->m_chain_sync.m_protect)
return;
3157 if (state->m_last_block_announcement < oldest_block_announcement || (state->m_last_block_announcement == oldest_block_announcement && pnode->
GetId() > worst_peer)) {
3158 worst_peer = pnode->
GetId();
3159 oldest_block_announcement = state->m_last_block_announcement;
3162 if (worst_peer != -1) {
3171 CNodeState &state = *State(pnode->
GetId());
3172 if (time_in_seconds - pnode->
nTimeConnected > MINIMUM_CONNECT_TIME && state.nBlocksInFlight == 0) {
3173 LogPrint(
BCLog::NET,
"disconnecting extra outbound peer=%d (last block announcement received at time %d)\n", pnode->
GetId(), oldest_block_announcement);
3177 LogPrint(
BCLog::NET,
"keeping outbound peer=%d chosen for eviction (connect time: %d, blocks_in_flight: %d)\n", pnode->
GetId(), pnode->
nTimeConnected, state.nBlocksInFlight);
3197 if (
connman ==
nullptr)
return;
3199 int64_t time_in_seconds =
GetTime();
3207 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);
3217 class CompareInvMempoolOrder
3221 explicit CompareInvMempoolOrder(
CTxMemPool *_mempool)
3226 bool operator()(std::set<uint256>::iterator a, std::set<uint256>::iterator b)
3249 bool pingSend =
false;
3260 while (nonce == 0) {
3265 if (pto->
nVersion > BIP0031_VERSION) {
3281 CNodeState &state = *State(pto->
GetId());
3295 std::vector<CAddress> vAddr;
3302 vAddr.push_back(addr);
3304 if (vAddr.size() >= 1000)
3322 bool fFetch = state.fPreferredDownload || (nPreferredDownload == 0 && !pto->
fClient && !pto->
fOneShot);
3326 state.fSyncStarted =
true;
3337 if (pindexStart->
pprev)
3338 pindexStart = pindexStart->
pprev;
3364 std::vector<CBlock> vHeaders;
3365 bool fRevertToInv = ((!state.fPreferHeaders &&
3369 ProcessBlockAvailability(pto->
GetId());
3371 if (!fRevertToInv) {
3372 bool fFoundStartingHeader =
false;
3381 fRevertToInv =
true;
3384 if (pBestIndex !=
nullptr && pindex->
pprev != pBestIndex) {
3396 fRevertToInv =
true;
3399 pBestIndex = pindex;
3400 if (fFoundStartingHeader) {
3403 }
else if (PeerHasHeader(&state, pindex)) {
3405 }
else if (pindex->
pprev ==
nullptr || PeerHasHeader(&state, pindex->
pprev)) {
3408 fFoundStartingHeader =
true;
3413 fRevertToInv =
true;
3418 if (!fRevertToInv && !vHeaders.empty()) {
3419 if (vHeaders.size() == 1 && state.fPreferHeaderAndIDs) {
3422 LogPrint(
BCLog::NET,
"%s sending header-and-ids %s to peer=%d\n", __func__,
3423 vHeaders.front().GetHash().ToString(), pto->
GetId());
3425 int nSendFlags = state.fWantsCmpctWitness ? 0 : SERIALIZE_TRANSACTION_NO_WITNESS;
3427 bool fGotBlockFromCache =
false;
3429 LOCK(cs_most_recent_block);
3430 if (most_recent_block_hash == pBestIndex->
GetBlockHash()) {
3431 if (state.fWantsCmpctWitness || !fWitnessesPresentInMostRecentCompactBlock)
3437 fGotBlockFromCache =
true;
3440 if (!fGotBlockFromCache) {
3447 state.pindexBestHeaderSent = pBestIndex;
3448 }
else if (state.fPreferHeaders) {
3449 if (vHeaders.size() > 1) {
3450 LogPrint(
BCLog::NET,
"%s: %u headers, range (%s, %s), to peer=%d\n", __func__,
3452 vHeaders.front().GetHash().ToString(),
3453 vHeaders.back().GetHash().ToString(), pto->
GetId());
3455 LogPrint(
BCLog::NET,
"%s: sending header %s to peer=%d\n", __func__,
3456 vHeaders.front().GetHash().ToString(), pto->
GetId());
3459 state.pindexBestHeaderSent = pBestIndex;
3461 fRevertToInv =
true;
3476 LogPrint(
BCLog::NET,
"Announcing block %s not on main chain (tip=%s)\n",
3481 if (!PeerHasHeader(&state, pindex)) {
3483 LogPrint(
BCLog::NET,
"%s: sending inv peer=%d hash=%s\n", __func__,
3494 std::vector<CInv> vInv;
3502 if (vInv.size() == MAX_INV_SZ) {
3512 fSendTrickle =
true;
3539 for (
const auto& txinfo : vtxinfo) {
3540 const uint256& hash = txinfo.tx->GetHash();
3544 if (txinfo.feeRate.GetFeePerK() < filterrate)
3548 if (!pto->
pfilter->IsRelevantAndUpdate(*txinfo.tx))
continue;
3551 vInv.push_back(inv);
3552 if (vInv.size() == MAX_INV_SZ) {
3563 std::vector<std::set<uint256>::iterator> vInvTx;
3566 vInvTx.push_back(it);
3575 CompareInvMempoolOrder compareInvMempoolOrder(&
mempool);
3576 std::make_heap(vInvTx.begin(), vInvTx.end(), compareInvMempoolOrder);
3579 unsigned int nRelayedTransactions = 0;
3581 while (!vInvTx.empty() && nRelayedTransactions < INVENTORY_BROADCAST_MAX) {
3583 std::pop_heap(vInvTx.begin(), vInvTx.end(), compareInvMempoolOrder);
3584 std::set<uint256>::iterator it = vInvTx.back();
3598 if (filterrate && txinfo.feeRate.GetFeePerK() < filterrate) {
3601 if (pto->
pfilter && !pto->
pfilter->IsRelevantAndUpdate(*txinfo.tx))
continue;
3604 nRelayedTransactions++;
3607 while (!vRelayExpiration.empty() && vRelayExpiration.front().first < nNow)
3609 mapRelay.erase(vRelayExpiration.front().second);
3610 vRelayExpiration.pop_front();
3613 auto ret = mapRelay.insert(std::make_pair(hash, std::move(txinfo.tx)));
3615 vRelayExpiration.
push_back(std::make_pair(nNow + 15 * 60 * 1000000,
ret.first));
3618 if (vInv.size() == MAX_INV_SZ) {
3631 if (state.nStallingSince && state.nStallingSince < nNow - 1000000 * BLOCK_STALLING_TIMEOUT) {
3635 LogPrintf(
"Peer=%d is stalling block download, disconnecting\n", pto->
GetId());
3644 if (state.vBlocksInFlight.size() > 0) {
3645 QueuedBlock &queuedBlock = state.vBlocksInFlight.front();
3646 int nOtherPeersWithValidatedDownloads = nPeersWithValidatedDownloads - (state.nBlocksInFlightValidHeaders > 0);
3647 if (nNow > state.nDownloadingSince + consensusParams.
nPowTargetSpacing * (BLOCK_DOWNLOAD_TIMEOUT_BASE + BLOCK_DOWNLOAD_TIMEOUT_PER_PEER * nOtherPeersWithValidatedDownloads)) {
3648 LogPrintf(
"Timeout downloading block %s from peer=%d, disconnecting\n", queuedBlock.hash.ToString(), pto->
GetId());
3654 if (state.fSyncStarted && state.nHeadersSyncTimeout < std::numeric_limits<int64_t>::max()) {
3657 if (nNow > state.nHeadersSyncTimeout && nSyncStarted == 1 && (nPreferredDownload - state.fPreferredDownload >= 1)) {
3664 LogPrintf(
"Timeout downloading headers from peer=%d, disconnecting\n", pto->
GetId());
3668 LogPrintf(
"Timeout downloading headers from whitelisted peer=%d, not disconnecting\n", pto->
GetId());
3674 state.fSyncStarted =
false;
3676 state.nHeadersSyncTimeout = 0;
3682 state.nHeadersSyncTimeout = std::numeric_limits<int64_t>::max();
3693 std::vector<CInv> vGetData;
3695 std::vector<const CBlockIndex*> vToDownload;
3697 FindNextBlocksToDownload(pto->
GetId(), MAX_BLOCKS_IN_TRANSIT_PER_PEER - state.nBlocksInFlight, vToDownload, staller, consensusParams);
3699 uint32_t nFetchFlags = GetFetchFlags(pto);
3705 if (state.nBlocksInFlight == 0 && staller != -1) {
3706 if (State(staller)->nStallingSince == 0) {
3707 State(staller)->nStallingSince = nNow;
3708 LogPrint(
BCLog::NET,
"Stall started peer=%d\n", staller);
3719 if (!AlreadyHave(inv))
3722 vGetData.push_back(inv);
3723 if (vGetData.size() >= 1000)
3734 if (!vGetData.empty())
3746 static CFeeRate default_feerate(DEFAULT_MIN_RELAY_TX_FEE);
3748 CAmount filterToSend = filterRounder.
round(currentFilter);
3760 (currentFilter < 3 * pto->lastSentFeeFilter / 4 || currentFilter > 4 * pto->
lastSentFeeFilter / 3)) {
3774 mapOrphanTransactions.clear();
3775 mapOrphanTransactionsByPrev.clear();
arith_uint256 nChainWork
(memory only) Total amount of work (expected number of hashes) in the chain up to and including this ...
enum ReadStatus_t ReadStatus
const char * PING
The ping message is sent periodically to help confirm that the receiving peer is still connected...
void Misbehaving(NodeId nodeid, int howmuch, const std::string &message="") EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Increase a node's misbehavior score.
std::atomic< uint64_t > nPingNonceSent
bool IsArgSet(const std::string &strArg) const
Return true if the given argument has been manually set.
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
int64_t nextSendTimeFeeFilter
int GetSendVersion() const
const char * BLOCKTXN
Contains a BlockTransactions.
bool fPruneMode
True if we're running in -prune mode.
ReadStatus FillBlock(CBlock &block, const std::vector< CTransactionRef > &vtx_missing)
ServiceFlags
nServices flags
CCriticalSection cs_filter
int64_t GetBlockTime() const
Describes a place in the block chain to another node such that if the other node doesn't have the sam...
CBlockIndex * pprev
pointer to the index of the predecessor of this block
std::vector< TxMempoolInfo > infoAll() const
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 ...
#define TRY_LOCK(cs, name)
uint32_t nStatus
Verification status of this block. See enum BlockStatus.
size_t GetAddressCount() const
void SetIP(const CNetAddr &ip)
void WakeMessageHandler()
void SetServices(const CService &addr, ServiceFlags nServices)
std::string ToString() const
std::list< CNetMessage > vProcessMsg
uint64_t ReadCompactSize(Stream &is)
const char * GETADDR
The getaddr message requests an addr message from the receiving node, preferably one with lots of IP ...
void UpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload) override
Overridden from CValidationInterface.
std::vector< uint16_t > indexes
int GetRecvVersion() const
void CheckForStaleTipAndEvictPeers(const Consensus::Params &consensusParams)
Evict extra outbound peers.
bool SendMessages(CNode *pto) override EXCLUSIVE_LOCKS_REQUIRED(pto -> cs_sendProcessing)
Send queued protocol messages to be sent to a give node.
void insert(const std::vector< unsigned char > &vKey)
bool GetNodeStateStats(NodeId nodeid, CNodeStateStats &stats)
Get statistics from node state.
size_t DynamicMemoryUsage() const
CCriticalSection g_cs_orphans
reverse_range< T > reverse_iterate(T &x)
const char * SENDCMPCT
Contains a 1-byte bool and 8-byte LE version number.
const CBlockIndex * LastCommonAncestor(const CBlockIndex *pa, const CBlockIndex *pb)
Find the last common ancestor two blocks have.
UniValue ret(UniValue::VARR)
PeerLogicValidation(CConnman *connman, CScheduler &scheduler, bool enable_bip61)
TxMempoolInfo info(const uint256 &hash) const
All parent headers found, difficulty matches, timestamp >= median previous, checkpoint.
std::vector< uint256 > vInventoryBlockToSend
bool MoneyRange(const CAmount &nValue)
CBlockHeader GetBlockHeader() const
void AskFor(const CInv &inv)
int Height() const
Return the maximal height in the chain.
BloomFilter is a probabilistic filter which SPV clients provide so that we can filter the transaction...
std::string HexStr(const T itbegin, const T itend, bool fSpaces=false)
CCriticalSection cs_SubVer
bool GetTryNewOutboundPeer()
Only first tx is coinbase, 2 <= coinbase input script length <= 100, transactions valid...
void PushMessage(CNode *pnode, CSerializedNetMsg &&msg)
arith_uint256 nMinimumChainWork
Minimum work we will assume exists on some valid chain.
std::unique_ptr< CBloomFilter > pfilter
void SetVersion(int nVersionIn)
void SetServiceFlagsIBDCache(bool state)
Set the current IBD status in order to figure out the desirable service flags.
const bool m_enable_bip61
Enable BIP61 (sending reject messages)
RollingBloomFilter is a probabilistic "keep track of most recently inserted" set. ...
void PrintExceptionContinue(const std::exception *pex, const char *pszThread)
std::atomic< int64_t > nPingUsecStart
CAddress GetLocalAddress(const CNetAddr *paddrPeer, ServiceFlags nLocalServices)
void scheduleEvery(Function f, int64_t deltaMilliSeconds)
CCriticalSection cs_feeFilter
CChainParams defines various tweakable parameters of a given instance of the Bitcoin system...
Double ended buffer combining vector and stream-like interfaces.
bool GetBoolArg(const std::string &strArg, bool fDefault) const
Return boolean argument or default value.
void SetTryNewOutboundPeer(bool flag)
const uint32_t MSG_WITNESS_FLAG
getdata message type flags
CCriticalSection cs_inventory
void Broadcast(int64_t nBestBlockTime, CConnman *connman)
uint64_t GetLocalNonce() const
bool SeenLocal(const CService &addr)
vote for a local address
std::set< uint256 > setInventoryTxToSend
std::vector< CAddress > vAddrToSend
std::atomic< int > nStartingHeight
class CNetProcessingCleanup instance_of_cnetprocessingcleanup
void PushAddress(const CAddress &_addr, FastRandomContext &insecure_rand)
bool ProcessNewBlock(const CChainParams &chainparams, const std::shared_ptr< const CBlock > pblock, bool fForceProcessing, bool *fNewBlock)
Process an incoming block.
constexpr Span< A > MakeSpan(A(&a)[N])
Create a span to a container exposing data() and size().
void SetRecvVersion(int nVersionIn)
const char * PONG
The pong message replies to a ping message, proving to the pinging node that the ponging node is stil...
std::shared_ptr< const CTransaction > CTransactionRef
std::atomic< int64_t > timeLastMempoolReq
bool ProcessMessages(CNode *pfrom, std::atomic< bool > &interrupt) override
Process protocol messages received from a given node.
const char * HEADERS
The headers message sends one or more block headers to a node which previously requested certain head...
unsigned int nChainTx
(memory only) Number of transactions in the chain up to and including this block. ...
void PushInventory(const CInv &inv)
bool ActivateBestChain(CValidationState &state, const CChainParams &chainparams, std::shared_ptr< const CBlock > pblock)
Find the best known block, and make it the tip of the block chain.
std::atomic< ServiceFlags > nServices
const std::vector< CTxIn > vin
void SetAddrLocal(const CService &addrLocalIn)
May not be called more than once.
int64_t nNextLocalAddrSend
std::deque< CInv > vRecvGetData
const char * INV
The inv message (inventory message) transmits one or more inventories of objects known to the transmi...
bool AcceptToMemoryPool(CTxMemPool &pool, CValidationState &state, const CTransactionRef &tx, bool *pfMissingInputs, std::list< CTransactionRef > *plTxnReplaced, bool bypass_limits, const CAmount nAbsurdFee, bool test_accept)
(try to) add transaction to memory pool plTxnReplaced will be appended to with all transactions repla...
bool AddOrphanTx(const CTransactionRef &tx, NodeId peer) EXCLUSIVE_LOCKS_REQUIRED(g_cs_orphans)
bool ForNode(NodeId id, std::function< bool(CNode *pnode)> func)
bool ProcessNewBlockHeaders(const std::vector< CBlockHeader > &headers, CValidationState &state, const CChainParams &chainparams, const CBlockIndex **ppindex, CBlockHeader *first_invalid)
Process incoming block headers.
bool contains(const std::vector< unsigned char > &vKey) const
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::unique_ptr< CCoinsViewCache > pcoinsTip
Global variable that points to the active CCoinsView (protected by cs_main)
int64_t CAmount
Amount in satoshis (Can be negative)
uint256 GetBlockHash() const
bool IsValid(enum BlockStatus nUpTo=BLOCK_VALID_TRANSACTIONS) const
Check whether this block index entry is valid up to the passed validity level.
#define AssertLockHeld(cs)
std::atomic< int64_t > nPingUsecTime
std::atomic< int64_t > nMinPingUsecTime
int GetMyStartingHeight() const
void Ban(const CNetAddr &netAddr, const BanReason &reason, int64_t bantimeoffset=0, bool sinceUnixEpoch=false)
ServiceFlags GetLocalServices() const
Outputs do not overspend inputs, no double spends, coinbase output ok, no immature coinbase spends...
Used to relay blocks as header + vector<merkle branch> to filtered nodes.
const char * GETHEADERS
The getheaders message requests a headers message that provides block headers starting from a particu...
if(!params[0].isNull()) nMinDepth
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...
bool push_back(const UniValue &val)
Scripts & signatures ok. Implies all parents are also at least SCRIPTS.
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).
bool exists(const uint256 &hash) const
An input of a transaction.
const uint256 & GetHash() const
bool IsPeerAddrLocalGood(CNode *pnode)
bool Contains(const CBlockIndex *pindex) const
Efficiently check whether a block is present in this chain.
A combination of a network address (CNetAddr) and a (TCP) port.
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
int64_t nPowTargetSpacing
std::vector< CAddress > GetAddresses()
CRollingBloomFilter filterInventoryKnown
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...
const char * SENDHEADERS
Indicates that a node prefers to receive new block announcements via a "headers" message rather than ...
const char * MEMPOOL
The mempool message requests the TXIDs of transactions that the receiving node has verified as valid ...
std::string GetRejectReason() const
void ForEachNodeThen(Callable &&pre, CallableAfter &&post)
bool IsProxy(const CNetAddr &addr)
const std::vector< CTxOut > vout
A CService with information about it as peer.
bool IsInitialBlockDownload()
Check whether we are doing an initial block download (synchronizing from disk or network) ...
std::map< uint256, COrphanTx > mapOrphanTransactions GUARDED_BY(g_cs_orphans)
std::vector< unsigned char > GetKey() const
CMainSignals & GetMainSignals()
std::vector< uint256 > vBlockHashesToAnnounce
const char * ADDR
The addr (IP address) message relays connection information for peers on the network.
const CMessageHeader::MessageStartChars & MessageStart() const
void AddNewAddresses(const std::vector< CAddress > &vAddr, const CAddress &addrFrom, int64_t nTimePenalty=0)
bool GetNetworkActive() const
const char * FILTERCLEAR
The filterclear message tells the receiving peer to remove a previously-set bloom filter...
std::atomic_bool fImporting
std::string ToString() const
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...
CSipHasher GetDeterministicRandomizer(uint64_t id) const
Get a unique deterministic randomizer.
Parameters that influence chain consensus.
An outpoint - a combination of a transaction hash and an index n into its vout.
const char * BLOCK
The block message transmits a single serialized block.
std::atomic_bool fDisconnect
std::string strSubVersion
Subversion as sent to the P2P network in version messages.
const char * FEEFILTER
The feefilter message tells the receiving peer not to inv us any txs which do not meet the specified ...
CFeeRate GetMinFee(size_t sizelimit) const
The minimum fee to get into the mempool, which may itself not be enough for larger-sized transactions...
void ForEachNode(Callable &&func)
CRollingBloomFilter addrKnown
unsigned int GetReceiveFloodSize() const
const char * REJECT
The reject message informs the receiving node that one of its previous messages has been rejected...
bool CheckIncomingNonce(uint64_t nonce)
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.
unsigned int LimitOrphanTxSize(unsigned int nMaxOrphans)
const char * GETBLOCKS
The getblocks message requests an inv message that provides block header hashes starting from a parti...
const int64_t nTimeConnected
int64_t m_stale_tip_check_time
Next time to check for stale tip.
void BlockConnected(const std::shared_ptr< const CBlock > &pblock, const CBlockIndex *pindexConnected, const std::vector< CTransactionRef > &vtxConflicted) override
Overridden from CValidationInterface.
std::atomic_bool fReindex
const char * VERACK
The verack message acknowledges a previously-received version message, informing the connecting node ...
Capture information about block/transaction validation.
std::atomic< bool > fPingQueued
void AddInventoryKnown(const CInv &inv)
bool IsReachable(enum Network net)
check whether a given network is one we can probably connect to
void NewPoWValidBlock(const CBlockIndex *pindex, const std::shared_ptr< const CBlock > &pblock) override
Overridden from CValidationInterface.
#define EXCLUSIVE_LOCKS_REQUIRED(...)
std::vector< CTransactionRef > vtx
std::string FormatStateMessage(const CValidationState &state)
Convert CValidationState to a human-readable message for logging.
const char * CMPCTBLOCK
Contains a CBlockHeaderAndShortTxIDs object - providing a header and list of "short txids"...
CTxMemPool stores valid-according-to-the-current-best-chain transactions that may be included in the ...
std::atomic< int64_t > nLastTXTime
bool CompareDepthAndScore(const uint256 &hasha, const uint256 &hashb)
#define LOCKS_EXCLUDED(...)
const char * VERSION
The version message provides information about the transmitting node to the receiving node at the beg...
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...
const CChainParams & Params()
Return the currently selected parameters.
void UpdateLastBlockAnnounceTime(NodeId node, int64_t time_in_seconds)
bool IsTxAvailable(size_t index) const
std::string GetArg(const std::string &strArg, const std::string &strDefault) const
Return string argument or default value.
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.
CCriticalSection cs_vProcessMsg
void SetSendVersion(int nVersionIn)
CBlockIndex * Tip() const
Returns the index entry for the tip of this chain, or nullptr if none.
void BlockChecked(const CBlock &block, const CValidationState &state) override
Overridden from CValidationInterface.
void SetBestHeight(int height)
#define LIMITED_STRING(obj, n)
void EraseOrphansFor(NodeId peer)
CAmount lastSentFeeFilter
std::atomic< int64_t > nTimeOffset
int64_t PoissonNextSend(int64_t now, int average_interval_seconds)
Return a timestamp in the future (in microseconds) for exponentially distributed events.
const char * GETDATA
The getdata message requests one or more data objects from another node.
Fee rate in satoshis per kilobyte: CAmount / kB.
std::atomic_bool fSuccessfullyConnected
CBlockLocator GetLocator(const CBlockIndex *pindex=nullptr) const
Return a CBlockLocator that refers to a block in this chain (by default the tip). ...
#define AssertLockNotHeld(cs)
void GetRandBytes(unsigned char *buf, int num)
Functions to gather random data via the OpenSSL PRNG.
std::atomic< int > nVersion
bool IsWitnessEnabled(const CBlockIndex *pindexPrev, const Consensus::Params ¶ms)
Check whether witness commitments are required for block.
unsigned int GetRejectCode() const
ReadStatus InitData(const CBlockHeaderAndShortTxIDs &cmpctblock, const std::vector< std::pair< uint256, CTransactionRef >> &extra_txn)
void FinalizeNode(NodeId nodeid, bool &fUpdateConnectionTime) override
Handle removal of a peer by updating various state and removing it from mapNodeState.
std::string ToString() const
bool CorruptionPossible() const
int GetExtraOutboundCount()
int64_t GetTime()
GetTimeMicros() and GetTimeMillis() both return the system time, but in different units...
const char * TX
The tx message transmits a single transaction.
The basic transaction that is broadcasted on the network and contained in blocks. ...
bool ReadRawBlockFromDisk(std::vector< uint8_t > &block, const CDiskBlockPos &pos, const CMessageHeader::MessageStartChars &message_start)
void MarkAddressGood(const CAddress &addr)
int nHeight
height of the entry in the chain. The genesis block has height 0
Information about a peer.
const Consensus::Params & GetConsensus() const
std::vector< int > vHeightInFlight
bool ReadBlockFromDisk(CBlock &block, const CDiskBlockPos &pos, const Consensus::Params &consensusParams)
Functions for disk access for blocks.
CAmount round(CAmount currentMinFee)
Quantize a minimum fee for privacy purpose before broadcast.
full block available in blk*.dat
std::string GetAddrName() const
void AddTimeData(const CNetAddr &ip, int64_t nOffsetSample)
CChain & chainActive
The currently-connected chain of blocks (protected by cs_main).
void AddAddressKnown(const CAddress &_addr)
void InitializeNode(CNode *pnode) override
Initialize a peer by adding it to mapNodeState and pushing a message requesting its version...
std::string SanitizeString(const std::string &str, int rule)
Remove unsafe chars.
std::atomic_bool fPauseRecv
limitedmap< uint256, int64_t > mapAlreadyAskedFor(MAX_INV_SZ)
std::atomic< int64_t > nLastBlockTime
std::multimap< int64_t, CInv > mapAskFor
CAmount GetFeePerK() const
Return the fee in satoshis for a size of 1000 bytes.
void AdvertiseLocal(CNode *pnode)
bool GetUseAddrmanOutgoing() const
unsigned int nTx
Number of transactions in this block.
const char * FILTERADD
The filteradd message tells the receiving peer to add a single element to a previously-set bloom filt...
std::string itostr(int n)
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...
uint64_t GetRand(uint64_t nMax)
std::set< uint256 > setAskFor
const char * GETBLOCKTXN
Contains a BlockTransactionsRequest Peer should respond with "blocktxn" message.
std::vector< unsigned char > ParseHex(const char *psz)
CBlockIndex * LookupBlockIndex(const uint256 &hash)