37 # error "Raven cannot be compiled without assertions." 61 static size_t vExtraTxnForCompactIt = 0;
62 static std::vector<std::pair<uint256, CTransactionRef>> vExtraTxnForCompact
GUARDED_BY(
cs_main);
64 static const uint64_t RANDOMIZER_ID_ADDRESS_RELAY = 0x3cac0035b5866b90ULL;
68 static const int STALE_RELAY_AGE_LIMIT = 30 * 24 * 60 * 60;
72 static const int HISTORICAL_BLOCK_AGE = 7 * 24 * 60 * 60;
86 std::map<uint256, std::pair<NodeId, bool>> mapBlockSource;
108 std::unique_ptr<CRollingBloomFilter> recentRejects;
109 uint256 hashRecentRejectsChainTip;
115 bool fValidatedHeaders;
116 std::unique_ptr<PartiallyDownloadedBlock> partialBlock;
118 std::map<uint256, std::pair<NodeId, std::list<QueuedBlock>::iterator> > mapBlocksInFlight;
121 std::list<NodeId> lNodesAnnouncingHeaderAndIDs;
124 int nPreferredDownload = 0;
127 int nPeersWithValidatedDownloads = 0;
130 int g_outbound_peers_with_protect_from_disconnect = 0;
133 int64_t g_last_tip_update = 0;
136 typedef std::map<uint256, CTransactionRef> MapRelay;
139 std::deque<std::pair<int64_t, MapRelay::iterator>> vRelayExpiration;
144 struct CBlockReject {
145 unsigned char chRejectCode;
146 std::string strRejectReason;
160 bool fCurrentlyConnected;
166 const std::string name;
168 std::vector<CBlockReject> rejects;
178 int nUnconnectingHeaders;
182 int64_t nHeadersSyncTimeout;
184 int64_t nStallingSince;
185 std::list<QueuedBlock> vBlocksInFlight;
187 int64_t nDownloadingSince;
189 int nBlocksInFlightValidHeaders;
191 bool fPreferredDownload;
195 bool fPreferHeaderAndIDs;
201 bool fProvidesHeaderAndIDs;
205 bool fWantsCmpctWitness;
210 bool fSupportsDesiredCmpctVersion;
226 struct ChainSyncTimeoutState {
232 bool m_sent_getheaders;
237 ChainSyncTimeoutState m_chain_sync;
240 int64_t m_last_block_announcement;
242 CNodeState(
CAddress addrIn, std::string addrNameIn) : address(addrIn), name(addrNameIn) {
243 fCurrentlyConnected =
false;
246 pindexBestKnownBlock =
nullptr;
247 hashLastUnknownBlock.
SetNull();
248 pindexLastCommonBlock =
nullptr;
249 pindexBestHeaderSent =
nullptr;
250 nUnconnectingHeaders = 0;
251 fSyncStarted =
false;
252 nHeadersSyncTimeout = 0;
254 nDownloadingSince = 0;
256 nBlocksInFlightValidHeaders = 0;
257 fPreferredDownload =
false;
258 fPreferHeaders =
false;
259 fPreferHeaderAndIDs =
false;
260 fProvidesHeaderAndIDs =
false;
261 fHaveWitness =
false;
262 fWantsCmpctWitness =
false;
263 fSupportsDesiredCmpctVersion =
false;
264 m_chain_sync = { 0,
nullptr,
false,
false };
265 m_last_block_announcement = 0;
270 std::map<NodeId, CNodeState> mapNodeState;
273 CNodeState *State(
NodeId pnode) {
274 std::map<NodeId, CNodeState>::iterator it = mapNodeState.find(pnode);
275 if (it == mapNodeState.end())
280 void UpdatePreferredDownload(
CNode* node, CNodeState* state)
282 nPreferredDownload -= state->fPreferredDownload;
287 nPreferredDownload += state->fPreferredDownload;
290 void PushNodeVersion(
CNode *pnode,
CConnman* connman, int64_t nTime)
305 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);
307 LogPrint(
BCLog::NET,
"send version message: version %d, blocks=%d, us=%s, peer=%d\n", PROTOCOL_VERSION, nNodeStartingHeight, addrMe.
ToString(), nodeid);
314 bool MarkBlockAsReceived(
const uint256& hash) {
315 std::map<uint256, std::pair<NodeId, std::list<QueuedBlock>::iterator> >::iterator itInFlight = mapBlocksInFlight.find(hash);
316 if (itInFlight != mapBlocksInFlight.end()) {
317 CNodeState *state = State(itInFlight->second.first);
318 assert(state !=
nullptr);
319 state->nBlocksInFlightValidHeaders -= itInFlight->second.second->fValidatedHeaders;
320 if (state->nBlocksInFlightValidHeaders == 0 && itInFlight->second.second->fValidatedHeaders) {
322 nPeersWithValidatedDownloads--;
324 if (state->vBlocksInFlight.begin() == itInFlight->second.second) {
326 state->nDownloadingSince = std::max(state->nDownloadingSince,
GetTimeMicros());
328 state->vBlocksInFlight.erase(itInFlight->second.second);
329 state->nBlocksInFlight--;
330 state->nStallingSince = 0;
331 mapBlocksInFlight.erase(itInFlight);
340 bool MarkBlockAsInFlight(
NodeId nodeid,
const uint256& hash,
const CBlockIndex* pindex =
nullptr, std::list<QueuedBlock>::iterator** pit =
nullptr) {
341 CNodeState *state = State(nodeid);
342 assert(state !=
nullptr);
345 std::map<uint256, std::pair<NodeId, std::list<QueuedBlock>::iterator> >::iterator itInFlight = mapBlocksInFlight.find(hash);
346 if (itInFlight != mapBlocksInFlight.end() && itInFlight->second.first == nodeid) {
348 *pit = &itInFlight->second.second;
354 MarkBlockAsReceived(hash);
356 std::list<QueuedBlock>::iterator it = state->vBlocksInFlight.insert(state->vBlocksInFlight.end(),
358 state->nBlocksInFlight++;
359 state->nBlocksInFlightValidHeaders += it->fValidatedHeaders;
360 if (state->nBlocksInFlight == 1) {
364 if (state->nBlocksInFlightValidHeaders == 1 && pindex !=
nullptr) {
365 nPeersWithValidatedDownloads++;
367 itInFlight = mapBlocksInFlight.insert(std::make_pair(hash, std::make_pair(nodeid, it))).first;
369 *pit = &itInFlight->second.second;
374 void ProcessBlockAvailability(
NodeId nodeid) {
375 CNodeState *state = State(nodeid);
376 assert(state !=
nullptr);
378 if (!state->hashLastUnknownBlock.IsNull()) {
379 BlockMap::iterator itOld =
mapBlockIndex.find(state->hashLastUnknownBlock);
380 if (itOld !=
mapBlockIndex.end() && itOld->second->nChainWork > 0) {
381 if (state->pindexBestKnownBlock ==
nullptr || itOld->second->nChainWork >= state->pindexBestKnownBlock->nChainWork)
382 state->pindexBestKnownBlock = itOld->second;
383 state->hashLastUnknownBlock.SetNull();
389 void UpdateBlockAvailability(
NodeId nodeid,
const uint256 &hash) {
390 CNodeState *state = State(nodeid);
391 assert(state !=
nullptr);
393 ProcessBlockAvailability(nodeid);
396 if (it !=
mapBlockIndex.end() && it->second->nChainWork > 0) {
398 if (state->pindexBestKnownBlock ==
nullptr || it->second->nChainWork >= state->pindexBestKnownBlock->nChainWork)
399 state->pindexBestKnownBlock = it->second;
402 state->hashLastUnknownBlock = hash;
406 void MaybeSetPeerAsAnnouncingHeaderAndIDs(
NodeId nodeid,
CConnman* connman) {
408 CNodeState* nodestate = State(nodeid);
409 if (!nodestate || !nodestate->fSupportsDesiredCmpctVersion) {
413 if (nodestate->fProvidesHeaderAndIDs) {
414 for (std::list<NodeId>::iterator it = lNodesAnnouncingHeaderAndIDs.begin(); it != lNodesAnnouncingHeaderAndIDs.end(); it++) {
416 lNodesAnnouncingHeaderAndIDs.erase(it);
417 lNodesAnnouncingHeaderAndIDs.push_back(nodeid);
423 if (lNodesAnnouncingHeaderAndIDs.size() >= 3) {
426 connman->
ForNode(lNodesAnnouncingHeaderAndIDs.front(), [connman, nCMPCTBLOCKVersion](
CNode* pnodeStop){
430 lNodesAnnouncingHeaderAndIDs.pop_front();
433 lNodesAnnouncingHeaderAndIDs.push_back(pfrom->
GetId());
442 if (g_last_tip_update == 0) {
455 bool PeerHasHeader(CNodeState *state,
const CBlockIndex *pindex)
457 if (state->pindexBestKnownBlock && pindex == state->pindexBestKnownBlock->GetAncestor(pindex->
nHeight))
459 if (state->pindexBestHeaderSent && pindex == state->pindexBestHeaderSent->GetAncestor(pindex->
nHeight))
466 void FindNextBlocksToDownload(
NodeId nodeid,
unsigned int count, std::vector<const CBlockIndex*>& vBlocks,
NodeId& nodeStaller,
const Consensus::Params& consensusParams) {
470 vBlocks.reserve(vBlocks.size() + count);
471 CNodeState *state = State(nodeid);
472 assert(state !=
nullptr);
475 ProcessBlockAvailability(nodeid);
482 if (state->pindexLastCommonBlock ==
nullptr) {
490 state->pindexLastCommonBlock =
LastCommonAncestor(state->pindexLastCommonBlock, state->pindexBestKnownBlock);
491 if (state->pindexLastCommonBlock == state->pindexBestKnownBlock)
494 std::vector<const CBlockIndex*> vToFetch;
495 const CBlockIndex *pindexWalk = state->pindexLastCommonBlock;
499 int nWindowEnd = state->pindexLastCommonBlock->nHeight + BLOCK_DOWNLOAD_WINDOW;
500 int nMaxHeight = std::min<int>(state->pindexBestKnownBlock->nHeight, nWindowEnd + 1);
502 while (pindexWalk->
nHeight < nMaxHeight) {
506 int nToFetch = std::min(nMaxHeight - pindexWalk->
nHeight, std::max<int>(count - vBlocks.size(), 128));
507 vToFetch.resize(nToFetch);
508 pindexWalk = state->pindexBestKnownBlock->GetAncestor(pindexWalk->
nHeight + nToFetch);
509 vToFetch[nToFetch - 1] = pindexWalk;
510 for (
unsigned int i = nToFetch - 1; i > 0; i--) {
511 vToFetch[i - 1] = vToFetch[i]->
pprev;
529 state->pindexLastCommonBlock = pindex;
530 }
else if (mapBlocksInFlight.count(pindex->
GetBlockHash()) == 0) {
532 if (pindex->
nHeight > nWindowEnd) {
534 if (vBlocks.size() == 0 && waitingfor != nodeid) {
536 nodeStaller = waitingfor;
540 vBlocks.push_back(pindex);
541 if (vBlocks.size() == count) {
544 }
else if (waitingfor == -1) {
546 waitingfor = mapBlocksInFlight[pindex->
GetBlockHash()].first;
567 mapNodeState.emplace_hint(mapNodeState.end(), std::piecewise_construct, std::forward_as_tuple(nodeid), std::forward_as_tuple(addr, std::move(addrName)));
570 PushNodeVersion(pnode, connman,
GetTime());
574 fUpdateConnectionTime =
false;
576 CNodeState *state = State(nodeid);
577 assert(state !=
nullptr);
579 if (state->fSyncStarted)
582 if (state->nMisbehavior == 0 && state->fCurrentlyConnected) {
583 fUpdateConnectionTime =
true;
586 for (
const QueuedBlock& entry : state->vBlocksInFlight) {
587 mapBlocksInFlight.erase(entry.hash);
590 nPreferredDownload -= state->fPreferredDownload;
591 nPeersWithValidatedDownloads -= (state->nBlocksInFlightValidHeaders != 0);
592 assert(nPeersWithValidatedDownloads >= 0);
593 g_outbound_peers_with_protect_from_disconnect -= state->m_chain_sync.m_protect;
594 assert(g_outbound_peers_with_protect_from_disconnect >= 0);
596 mapNodeState.erase(nodeid);
598 if (mapNodeState.empty()) {
600 assert(mapBlocksInFlight.empty());
601 assert(nPreferredDownload == 0);
602 assert(nPeersWithValidatedDownloads == 0);
603 assert(g_outbound_peers_with_protect_from_disconnect == 0);
610 CNodeState *state = State(nodeid);
611 if (state ==
nullptr)
614 stats.
nSyncHeight = state->pindexBestKnownBlock ? state->pindexBestKnownBlock->nHeight : -1;
615 stats.
nCommonHeight = state->pindexLastCommonBlock ? state->pindexLastCommonBlock->nHeight : -1;
616 for (
const QueuedBlock& queue : state->vBlocksInFlight) {
630 size_t max_extra_txn =
gArgs.
GetArg(
"-blockreconstructionextratxn", DEFAULT_BLOCK_RECONSTRUCTION_EXTRA_TXN);
631 if (max_extra_txn <= 0)
633 if (!vExtraTxnForCompact.size())
634 vExtraTxnForCompact.resize(max_extra_txn);
635 vExtraTxnForCompact[vExtraTxnForCompactIt] = std::make_pair(tx->GetWitnessHash(), tx);
636 vExtraTxnForCompactIt = (vExtraTxnForCompactIt + 1) % max_extra_txn;
641 const uint256& hash = tx->GetHash();
642 if (mapOrphanTransactions.count(hash))
652 unsigned int sz = GetTransactionWeight(*tx);
653 if (sz >= MAX_STANDARD_TX_WEIGHT)
659 auto ret = mapOrphanTransactions.emplace(hash,
COrphanTx{tx, peer,
GetTime() + ORPHAN_TX_EXPIRE_TIME});
661 for (
const CTxIn& txin : tx->vin) {
662 mapOrphanTransactionsByPrev[txin.
prevout].insert(ret.first);
668 mapOrphanTransactions.size(), mapOrphanTransactionsByPrev.size());
674 std::map<uint256, COrphanTx>::iterator it = mapOrphanTransactions.find(hash);
675 if (it == mapOrphanTransactions.end())
677 for (
const CTxIn& txin : it->second.tx->vin)
679 auto itPrev = mapOrphanTransactionsByPrev.find(txin.
prevout);
680 if (itPrev == mapOrphanTransactionsByPrev.end())
682 itPrev->second.erase(it);
683 if (itPrev->second.empty())
684 mapOrphanTransactionsByPrev.erase(itPrev);
686 mapOrphanTransactions.erase(it);
693 std::map<uint256, COrphanTx>::iterator iter = mapOrphanTransactions.begin();
694 while (iter != mapOrphanTransactions.end())
696 std::map<uint256, COrphanTx>::iterator maybeErase = iter++;
697 if (maybeErase->second.fromPeer == peer)
699 nErased += EraseOrphanTx(maybeErase->second.tx->GetHash());
708 unsigned int nEvicted = 0;
709 static int64_t nNextSweep;
711 if (nNextSweep <= nNow) {
714 int64_t nMinExpTime = nNow + ORPHAN_TX_EXPIRE_TIME - ORPHAN_TX_EXPIRE_INTERVAL;
715 std::map<uint256, COrphanTx>::iterator iter = mapOrphanTransactions.begin();
716 while (iter != mapOrphanTransactions.end())
718 std::map<uint256, COrphanTx>::iterator maybeErase = iter++;
719 if (maybeErase->second.nTimeExpire <= nNow) {
720 nErased += EraseOrphanTx(maybeErase->second.tx->GetHash());
722 nMinExpTime = std::min(maybeErase->second.nTimeExpire, nMinExpTime);
726 nNextSweep = nMinExpTime + ORPHAN_TX_EXPIRE_INTERVAL;
729 while (mapOrphanTransactions.size() > nMaxOrphans)
733 std::map<uint256, COrphanTx>::iterator it = mapOrphanTransactions.lower_bound(randomhash);
734 if (it == mapOrphanTransactions.end())
735 it = mapOrphanTransactions.begin();
736 EraseOrphanTx(it->first);
748 CNodeState *state = State(pnode);
749 if (state ==
nullptr)
752 state->nMisbehavior += howmuch;
753 int banscore =
gArgs.
GetArg(
"-banscore", DEFAULT_BANSCORE_THRESHOLD);
754 if (state->nMisbehavior >= banscore && state->nMisbehavior - howmuch < banscore)
756 LogPrintf(
"%s: %s peer=%d (%d -> %d) BAN THRESHOLD EXCEEDED\n", __func__, state->name, pnode, state->nMisbehavior-howmuch, state->nMisbehavior);
757 state->fShouldBan =
true;
759 LogPrintf(
"%s: %s peer=%d (%d -> %d)\n", __func__, state->name, pnode, state->nMisbehavior-howmuch, state->nMisbehavior);
794 static_assert(EXTRA_PEER_CHECK_INTERVAL < STALE_CHECK_INTERVAL,
"peer eviction timer should be less than stale tip check timer");
801 std::vector<uint256> vOrphanErase;
807 for (
const auto& txin : tx.
vin) {
808 auto itByPrev = mapOrphanTransactionsByPrev.find(txin.prevout);
809 if (itByPrev == mapOrphanTransactionsByPrev.end())
continue;
810 for (
auto mi = itByPrev->second.begin(); mi != itByPrev->second.end(); ++mi) {
813 vOrphanErase.push_back(orphanHash);
819 if (vOrphanErase.size()) {
821 for (
uint256 &orphanHash : vOrphanErase) {
822 nErased += EraseOrphanTx(orphanHash);
832 static std::shared_ptr<const CBlock> most_recent_block;
833 static std::shared_ptr<const CBlockHeaderAndShortTxIDs> most_recent_compact_block;
834 static uint256 most_recent_block_hash;
835 static bool fWitnessesPresentInMostRecentCompactBlock;
838 std::shared_ptr<const CBlockHeaderAndShortTxIDs> pcmpctblock = std::make_shared<const CBlockHeaderAndShortTxIDs> (*pblock,
true);
843 static int nHighestFastAnnounce = 0;
844 if (pindex->
nHeight <= nHighestFastAnnounce)
846 nHighestFastAnnounce = pindex->
nHeight;
849 uint256 hashBlock(pblock->GetHash());
852 LOCK(cs_most_recent_block);
853 most_recent_block_hash = hashBlock;
854 most_recent_block = pblock;
855 most_recent_compact_block = pcmpctblock;
856 fWitnessesPresentInMostRecentCompactBlock = fWitnessEnabled;
859 connman->
ForEachNode([
this, &pcmpctblock, pindex, &msgMaker, fWitnessEnabled, &hashBlock](
CNode* pnode) {
863 ProcessBlockAvailability(pnode->
GetId());
864 CNodeState &state = *State(pnode->
GetId());
867 if (state.fPreferHeaderAndIDs && (!fWitnessEnabled || state.fWantsCmpctWitness) &&
868 !PeerHasHeader(&state, pindex) && PeerHasHeader(&state, pindex->
pprev)) {
870 LogPrint(
BCLog::NET,
"%s sending header-and-ids %s to peer=%d\n",
"PeerLogicValidation::NewPoWValidBlock",
871 hashBlock.ToString(), pnode->
GetId());
873 state.pindexBestHeaderSent = pindex;
879 const int nNewHeight = pindexNew->
nHeight;
882 if (!fInitialDownload) {
884 std::vector<uint256> vHashes;
886 while (pindexToAnnounce != pindexFork) {
888 pindexToAnnounce = pindexToAnnounce->
pprev;
889 if (vHashes.size() == MAX_BLOCKS_TO_ANNOUNCE) {
898 for (const uint256& hash : reverse_iterate(vHashes)) {
899 pnode->PushBlockHash(hash);
913 std::map<uint256, std::pair<NodeId, bool>>::iterator it = mapBlockSource.find(hash);
918 if (it != mapBlockSource.end() && State(it->second.first) && state.
GetRejectCode() > 0 && state.
GetRejectCode() < REJECT_INTERNAL) {
920 State(it->second.first)->rejects.push_back(reject);
921 if (nDoS > 0 && it->second.second)
933 mapBlocksInFlight.count(hash) == mapBlocksInFlight.size()) {
934 if (it != mapBlockSource.end()) {
935 MaybeSetPeerAsAnnouncingHeaderAndIDs(it->second.first, connman);
938 if (it != mapBlockSource.end())
939 mapBlockSource.erase(it);
955 assert(recentRejects);
963 recentRejects->reset();
966 return recentRejects->contains(inv.
hash) ||
968 mapOrphanTransactions.count(inv.
hash) ||
989 static void RelayAddress(
const CAddress& addr,
bool fReachable,
CConnman* connman)
991 unsigned int nRelayNodes = fReachable ? 2 : 1;
996 uint64_t hashAddr = addr.
GetHash();
1000 std::array<std::pair<uint64_t, CNode*>,2> best{{{0,
nullptr}, {0,
nullptr}}};
1001 assert(nRelayNodes <= best.size());
1003 auto sortfunc = [&best, &hasher, nRelayNodes](
CNode* pnode) {
1004 if (pnode->
nVersion >= CADDR_TIME_VERSION) {
1006 for (
unsigned int i = 0; i < nRelayNodes; i++) {
1007 if (hashKey > best[i].first) {
1008 std::copy(best.begin() + i, best.begin() + nRelayNodes - 1, best.begin() + i + 1);
1009 best[i] = std::make_pair(hashKey, pnode);
1016 auto pushfunc = [&addr, &best, nRelayNodes, &insecure_rand] {
1017 for (
unsigned int i = 0; i < nRelayNodes && best[i].first != 0; i++) {
1018 best[i].second->PushAddress(addr, insecure_rand);
1027 std::deque<CInv>::iterator it = pfrom->
vRecvGetData.begin();
1028 std::vector<CInv> vNotFound;
1037 const CInv &inv = *it;
1039 if (interruptMsgProc)
1048 std::shared_ptr<const CBlock> a_recent_block;
1049 std::shared_ptr<const CBlockHeaderAndShortTxIDs> a_recent_compact_block;
1050 bool fWitnessesPresentInARecentCompactBlock;
1052 LOCK(cs_most_recent_block);
1053 a_recent_block = most_recent_block;
1054 a_recent_compact_block = most_recent_compact_block;
1055 fWitnessesPresentInARecentCompactBlock = fWitnessesPresentInMostRecentCompactBlock;
1078 LogPrintf(
"%s: ignoring request from peer=%i for old block that isn't in the main chain\n", __func__, pfrom->
GetId());
1096 std::shared_ptr<const CBlock> pblock;
1097 if (a_recent_block && a_recent_block->GetHash() == (*mi).second->GetBlockHash()) {
1098 pblock = a_recent_block;
1101 std::shared_ptr<CBlock> pblockRead = std::make_shared<CBlock>();
1103 assert(!
"cannot load block from disk");
1104 pblock = pblockRead;
1112 bool sendMerkleBlock =
false;
1117 sendMerkleBlock =
true;
1121 if (sendMerkleBlock) {
1129 typedef std::pair<unsigned int, uint256> PairType;
1142 bool fPeerWantsWitness = State(pfrom->
GetId())->fWantsCmpctWitness;
1143 int nSendFlags = fPeerWantsWitness ? 0 : SERIALIZE_TRANSACTION_NO_WITNESS;
1144 if (CanDirectFetch(consensusParams) && mi->second->nHeight >=
chainActive.
Height() - MAX_CMPCTBLOCK_DEPTH) {
1145 if ((fPeerWantsWitness || !fWitnessesPresentInARecentCompactBlock) && a_recent_compact_block && a_recent_compact_block->header.GetHash() == mi->second->GetBlockHash()) {
1162 std::vector<CInv> vInv;
1173 auto mi = mapRelay.find(inv.
hash);
1174 int nSendFlags = (inv.
type ==
MSG_TX ? SERIALIZE_TRANSACTION_NO_WITNESS : 0);
1175 if (mi != mapRelay.end()) {
1188 vNotFound.push_back(inv);
1202 if (!vNotFound.empty()) {
1214 void static ProcessAssetGetData(
CNode* pfrom,
const Consensus::Params& consensusParams,
CConnman* connman,
const std::atomic<bool>& interruptMsgProc)
1217 std::vector<CInvAsset> vNotFound;
1228 if (interruptMsgProc)
1234 vNotFound.push_back(inv);
1240 if (currentActiveAssetCache) {
1244 if (currentActiveAssetCache->GetAssetMetaDataIfExists(inv.
name, asset, height, hash)) {
1281 uint32_t nFetchFlags = 0;
1290 for (
size_t i = 0; i < req.
indexes.size(); i++) {
1294 LogPrintf(
"Peer %d sent us a getblocktxn with out-of-bounds tx indices", pfrom->
GetId());
1301 int nSendFlags = State(pfrom->
GetId())->fWantsCmpctWitness ? 0 : SERIALIZE_TRANSACTION_NO_WITNESS;
1305 bool static ProcessHeadersMessage(
CNode *pfrom,
CConnman *connman,
const std::vector<CBlockHeader>& headers,
const CChainParams& chainparams,
bool punish_duplicate_invalid)
1308 size_t nCount = headers.size();
1315 bool received_new_header =
false;
1319 CNodeState *nodestate = State(pfrom->
GetId());
1330 nodestate->nUnconnectingHeaders++;
1332 LogPrint(
BCLog::NET,
"received header %s: missing prev block %s, sending getheaders (%d) to end (peer=%d, nUnconnectingHeaders=%d)\n",
1333 headers[0].GetHash().ToString(),
1334 headers[0].hashPrevBlock.ToString(),
1336 pfrom->
GetId(), nodestate->nUnconnectingHeaders);
1340 UpdateBlockAvailability(pfrom->
GetId(), headers.back().GetHash());
1342 if (nodestate->nUnconnectingHeaders % MAX_UNCONNECTING_HEADERS == 0) {
1350 if (!hashLastBlock.
IsNull() && header.hashPrevBlock != hashLastBlock) {
1352 return error(
"non-continuous headers sequence");
1354 hashLastBlock = header.GetHash();
1360 received_new_header =
true;
1407 return error(
"invalid header received");
1413 CNodeState *nodestate = State(pfrom->
GetId());
1414 if (nodestate->nUnconnectingHeaders > 0) {
1415 LogPrint(
BCLog::NET,
"peer=%d: resetting nUnconnectingHeaders (%d -> 0)\n", pfrom->
GetId(), nodestate->nUnconnectingHeaders);
1417 nodestate->nUnconnectingHeaders = 0;
1427 nodestate->m_last_block_announcement =
GetTime();
1430 if (nCount == MAX_HEADERS_RESULTS) {
1438 bool fCanDirectFetch = CanDirectFetch(chainparams.
GetConsensus());
1442 std::vector<const CBlockIndex*> vToFetch;
1445 while (pindexWalk && !
chainActive.
Contains(pindexWalk) && vToFetch.size() <= MAX_BLOCKS_IN_TRANSIT_PER_PEER) {
1447 !mapBlocksInFlight.count(pindexWalk->
GetBlockHash()) &&
1450 vToFetch.push_back(pindexWalk);
1452 pindexWalk = pindexWalk->
pprev;
1463 std::vector<CInv> vGetData;
1466 if (nodestate->nBlocksInFlight >= MAX_BLOCKS_IN_TRANSIT_PER_PEER) {
1476 if (vGetData.size() > 1) {
1480 if (vGetData.size() > 0) {
1481 if (nodestate->fSupportsDesiredCmpctVersion && vGetData.size() == 1 && mapBlocksInFlight.size() == 1 && pindexLast->
pprev->
IsValid(
BLOCK_VALID_CHAIN)) {
1494 if (nodestate->pindexBestKnownBlock && nodestate->pindexBestKnownBlock->nChainWork <
nMinimumChainWork) {
1504 LogPrintf(
"Disconnecting outbound peer %d -- headers chain has insufficient work\n", pfrom->
GetId());
1513 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) {
1515 nodestate->m_chain_sync.m_protect =
true;
1516 ++g_outbound_peers_with_protect_from_disconnect;
1524 bool static ProcessMessage(
CNode* pfrom,
const std::string& strCommand,
CDataStream& vRecv, int64_t nTimeReceived,
const CChainParams& chainparams,
CConnman* connman,
const std::atomic<bool>& interruptMsgProc)
1529 LogPrintf(
"dropmessagestest DROPPING RECV MESSAGE\n");
1538 if (pfrom->
nVersion >= NO_BLOOM_VERSION) {
1552 std::string strMsg;
unsigned char ccode; std::string strReason;
1555 std::ostringstream ss;
1556 ss << strMsg <<
" code " <<
itostr(ccode) <<
": " << strReason;
1562 ss <<
": hash " << hash.
ToString();
1565 }
catch (
const std::ios_base::failure&) {
1586 uint64_t nNonce = 1;
1587 uint64_t nServiceInt;
1591 std::string strSubVer;
1592 std::string cleanSubVer;
1593 int nStartingHeight = -1;
1596 vRecv >> nVersion >> nServiceInt >> nTime >> addrMe;
1597 nSendVersion = std::min(nVersion, PROTOCOL_VERSION);
1605 LogPrint(
BCLog::NET,
"peer=%d does not offer the expected services (%08x offered, %08x expected); disconnecting\n", pfrom->
GetId(), nServices, GetDesirableServiceFlags(nServices));
1607 strprintf(
"Expected to offer services %08x", GetDesirableServiceFlags(nServices))));
1612 if (nServices & ((1 << 7) | (1 << 5))) {
1623 if (nVersion < MIN_PEER_PROTO_VERSION)
1626 LogPrintf(
"peer=%d using obsolete version %i; disconnecting\n", pfrom->
GetId(), nVersion);
1628 strprintf(
"Version must be %d or greater", MIN_PEER_PROTO_VERSION)));
1634 LogPrintf(
"peer=%d using obsolete version %i; disconnecting because messaging is active\n", pfrom->
GetId(), nVersion);
1636 strprintf(
"Version must be %d or greater", ASSET_MESSAGING_VERSION)));
1641 if (nVersion == 10300)
1644 vRecv >> addrFrom >> nNonce;
1645 if (!vRecv.
empty()) {
1649 if (!vRecv.
empty()) {
1650 vRecv >> nStartingHeight;
1662 if (pfrom->
fInbound && addrMe.IsRoutable())
1694 State(pfrom->
GetId())->fHaveWitness =
true;
1700 UpdatePreferredDownload(pfrom, State(pfrom->
GetId()));
1730 std::string remoteAddr;
1734 LogPrintf(
"receive version message: %s: version %d, blocks=%d, us=%s, peer=%d%s\n",
1739 int64_t nTimeOffset = nTime -
GetTime();
1745 CDataStream finalAlert(
ParseHex(
"60010000000000000000000000ffffff7f00000000ffffff7ffeffff7f01ffffff7f00000000ffffff7f00ffffff7f002f555247454e543a20416c657274206b657920636f6d70726f6d697365642c2075706772616465207265717569726564004630440220653febd6410f470f6bae11cad19c48413becb1ac2c17f908fd0fd53bdc3abd5202206d0e9c96fe88d4a0f01ed9dedae2b6f9e00da94cad0fecaae66ecf689bf71b50"),
SER_NETWORK, PROTOCOL_VERSION);
1776 State(pfrom->
GetId())->fCurrentlyConnected =
true;
1779 if (pfrom->
nVersion >= SENDHEADERS_VERSION) {
1786 if (pfrom->
nVersion >= SHORT_IDS_BLOCKS_VERSION) {
1792 bool fAnnounceUsingCMPCTBLOCK =
false;
1793 uint64_t nCMPCTBLOCKVersion = 2;
1796 nCMPCTBLOCKVersion = 1;
1812 std::vector<CAddress> vAddr;
1818 if (vAddr.size() > 1000)
1822 return error(
"message addr size() = %u", vAddr.size());
1826 std::vector<CAddress> vAddrOk;
1828 int64_t nSince = nNow - 10 * 60;
1831 if (interruptMsgProc)
1837 if (!MayHaveUsefulAddressDB(addr.
nServices))
1840 if (addr.
nTime <= 100000000 || addr.
nTime > nNow + 10 * 60)
1841 addr.
nTime = nNow - 5 * 24 * 60 * 60;
1847 RelayAddress(addr, fReachable, connman);
1851 vAddrOk.push_back(addr);
1854 if (vAddr.size() < 1000)
1863 State(pfrom->
GetId())->fPreferHeaders =
true;
1868 bool fAnnounceUsingCMPCTBLOCK =
false;
1869 uint64_t nCMPCTBLOCKVersion = 0;
1870 vRecv >> fAnnounceUsingCMPCTBLOCK >> nCMPCTBLOCKVersion;
1874 if (!State(pfrom->
GetId())->fProvidesHeaderAndIDs) {
1875 State(pfrom->
GetId())->fProvidesHeaderAndIDs =
true;
1876 State(pfrom->
GetId())->fWantsCmpctWitness = nCMPCTBLOCKVersion == 2;
1878 if (State(pfrom->
GetId())->fWantsCmpctWitness == (nCMPCTBLOCKVersion == 2))
1879 State(pfrom->
GetId())->fPreferHeaderAndIDs = fAnnounceUsingCMPCTBLOCK;
1880 if (!State(pfrom->
GetId())->fSupportsDesiredCmpctVersion) {
1882 State(pfrom->
GetId())->fSupportsDesiredCmpctVersion = (nCMPCTBLOCKVersion == 2);
1884 State(pfrom->
GetId())->fSupportsDesiredCmpctVersion = (nCMPCTBLOCKVersion == 1);
1892 std::vector<CInv> vInv;
1894 if (vInv.size() > MAX_INV_SZ)
1898 return error(
"message inv size() = %u", vInv.size());
1905 fBlocksOnly =
false;
1911 for (
CInv &inv : vInv)
1913 if (interruptMsgProc)
1916 bool fAlreadyHave = AlreadyHave(inv);
1920 inv.
type |= nFetchFlags;
1924 UpdateBlockAvailability(pfrom->
GetId(), inv.
hash);
1952 std::vector<CInv> vInv;
1954 if (vInv.size() > MAX_INV_SZ)
1958 return error(
"message getdata size() = %u", vInv.size());
1963 if (vInv.size() > 0) {
1974 LogPrint(
BCLog::NET,
"Ignoring getassetdata from peer=%d because node is in initial block download\n", pfrom->
GetId());
1978 std::vector<CInvAsset> vInvAsset;
1981 if (vInvAsset.size() > MAX_ASSET_INV_SZ)
1985 return error(
"message getassetdata size() = %u", vInvAsset.size());
1988 for (
auto item : vInvAsset) {
1992 return error(
"message getassetdata assetname size() = %u", item.name.size());
1998 if (vInvAsset.size() > 0) {
2010 vRecv >> locator >> hashStop;
2020 std::shared_ptr<const CBlock> a_recent_block;
2022 LOCK(cs_most_recent_block);
2023 a_recent_block = most_recent_block;
2038 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());
2072 std::shared_ptr<const CBlock> recent_block;
2074 LOCK(cs_most_recent_block);
2075 if (most_recent_block_hash == req.blockhash)
2076 recent_block = most_recent_block;
2080 SendBlockTransactions(*recent_block, req, pfrom, connman);
2088 LogPrintf(
"Peer %d sent us a getblocktxn for a block we don't have", pfrom->
GetId());
2100 LogPrint(
BCLog::NET,
"Peer %d sent us a getblocktxn for a block > %i deep", pfrom->
GetId(), MAX_BLOCKTXN_DEPTH);
2103 inv.hash = req.blockhash;
2113 SendBlockTransactions(block, req, pfrom, connman);
2121 vRecv >> locator >> hashStop;
2125 LogPrint(
BCLog::NET,
"Ignoring getheaders from peer=%d because node is in initial block download\n", pfrom->
GetId());
2129 CNodeState *nodestate = State(pfrom->
GetId());
2137 pindex = (*mi).second;
2140 !StaleBlockRequestAllowed(pindex, chainparams.
GetConsensus())) {
2141 LogPrintf(
"%s: ignoring request from peer=%i for old block header that isn't in the main chain\n", __func__, pfrom->
GetId());
2154 std::vector<CBlock> vHeaders;
2155 int nLimit = MAX_HEADERS_RESULTS;
2156 LogPrint(
BCLog::NET,
"getheaders %d to %s from peer=%d\n", (pindex ? pindex->nHeight : -1), hashStop.IsNull() ?
"end" : hashStop.ToString(), pfrom->
GetId());
2159 vHeaders.push_back(pindex->GetBlockHeader());
2160 if (--nLimit <= 0 || pindex->GetBlockHash() == hashStop)
2175 nodestate->pindexBestHeaderSent = pindex ? pindex :
chainActive.
Tip();
2190 std::deque<COutPoint> vWorkQueue;
2191 std::vector<uint256> vEraseQueue;
2201 bool fMissingInputs =
false;
2207 std::list<CTransactionRef> lRemovedTxn;
2209 if (!AlreadyHave(inv) &&
2212 RelayTransaction(tx, connman);
2213 for (
unsigned int i = 0; i < tx.
vout.size(); i++) {
2214 vWorkQueue.emplace_back(inv.
hash, i);
2225 std::set<NodeId> setMisbehaving;
2226 while (!vWorkQueue.empty()) {
2227 auto itByPrev = mapOrphanTransactionsByPrev.find(vWorkQueue.front());
2228 vWorkQueue.pop_front();
2229 if (itByPrev == mapOrphanTransactionsByPrev.end())
2231 for (
auto mi = itByPrev->second.begin();
2232 mi != itByPrev->second.end();
2238 NodeId fromPeer = (*mi)->second.fromPeer;
2239 bool fMissingInputs2 =
false;
2246 if (setMisbehaving.count(fromPeer))
2250 RelayTransaction(orphanTx, connman);
2251 for (
unsigned int i = 0; i < orphanTx.
vout.size(); i++) {
2252 vWorkQueue.emplace_back(orphanHash, i);
2254 vEraseQueue.push_back(orphanHash);
2256 else if (!fMissingInputs2)
2259 if (stateDummy.
IsInvalid(nDos) && nDos > 0)
2263 setMisbehaving.insert(fromPeer);
2269 vEraseQueue.push_back(orphanHash);
2274 assert(recentRejects);
2275 recentRejects->insert(orphanHash);
2282 for (
uint256 hash : vEraseQueue)
2283 EraseOrphanTx(hash);
2285 else if (fMissingInputs)
2287 bool fRejectedParents =
false;
2290 fRejectedParents =
true;
2294 if (!fRejectedParents) {
2299 if (!AlreadyHave(_inv)) pfrom->
AskFor(_inv);
2304 unsigned int nMaxOrphanTx = (
unsigned int)std::max((int64_t)0,
gArgs.
GetArg(
"-maxorphantx", DEFAULT_MAX_ORPHAN_TRANSACTIONS));
2313 recentRejects->insert(tx.
GetHash());
2320 assert(recentRejects);
2321 recentRejects->insert(tx.
GetHash());
2322 if (RecursiveDynamicUsage(*ptx) < 100000) {
2325 }
else if (tx.
HasWitness() && RecursiveDynamicUsage(*ptx) < 100000) {
2339 if (!state.
IsInvalid(nDoS) || nDoS == 0) {
2341 RelayTransaction(tx, connman);
2370 vRecv >> cmpctblock;
2372 bool received_new_header =
false;
2385 received_new_header =
true;
2398 LogPrintf(
"Peer %d sent us invalid header via cmpctblock\n", pfrom->
GetId());
2407 bool fProcessBLOCKTXN =
false;
2412 bool fRevertToHeaderProcessing =
false;
2416 std::shared_ptr<CBlock> pblock = std::make_shared<CBlock>();
2417 bool fBlockReconstructed =
false;
2425 CNodeState *nodestate = State(pfrom->
GetId());
2430 nodestate->m_last_block_announcement =
GetTime();
2433 std::map<uint256, std::pair<NodeId, std::list<QueuedBlock>::iterator> >::iterator blockInFlightIt = mapBlocksInFlight.find(pindex->
GetBlockHash());
2434 bool fAlreadyInFlight = blockInFlightIt != mapBlocksInFlight.end();
2441 if (fAlreadyInFlight) {
2444 std::vector<CInv> vInv(1);
2452 if (!fAlreadyInFlight && !CanDirectFetch(chainparams.GetConsensus()))
2455 if (
IsWitnessEnabled(pindex->
pprev, chainparams.GetConsensus()) && !nodestate->fSupportsDesiredCmpctVersion) {
2464 if ((!fAlreadyInFlight && nodestate->nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER) ||
2465 (fAlreadyInFlight && blockInFlightIt->second.first == pfrom->
GetId())) {
2466 std::list<QueuedBlock>::iterator* queuedBlockIt =
nullptr;
2467 if (!MarkBlockAsInFlight(pfrom->
GetId(), pindex->
GetBlockHash(), pindex, &queuedBlockIt)) {
2468 if (!(*queuedBlockIt)->partialBlock)
2469 (*queuedBlockIt)->partialBlock.reset(
new PartiallyDownloadedBlock(&
mempool));
2477 PartiallyDownloadedBlock& partialBlock = *(*queuedBlockIt)->partialBlock;
2482 LogPrintf(
"Peer %d sent us invalid compact block\n", pfrom->
GetId());
2486 std::vector<CInv> vInv(1);
2493 for (
size_t i = 0; i < cmpctblock.BlockTxCount(); i++) {
2500 txn.
blockhash = cmpctblock.header.GetHash();
2502 fProcessBLOCKTXN =
true;
2513 PartiallyDownloadedBlock tempBlock(&
mempool);
2519 std::vector<CTransactionRef> dummy;
2520 status = tempBlock.
FillBlock(*pblock, dummy);
2522 fBlockReconstructed =
true;
2526 if (fAlreadyInFlight) {
2529 std::vector<CInv> vInv(1);
2535 fRevertToHeaderProcessing =
true;
2540 if (fProcessBLOCKTXN)
2541 return ProcessMessage(pfrom,
NetMsgType::BLOCKTXN, blockTxnMsg, nTimeReceived, chainparams, connman, interruptMsgProc);
2543 if (fRevertToHeaderProcessing) {
2549 return ProcessHeadersMessage(pfrom, connman, {cmpctblock.header}, chainparams,
false);
2552 if (fBlockReconstructed) {
2557 mapBlockSource.emplace(pblock->GetHash(), std::make_pair(pfrom->
GetId(),
false));
2559 bool fNewBlock =
false;
2574 mapBlockSource.erase(pblock->GetHash());
2582 MarkBlockAsReceived(pblock->GetHash());
2593 std::shared_ptr<CBlock> pblock = std::make_shared<CBlock>();
2594 bool fBlockRead =
false;
2598 std::map<uint256, std::pair<NodeId, std::list<QueuedBlock>::iterator> >::iterator it = mapBlocksInFlight.find(resp.blockhash);
2599 if (it == mapBlocksInFlight.end() || !it->second.second->partialBlock ||
2600 it->second.first != pfrom->
GetId()) {
2605 PartiallyDownloadedBlock& partialBlock = *it->second.second->partialBlock;
2608 MarkBlockAsReceived(resp.blockhash);
2610 LogPrintf(
"Peer %d sent us invalid compact block/non-matching block transactions\n", pfrom->
GetId());
2614 std::vector<CInv> invs;
2635 MarkBlockAsReceived(resp.blockhash);
2642 mapBlockSource.emplace(resp.blockhash, std::make_pair(pfrom->
GetId(),
false));
2646 bool fNewBlock =
false;
2658 mapBlockSource.erase(pblock->GetHash());
2666 std::vector<CBlockHeader> headers;
2670 if (nCount > MAX_HEADERS_RESULTS) {
2673 return error(
"headers message size = %u", nCount);
2675 headers.resize(nCount);
2676 for (
unsigned int n = 0; n < nCount; n++) {
2677 vRecv >> headers[n];
2686 return ProcessHeadersMessage(pfrom, connman, headers, chainparams, should_punish);
2691 std::shared_ptr<CBlock> pblock = std::make_shared<CBlock>();
2696 bool forceProcessing =
false;
2697 const uint256 hash(pblock->GetHash());
2702 forceProcessing |= MarkBlockAsReceived(hash);
2705 mapBlockSource.emplace(hash, std::make_pair(pfrom->
GetId(),
true));
2707 bool fNewBlock =
false;
2713 mapBlockSource.erase(pblock->GetHash());
2769 if (pfrom->
nVersion > BIP0031_VERSION)
2791 int64_t pingUsecEnd = nTimeReceived;
2794 bool bPingFinished =
false;
2795 std::string sProblem;
2797 if (nAvail >=
sizeof(nonce)) {
2804 bPingFinished =
true;
2806 if (pingUsecTime > 0) {
2812 sProblem =
"Timing mishap";
2816 sProblem =
"Nonce mismatch";
2819 bPingFinished =
true;
2820 sProblem =
"Nonce zero";
2824 sProblem =
"Unsolicited pong without ping";
2828 bPingFinished =
true;
2829 sProblem =
"Short payload";
2832 if (!(sProblem.empty())) {
2840 if (bPingFinished) {
2851 if (!filter.IsWithinSizeConstraints())
2870 std::vector<unsigned char> vData;
2876 if (vData.size() > MAX_SCRIPT_ELEMENT_SIZE) {
2905 vRecv >> newFeeFilter;
2935 static bool SendRejectsAndCheckIfBanned(
CNode* pnode,
CConnman* connman)
2938 CNodeState &state = *State(pnode->
GetId());
2940 for (
const CBlockReject& reject : state.rejects) {
2943 state.rejects.clear();
2945 if (state.fShouldBan) {
2946 state.fShouldBan =
false;
2976 bool fMoreWork =
false;
2991 std::list<CNetMessage> msgs;
3026 const uint256& hash = msg.GetMessageHash();
3029 LogPrintf(
"%s(%s, %u bytes): CHECKSUM ERROR expected %s was %s\n", __func__,
3040 fRet = ProcessMessage(pfrom, strCommand, vRecv, msg.nTime, chainparams, connman, interruptMsgProc);
3041 if (interruptMsgProc)
3046 catch (
const std::ios_base::failure& e)
3049 if (strstr(e.what(),
"end of data"))
3052 LogPrintf(
"%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());
3054 else if (strstr(e.what(),
"size too large"))
3057 LogPrintf(
"%s(%s, %u bytes): Exception '%s' caught\n", __func__,
SanitizeString(strCommand), nMessageSize, e.what());
3059 else if (strstr(e.what(),
"non-canonical ReadCompactSize()"))
3062 LogPrintf(
"%s(%s, %u bytes): Exception '%s' caught\n", __func__,
SanitizeString(strCommand), nMessageSize, e.what());
3069 catch (
const std::exception& e) {
3080 SendRejectsAndCheckIfBanned(pfrom, connman);
3089 CNodeState &state = *State(pto->
GetId());
3099 if (state.pindexBestKnownBlock !=
nullptr && state.pindexBestKnownBlock->nChainWork >=
chainActive.
Tip()->
nChainWork) {
3100 if (state.m_chain_sync.m_timeout != 0) {
3101 state.m_chain_sync.m_timeout = 0;
3102 state.m_chain_sync.m_work_header =
nullptr;
3103 state.m_chain_sync.m_sent_getheaders =
false;
3105 }
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)) {
3110 state.m_chain_sync.m_timeout = time_in_seconds + CHAIN_SYNC_TIMEOUT;
3112 state.m_chain_sync.m_sent_getheaders =
false;
3113 }
else if (state.m_chain_sync.m_timeout > 0 && time_in_seconds > state.m_chain_sync.m_timeout) {
3117 if (state.m_chain_sync.m_sent_getheaders) {
3119 LogPrintf(
"Disconnecting outbound peer %d for old chain, best known block = %s\n", pto->
GetId(), state.pindexBestKnownBlock !=
nullptr ? state.pindexBestKnownBlock->GetBlockHash().ToString() :
"<none>");
3122 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());
3124 state.m_chain_sync.m_sent_getheaders =
true;
3125 constexpr int64_t HEADERS_RESPONSE_TIME = 120;
3131 state.m_chain_sync.m_timeout = time_in_seconds + HEADERS_RESPONSE_TIME;
3141 if (extra_peers > 0) {
3147 int64_t oldest_block_announcement = std::numeric_limits<int64_t>::max();
3154 CNodeState *state = State(pnode->
GetId());
3155 if (state ==
nullptr)
return;
3157 if (state->m_chain_sync.m_protect)
return;
3158 if (state->m_last_block_announcement < oldest_block_announcement || (state->m_last_block_announcement == oldest_block_announcement && pnode->
GetId() > worst_peer)) {
3159 worst_peer = pnode->
GetId();
3160 oldest_block_announcement = state->m_last_block_announcement;
3163 if (worst_peer != -1) {
3164 bool disconnected = connman->
ForNode(worst_peer, [&](
CNode *pnode) {
3170 CNodeState &state = *State(pnode->
GetId());
3171 if (time_in_seconds - pnode->
nTimeConnected > MINIMUM_CONNECT_TIME && state.nBlocksInFlight == 0) {
3172 LogPrint(
BCLog::NET,
"disconnecting extra outbound peer=%d (last block announcement received at time %d)\n", pnode->
GetId(), oldest_block_announcement);
3194 if (connman ==
nullptr)
return;
3196 int64_t time_in_seconds =
GetTime();
3204 if (TipMayBeStale(consensusParams)) {
3205 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);
3223 bool operator()(std::set<uint256>::iterator a, std::set<uint256>::iterator b)
3245 bool pingSend =
false;
3256 while (nonce == 0) {
3261 if (pto->
nVersion > BIP0031_VERSION) {
3275 if (SendRejectsAndCheckIfBanned(pto, connman))
3277 CNodeState &state = *State(pto->
GetId());
3291 std::vector<CAddress> vAddr;
3298 vAddr.push_back(addr);
3300 if (vAddr.size() >= 1000)
3324 std::vector<CInvAsset> vInvAssets;
3330 if (vInvAssets.size() == MAX_ASSET_INV_SZ) {
3337 if (!vInvAssets.empty())
3344 bool fFetch = state.fPreferredDownload || (nPreferredDownload == 0 && !pto->
fClient && !pto->
fOneShot);
3348 state.fSyncStarted =
true;
3359 if (pindexStart->
pprev)
3360 pindexStart = pindexStart->
pprev;
3386 std::vector<CBlock> vHeaders;
3387 bool fRevertToInv = ((!state.fPreferHeaders &&
3391 ProcessBlockAvailability(pto->
GetId());
3393 if (!fRevertToInv) {
3394 bool fFoundStartingHeader =
false;
3404 fRevertToInv =
true;
3407 if (pBestIndex !=
nullptr && pindex->
pprev != pBestIndex) {
3419 fRevertToInv =
true;
3422 pBestIndex = pindex;
3423 if (fFoundStartingHeader) {
3425 vHeaders.push_back(pindex->GetBlockHeader());
3426 }
else if (PeerHasHeader(&state, pindex)) {
3428 }
else if (pindex->pprev ==
nullptr || PeerHasHeader(&state, pindex->pprev)) {
3431 fFoundStartingHeader =
true;
3432 vHeaders.push_back(pindex->GetBlockHeader());
3436 fRevertToInv =
true;
3441 if (!fRevertToInv && !vHeaders.empty()) {
3442 if (vHeaders.size() == 1 && state.fPreferHeaderAndIDs) {
3446 vHeaders.front().GetHash().ToString(), pto->
GetId());
3448 int nSendFlags = state.fWantsCmpctWitness ? 0 : SERIALIZE_TRANSACTION_NO_WITNESS;
3450 bool fGotBlockFromCache =
false;
3452 LOCK(cs_most_recent_block);
3453 if (most_recent_block_hash == pBestIndex->
GetBlockHash()) {
3454 if (state.fWantsCmpctWitness || !fWitnessesPresentInMostRecentCompactBlock)
3460 fGotBlockFromCache =
true;
3463 if (!fGotBlockFromCache) {
3470 state.pindexBestHeaderSent = pBestIndex;
3471 }
else if (state.fPreferHeaders) {
3472 if (vHeaders.size() > 1) {
3475 vHeaders.front().GetHash().ToString(),
3476 vHeaders.back().GetHash().ToString(), pto->
GetId());
3479 vHeaders.front().GetHash().ToString(), pto->
GetId());
3482 state.pindexBestHeaderSent = pBestIndex;
3484 fRevertToInv =
true;
3505 if (!PeerHasHeader(&state, pindex)) {
3518 std::vector<CInv> vInv;
3526 if (vInv.size() == MAX_INV_SZ) {
3536 fSendTrickle =
true;
3559 for (
const auto& txinfo : vtxinfo) {
3560 const uint256& hash = txinfo.tx->GetHash();
3564 if (txinfo.feeRate.GetFeePerK() < filterrate)
3571 vInv.push_back(inv);
3572 if (vInv.size() == MAX_INV_SZ) {
3583 std::vector<std::set<uint256>::iterator> vInvTx;
3586 vInvTx.push_back(it);
3596 std::make_heap(vInvTx.begin(), vInvTx.end(), compareInvMempoolOrder);
3599 unsigned int nRelayedTransactions = 0;
3601 while (!vInvTx.empty() && nRelayedTransactions < INVENTORY_BROADCAST_MAX) {
3603 std::pop_heap(vInvTx.begin(), vInvTx.end(), compareInvMempoolOrder);
3604 std::set<uint256>::iterator it = vInvTx.back();
3618 if (filterrate && txinfo.feeRate.GetFeePerK() < filterrate) {
3624 nRelayedTransactions++;
3627 while (!vRelayExpiration.empty() && vRelayExpiration.front().first < nNow)
3629 mapRelay.erase(vRelayExpiration.front().second);
3630 vRelayExpiration.pop_front();
3633 auto ret = mapRelay.insert(std::make_pair(hash, std::move(txinfo.tx)));
3635 vRelayExpiration.push_back(std::make_pair(nNow + 15 * 60 * 1000000, ret.first));
3638 if (vInv.size() == MAX_INV_SZ) {
3651 if (state.nStallingSince && state.nStallingSince < nNow - 1000000 * BLOCK_STALLING_TIMEOUT) {
3655 LogPrintf(
"Peer=%d is stalling block download, disconnecting\n", pto->
GetId());
3664 if (state.vBlocksInFlight.size() > 0) {
3665 QueuedBlock &queuedBlock = state.vBlocksInFlight.front();
3666 int nOtherPeersWithValidatedDownloads = nPeersWithValidatedDownloads - (state.nBlocksInFlightValidHeaders > 0);
3667 if (nNow > state.nDownloadingSince + consensusParams.
nPowTargetSpacing * (BLOCK_DOWNLOAD_TIMEOUT_BASE + BLOCK_DOWNLOAD_TIMEOUT_PER_PEER * nOtherPeersWithValidatedDownloads)) {
3668 LogPrintf(
"Timeout downloading block %s from peer=%d, disconnecting\n", queuedBlock.hash.ToString(), pto->
GetId());
3674 if (state.fSyncStarted && state.nHeadersSyncTimeout < std::numeric_limits<int64_t>::max()) {
3677 if (nNow > state.nHeadersSyncTimeout && nSyncStarted == 1 && (nPreferredDownload - state.fPreferredDownload >= 1)) {
3684 LogPrintf(
"Timeout downloading headers from peer=%d, disconnecting\n", pto->
GetId());
3688 LogPrintf(
"Timeout downloading headers from whitelisted peer=%d, not disconnecting\n", pto->
GetId());
3694 state.fSyncStarted =
false;
3696 state.nHeadersSyncTimeout = 0;
3702 state.nHeadersSyncTimeout = std::numeric_limits<int64_t>::max();
3713 std::vector<CInv> vGetData;
3715 std::vector<const CBlockIndex*> vToDownload;
3717 FindNextBlocksToDownload(pto->
GetId(), MAX_BLOCKS_IN_TRANSIT_PER_PEER - state.nBlocksInFlight, vToDownload, staller, consensusParams);
3725 if (state.nBlocksInFlight == 0 && staller != -1) {
3726 if (State(staller)->nStallingSince == 0) {
3727 State(staller)->nStallingSince = nNow;
3739 if (!AlreadyHave(inv))
3742 vGetData.push_back(inv);
3743 if (vGetData.size() >= 1000)
3754 if (!vGetData.empty())
3766 static CFeeRate default_feerate(DEFAULT_MIN_RELAY_TX_FEE);
3768 CAmount filterToSend = filterRounder.
round(currentFilter);
3780 (currentFilter < 3 * pto->lastSentFeeFilter / 4 || currentFilter > 4 * pto->
lastSentFeeFilter / 3)) {
3794 mapOrphanTransactions.clear();
3795 mapOrphanTransactionsByPrev.clear();
uint32_t GetFetchFlags(CNode *pfrom)
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...
unsigned int LimitOrphanTxSize(unsigned int nMaxOrphans) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
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
const char * ASSETNOTFOUND
The asstnotfound message is a reply to a getassetdata message which requested an object the receiving...
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
bool operator()(const I &a, const I &b)
bool operator()(std::set< uint256 >::iterator a, std::set< uint256 >::iterator b)
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
Notifies listeners of updated block chain tip.
std::vector< uint16_t > indexes
int GetRecvVersion() const
void CheckForStaleTipAndEvictPeers(const Consensus::Params &consensusParams)
void insert(const std::vector< unsigned char > &vKey)
bool GetNodeStateStats(NodeId nodeid, CNodeStateStats &stats)
Get statistics from node state.
size_t DynamicMemoryUsage() const
const char * GETASSETDATA
Contains a AssetDataRequest.
reverse_range< T > reverse_iterate(T &x)
bool IsRelevantAndUpdate(const CTransaction &tx)
Also adds any outputs which match the filter to the filter (to match their spending txes) ...
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.
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)
void AskFor(const CInv &inv)
int Height() const
Return the maximal height in the chain.
CCriticalSection cs_main
Global state.
BloomFilter is a probabilistic filter which SPV clients provide so that we can filter the transaction...
void EvictExtraOutboundPeers(int64_t time_in_seconds)
std::string HexStr(const T itbegin, const T itend, bool fSpaces=false)
CCriticalSection cs_SubVer
bool GetTryNewOutboundPeer()
bool HaveCoinInCache(const COutPoint &outpoint) const
Check if we have the given utxo already loaded in this cache.
Only first tx is coinbase, 2 <= coinbase input script length <= 100, transactions valid...
bool IsOutboundDisconnectionCandidate(const CNode *node)
void PushMessage(CNode *pnode, CSerializedNetMsg &&msg)
arith_uint256 nMinimumChainWork
Minimum work we will assume exists on some valid chain.
void SetVersion(int nVersionIn)
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 Raven system...
void Inventory(const uint256 &)
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)
bool AddOrphanTx(const CTransactionRef &tx, NodeId peer) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
uint64_t GetLocalNonce() const
bool SeenLocal(const CService &addr)
vote for a local address
std::set< uint256 > setInventoryTxToSend
std::vector< CAddress > vAddrToSend
void insert(const std::vector< unsigned char > &vKey)
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.
void EraseOrphansFor(NodeId peer) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
int MaxReorganizationDepth() const
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)
Make the best chain active, in multiple steps.
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 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...
int64_t CAmount
Amount in corbies (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)
bool AreMessagingDeployed()
std::atomic< int64_t > nPingUsecTime
std::atomic< int64_t > nMinPingUsecTime
int GetMyStartingHeight() const
CCoinsViewCache * pcoinsTip
Global variable that points to the active CCoinsView (protected by cs_main)
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...
bool IsAssetNameValid(const std::string &name, AssetType &assetType, std::string &error)
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...
void Misbehaving(NodeId pnode, int howmuch)
Increase a node's misbehavior score.
Scripts & signatures ok. Implies all parents are also at least SCRIPTS.
bool AcceptToMemoryPool(CTxMemPool &pool, CValidationState &state, const CTransactionRef &tx, bool *pfMissingInputs, std::list< CTransactionRef > *plTxnReplaced, bool bypass_limits, const CAmount nAbsurdFee)
(try to) add transaction to memory pool plTxnReplaced will be appended to with all transactions repla...
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).
std::vector< CTransactionRef > txn
CAssetsCache * GetCurrentAssetCache()
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.
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::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
std::atomic< int64_t > nTimeBestReceived(0)
bool exists(uint256 hash) const
void AddNewAddresses(const std::vector< CAddress > &vAddr, const CAddress &addrFrom, int64_t nTimePenalty=0)
CChain chainActive
The currently-connected chain of blocks (protected by cs_main).
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
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...
CFeeRate minRelayTxFeeV2
A fee rate smaller than this is considered zero fee (for relaying, mining and transaction creation) ...
bool CheckIncomingNonce(uint64_t nonce)
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
void BlockConnected(const std::shared_ptr< const CBlock > &pblock, const CBlockIndex *pindexConnected, const std::vector< CTransactionRef > &vtxConflicted) override
Notifies listeners of a block being connected.
#define LogPrint(category,...)
std::atomic_bool fReindex
const char * VERACK
The verack message acknowledges a previously-received version message, informing the connecting node ...
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
int64_t PoissonNextSend(int64_t nNow, int average_interval_seconds)
Return a timestamp in the future (in microseconds) for exponentially distributed events.
void NewPoWValidBlock(const CBlockIndex *pindex, const std::shared_ptr< const CBlock > &pblock) override
Notifies listeners that a block which builds directly on our current tip has been received and connec...
#define EXCLUSIVE_LOCKS_REQUIRED(...)
std::vector< CTransactionRef > vtx
std::deque< CInvAsset > vRecvAssetGetData
std::string FormatStateMessage(const CValidationState &state)
Convert CValidationState to a human-readable message for logging.
std::map< uint256, COrphanTx > mapOrphanTransactions GUARDED_BY(cs_main)
CompareInvMempoolOrder(CTxMemPool *_mempool)
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)
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.
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()
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
Notifies listeners of a block validation result.
void SetBestHeight(int height)
#define LIMITED_STRING(obj, n)
CAmount lastSentFeeFilter
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.
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). ...
void GetRandBytes(unsigned char *buf, int num)
Functions to gather random data via the OpenSSL PRNG.
std::set< std::string > setInventoryAssetsSend
bool error(const char *fmt, const Args &... args)
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
void ConsiderEviction(CNode *pto, int64_t time_in_seconds)
ReadStatus InitData(const CBlockHeaderAndShortTxIDs &cmpctblock, const std::vector< std::pair< uint256, CTransactionRef >> &extra_txn)
void UpdateEmptyFull()
Checks for empty and full filters to avoid wasting cpu.
void FinalizeNode(NodeId nodeid, bool &fUpdateConnectionTime) override
std::string ToString() const
bool CorruptionPossible() const
int GetExtraOutboundCount()
const char * ASSETDATA
Contains a AssetData Sent in response to a "getassetdata" message.
int64_t GetTime()
GetTimeMicros() and GetTimeMillis() both return the system time, but in different units...
PeerLogicValidation(CConnman *connman, CScheduler &scheduler)
void AddToCompactExtraTransactions(const CTransactionRef &tx)
const char * TX
The tx message transmits a single transaction.
The basic transaction that is broadcasted on the network and contained in blocks. ...
CLRUCache< std::string, CDatabasedAssetData > * passetsCache
Global variable that point to the assets metadata LRU Cache (protected by cs_main) ...
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)
void AddAddressKnown(const CAddress &_addr)
void InitializeNode(CNode *pnode) override
std::string SanitizeString(const std::string &str, int rule)
Remove unsafe chars.
std::atomic_bool fPauseRecv
limitedmap< uint256, int64_t > mapAlreadyAskedFor(MAX_INV_SZ)
bool SendMessages(CNode *pto, std::atomic< bool > &interrupt) override
Send queued protocol messages to be sent to a give node.
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)
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...
Wrapped boost mutex: supports recursive locking, but no waiting TODO: We should move away from using ...
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)