36 # error "Fabcoin cannot be compiled without assertions." 60 static size_t vExtraTxnForCompactIt = 0;
61 static std::vector<std::pair<uint256, CTransactionRef>> vExtraTxnForCompact
GUARDED_BY(
cs_main);
63 static const uint64_t RANDOMIZER_ID_ADDRESS_RELAY = 0x3cac0035b5866b90ULL;
77 std::map<uint256, std::pair<NodeId, bool>> mapBlockSource;
99 std::unique_ptr<CRollingBloomFilter> recentRejects;
100 uint256 hashRecentRejectsChainTip;
106 bool fValidatedHeaders;
107 std::unique_ptr<PartiallyDownloadedBlock> partialBlock;
109 std::map<uint256, std::pair<NodeId, std::list<QueuedBlock>::iterator> > mapBlocksInFlight;
112 std::list<NodeId> lNodesAnnouncingHeaderAndIDs;
115 int nPreferredDownload = 0;
118 int nPeersWithValidatedDownloads = 0;
121 int g_outbound_peers_with_protect_from_disconnect = 0;
124 int64_t g_last_tip_update = 0;
127 typedef std::map<uint256, CTransactionRef> MapRelay;
130 std::deque<std::pair<int64_t, MapRelay::iterator>> vRelayExpiration;
135 struct CBlockReject {
136 unsigned char chRejectCode;
137 std::string strRejectReason;
151 bool fCurrentlyConnected;
157 const std::string
name;
159 std::vector<CBlockReject> rejects;
169 int nUnconnectingHeaders;
173 int64_t nHeadersSyncTimeout;
175 int64_t nStallingSince;
176 std::list<QueuedBlock> vBlocksInFlight;
178 int64_t nDownloadingSince;
180 int nBlocksInFlightValidHeaders;
182 bool fPreferredDownload;
186 bool fPreferHeaderAndIDs;
192 bool fProvidesHeaderAndIDs;
196 bool fWantsCmpctWitness;
201 bool fSupportsDesiredCmpctVersion;
217 struct ChainSyncTimeoutState {
223 bool m_sent_getheaders;
228 ChainSyncTimeoutState m_chain_sync;
231 int64_t m_last_block_announcement;
233 CNodeState(
CAddress addrIn, std::string addrNameIn) : address(addrIn), name(addrNameIn) {
234 fCurrentlyConnected =
false;
237 pindexBestKnownBlock =
nullptr;
238 hashLastUnknownBlock.
SetNull();
239 pindexLastCommonBlock =
nullptr;
240 pindexBestHeaderSent =
nullptr;
241 nUnconnectingHeaders = 0;
242 fSyncStarted =
false;
243 nHeadersSyncTimeout = 0;
245 nDownloadingSince = 0;
247 nBlocksInFlightValidHeaders = 0;
248 fPreferredDownload =
false;
249 fPreferHeaders =
false;
250 fPreferHeaderAndIDs =
false;
251 fProvidesHeaderAndIDs =
false;
252 fHaveWitness =
false;
253 fWantsCmpctWitness =
false;
254 fSupportsDesiredCmpctVersion =
false;
255 m_chain_sync = { 0,
nullptr,
false,
false };
256 m_last_block_announcement = 0;
261 std::map<NodeId, CNodeState> mapNodeState;
264 CNodeState *State(
NodeId pnode) {
265 std::map<NodeId, CNodeState>::iterator it = mapNodeState.find(pnode);
266 if (it == mapNodeState.end())
271 void UpdatePreferredDownload(
CNode*
node, CNodeState* state)
273 nPreferredDownload -= state->fPreferredDownload;
278 nPreferredDownload += state->fPreferredDownload;
281 void PushNodeVersion(
CNode *pnode,
CConnman* connman, int64_t nTime)
296 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);
298 LogPrint(
BCLog::NET,
"send version message: version %d, blocks=%d, us=%s, peer=%d\n", PROTOCOL_VERSION, nNodeStartingHeight, addrMe.
ToString(), nodeid);
305 bool MarkBlockAsReceived(
const uint256& hash) {
306 std::map<uint256, std::pair<NodeId, std::list<QueuedBlock>::iterator> >::iterator itInFlight = mapBlocksInFlight.find(hash);
307 if (itInFlight != mapBlocksInFlight.end()) {
308 CNodeState *state = State(itInFlight->second.first);
309 state->nBlocksInFlightValidHeaders -= itInFlight->second.second->fValidatedHeaders;
310 if (state->nBlocksInFlightValidHeaders == 0 && itInFlight->second.second->fValidatedHeaders) {
312 nPeersWithValidatedDownloads--;
314 if (state->vBlocksInFlight.begin() == itInFlight->second.second) {
318 state->vBlocksInFlight.erase(itInFlight->second.second);
319 state->nBlocksInFlight--;
320 state->nStallingSince = 0;
321 mapBlocksInFlight.erase(itInFlight);
330 bool MarkBlockAsInFlight(
NodeId nodeid,
const uint256& hash,
const CBlockIndex* pindex =
nullptr, std::list<QueuedBlock>::iterator** pit =
nullptr) {
331 CNodeState *state = State(nodeid);
335 std::map<uint256, std::pair<NodeId, std::list<QueuedBlock>::iterator> >::iterator itInFlight = mapBlocksInFlight.find(hash);
336 if (itInFlight != mapBlocksInFlight.end() && itInFlight->second.first == nodeid) {
338 *pit = &itInFlight->second.second;
344 MarkBlockAsReceived(hash);
346 std::list<QueuedBlock>::iterator it = state->vBlocksInFlight.insert(state->vBlocksInFlight.end(),
348 state->nBlocksInFlight++;
349 state->nBlocksInFlightValidHeaders += it->fValidatedHeaders;
350 if (state->nBlocksInFlight == 1) {
354 if (state->nBlocksInFlightValidHeaders == 1 && pindex !=
nullptr) {
355 nPeersWithValidatedDownloads++;
357 itInFlight = mapBlocksInFlight.insert(std::make_pair(hash, std::make_pair(nodeid, it))).first;
359 *pit = &itInFlight->second.second;
364 void ProcessBlockAvailability(
NodeId nodeid) {
365 CNodeState *state = State(nodeid);
368 if (!state->hashLastUnknownBlock.IsNull()) {
369 BlockMap::iterator itOld =
mapBlockIndex.find(state->hashLastUnknownBlock);
370 if (itOld !=
mapBlockIndex.end() && itOld->second->nChainWork > 0) {
371 if (state->pindexBestKnownBlock ==
nullptr || itOld->second->nChainWork >= state->pindexBestKnownBlock->nChainWork)
372 state->pindexBestKnownBlock = itOld->second;
373 state->hashLastUnknownBlock.SetNull();
379 void UpdateBlockAvailability(
NodeId nodeid,
const uint256 &hash) {
380 CNodeState *state = State(nodeid);
383 ProcessBlockAvailability(nodeid);
386 if (it !=
mapBlockIndex.end() && it->second->nChainWork > 0) {
388 if (state->pindexBestKnownBlock ==
nullptr || it->second->nChainWork >= state->pindexBestKnownBlock->nChainWork)
389 state->pindexBestKnownBlock = it->second;
392 state->hashLastUnknownBlock = hash;
396 void MaybeSetPeerAsAnnouncingHeaderAndIDs(
NodeId nodeid,
CConnman* connman) {
398 CNodeState* nodestate = State(nodeid);
399 if (!nodestate || !nodestate->fSupportsDesiredCmpctVersion) {
403 if (nodestate->fProvidesHeaderAndIDs) {
404 for (std::list<NodeId>::iterator it = lNodesAnnouncingHeaderAndIDs.begin(); it != lNodesAnnouncingHeaderAndIDs.end(); it++) {
406 lNodesAnnouncingHeaderAndIDs.erase(it);
407 lNodesAnnouncingHeaderAndIDs.push_back(nodeid);
412 bool fAnnounceUsingCMPCTBLOCK =
false;
414 if (lNodesAnnouncingHeaderAndIDs.size() >= 3) {
417 connman->
ForNode(lNodesAnnouncingHeaderAndIDs.front(), [connman, fAnnounceUsingCMPCTBLOCK, nCMPCTBLOCKVersion](
CNode* pnodeStop){
421 lNodesAnnouncingHeaderAndIDs.pop_front();
423 fAnnounceUsingCMPCTBLOCK =
true;
425 lNodesAnnouncingHeaderAndIDs.push_back(pfrom->
GetId());
434 if (g_last_tip_update == 0) {
447 bool PeerHasHeader(CNodeState *state,
const CBlockIndex *pindex)
449 if (state->pindexBestKnownBlock && pindex == state->pindexBestKnownBlock->GetAncestor(pindex->
nHeight))
451 if (state->pindexBestHeaderSent && pindex == state->pindexBestHeaderSent->GetAncestor(pindex->
nHeight))
458 void FindNextBlocksToDownload(
NodeId nodeid,
unsigned int count, std::vector<const CBlockIndex*>& vBlocks,
NodeId& nodeStaller,
const Consensus::Params& consensusParams) {
462 vBlocks.reserve(vBlocks.size() +
count);
463 CNodeState *state = State(nodeid);
467 ProcessBlockAvailability(nodeid);
474 if (state->pindexLastCommonBlock ==
nullptr) {
482 state->pindexLastCommonBlock =
LastCommonAncestor(state->pindexLastCommonBlock, state->pindexBestKnownBlock);
483 if (state->pindexLastCommonBlock == state->pindexBestKnownBlock)
486 std::vector<const CBlockIndex*> vToFetch;
487 const CBlockIndex *pindexWalk = state->pindexLastCommonBlock;
491 int nWindowEnd = state->pindexLastCommonBlock->nHeight + BLOCK_DOWNLOAD_WINDOW;
492 int nMaxHeight = std::min<int>(state->pindexBestKnownBlock->nHeight, nWindowEnd + 1);
494 while (pindexWalk->
nHeight < nMaxHeight) {
498 int nToFetch =
std::min(nMaxHeight - pindexWalk->
nHeight, std::max<int>(count - vBlocks.size(), 128));
499 vToFetch.resize(nToFetch);
500 pindexWalk = state->pindexBestKnownBlock->GetAncestor(pindexWalk->
nHeight + nToFetch);
501 vToFetch[nToFetch - 1] = pindexWalk;
502 for (
unsigned int i = nToFetch - 1; i > 0; i--) {
503 vToFetch[i - 1] = vToFetch[i]->
pprev;
521 state->pindexLastCommonBlock = pindex;
522 }
else if (mapBlocksInFlight.count(pindex->
GetBlockHash()) == 0) {
524 if (pindex->
nHeight > nWindowEnd) {
526 if (vBlocks.size() == 0 && waitingfor != nodeid) {
528 nodeStaller = waitingfor;
532 vBlocks.push_back(pindex);
533 if (vBlocks.size() ==
count) {
536 }
else if (waitingfor == -1) {
538 waitingfor = mapBlocksInFlight[pindex->
GetBlockHash()].first;
551 CNodeState *state = State(node);
552 if (state) state->m_last_block_announcement = time_in_seconds;
568 mapNodeState.emplace_hint(mapNodeState.end(), std::piecewise_construct, std::forward_as_tuple(nodeid), std::forward_as_tuple(addr, std::move(addrName)));
571 PushNodeVersion(pnode, connman,
GetTime());
575 fUpdateConnectionTime =
false;
577 CNodeState *state = State(nodeid);
580 if (state->fSyncStarted)
583 if (state->nMisbehavior == 0 && state->fCurrentlyConnected) {
584 fUpdateConnectionTime =
true;
587 for (
const QueuedBlock& entry : state->vBlocksInFlight) {
588 mapBlocksInFlight.erase(entry.hash);
591 nPreferredDownload -= state->fPreferredDownload;
592 nPeersWithValidatedDownloads -= (state->nBlocksInFlightValidHeaders != 0);
593 assert(nPeersWithValidatedDownloads >= 0);
594 g_outbound_peers_with_protect_from_disconnect -= state->m_chain_sync.m_protect;
595 assert(g_outbound_peers_with_protect_from_disconnect >= 0);
597 mapNodeState.erase(nodeid);
599 if (mapNodeState.empty()) {
601 assert(mapBlocksInFlight.empty());
602 assert(nPreferredDownload == 0);
603 assert(nPeersWithValidatedDownloads == 0);
604 assert(g_outbound_peers_with_protect_from_disconnect == 0);
611 CNodeState *state = State(nodeid);
612 if (state ==
nullptr)
615 stats.
nSyncHeight = state->pindexBestKnownBlock ? state->pindexBestKnownBlock->nHeight : -1;
616 stats.
nCommonHeight = state->pindexLastCommonBlock ? state->pindexLastCommonBlock->nHeight : -1;
617 for (
const QueuedBlock& queue : state->vBlocksInFlight) {
631 size_t max_extra_txn =
gArgs.
GetArg(
"-blockreconstructionextratxn", DEFAULT_BLOCK_RECONSTRUCTION_EXTRA_TXN);
632 if (max_extra_txn <= 0)
634 if (!vExtraTxnForCompact.size())
635 vExtraTxnForCompact.resize(max_extra_txn);
636 vExtraTxnForCompact[vExtraTxnForCompactIt] = std::make_pair(tx->GetWitnessHash(), tx);
637 vExtraTxnForCompactIt = (vExtraTxnForCompactIt + 1) % max_extra_txn;
642 const uint256& hash = tx->GetHash();
643 if (mapOrphanTransactions.count(hash))
654 if (sz >= MAX_STANDARD_TX_WEIGHT)
660 auto ret = mapOrphanTransactions.emplace(hash,
COrphanTx{tx, peer,
GetTime() + ORPHAN_TX_EXPIRE_TIME});
662 for (
const CTxIn& txin : tx->vin) {
663 mapOrphanTransactionsByPrev[txin.
prevout].insert(ret.first);
669 mapOrphanTransactions.size(), mapOrphanTransactionsByPrev.size());
675 std::map<uint256, COrphanTx>::iterator it = mapOrphanTransactions.find(hash);
676 if (it == mapOrphanTransactions.end())
678 for (
const CTxIn& txin : it->second.tx->vin)
680 auto itPrev = mapOrphanTransactionsByPrev.find(txin.
prevout);
681 if (itPrev == mapOrphanTransactionsByPrev.end())
683 itPrev->second.erase(it);
684 if (itPrev->second.empty())
685 mapOrphanTransactionsByPrev.erase(itPrev);
687 mapOrphanTransactions.erase(it);
694 std::map<uint256, COrphanTx>::iterator iter = mapOrphanTransactions.begin();
695 while (iter != mapOrphanTransactions.end())
697 std::map<uint256, COrphanTx>::iterator maybeErase = iter++;
698 if (maybeErase->second.fromPeer == peer)
700 nErased += EraseOrphanTx(maybeErase->second.tx->GetHash());
709 unsigned int nEvicted = 0;
710 static int64_t nNextSweep;
712 if (nNextSweep <= nNow) {
715 int64_t nMinExpTime = nNow + ORPHAN_TX_EXPIRE_TIME - ORPHAN_TX_EXPIRE_INTERVAL;
716 std::map<uint256, COrphanTx>::iterator iter = mapOrphanTransactions.begin();
717 while (iter != mapOrphanTransactions.end())
719 std::map<uint256, COrphanTx>::iterator maybeErase = iter++;
720 if (maybeErase->second.nTimeExpire <= nNow) {
721 nErased += EraseOrphanTx(maybeErase->second.tx->GetHash());
723 nMinExpTime =
std::min(maybeErase->second.nTimeExpire, nMinExpTime);
727 nNextSweep = nMinExpTime + ORPHAN_TX_EXPIRE_INTERVAL;
730 while (mapOrphanTransactions.size() > nMaxOrphans)
734 std::map<uint256, COrphanTx>::iterator it = mapOrphanTransactions.lower_bound(randomhash);
735 if (it == mapOrphanTransactions.end())
736 it = mapOrphanTransactions.begin();
737 EraseOrphanTx(it->first);
749 CNodeState *state = State(pnode);
750 if (state ==
nullptr)
753 state->nMisbehavior += howmuch;
754 int banscore =
gArgs.
GetArg(
"-banscore", DEFAULT_BANSCORE_THRESHOLD);
755 if (state->nMisbehavior >= banscore && state->nMisbehavior - howmuch < banscore)
757 LogPrintf(
"%s: %s peer=%d (%d -> %d) BAN THRESHOLD EXCEEDED\n", __func__, state->name, pnode, state->nMisbehavior-howmuch, state->nMisbehavior);
758 state->fShouldBan =
true;
760 LogPrintf(
"%s: %s peer=%d (%d -> %d)\n", __func__, state->name, pnode, state->nMisbehavior-howmuch, state->nMisbehavior);
784 static_assert(EXTRA_PEER_CHECK_INTERVAL < STALE_CHECK_INTERVAL,
"peer eviction timer should be less than stale tip check timer");
791 std::vector<uint256> vOrphanErase;
797 for (
const auto& txin : tx.
vin) {
798 auto itByPrev = mapOrphanTransactionsByPrev.find(txin.prevout);
799 if (itByPrev == mapOrphanTransactionsByPrev.end())
continue;
800 for (
auto mi = itByPrev->second.begin(); mi != itByPrev->second.end(); ++mi) {
803 vOrphanErase.push_back(orphanHash);
809 if (vOrphanErase.size()) {
811 for (
uint256 &orphanHash : vOrphanErase) {
812 nErased += EraseOrphanTx(orphanHash);
822 static std::shared_ptr<const CBlock> most_recent_block;
823 static std::shared_ptr<const CBlockHeaderAndShortTxIDs> most_recent_compact_block;
824 static uint256 most_recent_block_hash;
825 static bool fWitnessesPresentInMostRecentCompactBlock;
828 std::shared_ptr<const CBlockHeaderAndShortTxIDs> pcmpctblock = std::make_shared<const CBlockHeaderAndShortTxIDs> (*pblock,
true);
833 static int nHighestFastAnnounce = 0;
834 if (pindex->
nHeight <= nHighestFastAnnounce)
836 nHighestFastAnnounce = pindex->
nHeight;
839 uint256 hashBlock(pblock->GetHash());
842 LOCK(cs_most_recent_block);
843 most_recent_block_hash = hashBlock;
844 most_recent_block = pblock;
845 most_recent_compact_block = pcmpctblock;
846 fWitnessesPresentInMostRecentCompactBlock = fWitnessEnabled;
849 connman->
ForEachNode([
this, &pcmpctblock, pindex, &msgMaker, fWitnessEnabled, &hashBlock](
CNode* pnode) {
853 ProcessBlockAvailability(pnode->
GetId());
854 CNodeState &state = *State(pnode->
GetId());
857 if (state.fPreferHeaderAndIDs && (!fWitnessEnabled || state.fWantsCmpctWitness) &&
858 !PeerHasHeader(&state, pindex) && PeerHasHeader(&state, pindex->
pprev)) {
860 LogPrint(
BCLog::NET,
"%s sending header-and-ids %s to peer=%d\n",
"PeerLogicValidation::NewPoWValidBlock",
861 hashBlock.ToString(), pnode->
GetId());
863 state.pindexBestHeaderSent = pindex;
869 const int nNewHeight = pindexNew->
nHeight;
872 if (!fInitialDownload) {
874 std::vector<uint256> vHashes;
876 while (pindexToAnnounce != pindexFork) {
878 pindexToAnnounce = pindexToAnnounce->
pprev;
879 if (vHashes.size() == MAX_BLOCKS_TO_ANNOUNCE) {
888 for (const uint256& hash : reverse_iterate(vHashes)) {
889 pnode->PushBlockHash(hash);
903 std::map<uint256, std::pair<NodeId, bool>>::iterator it = mapBlockSource.find(hash);
908 if (it != mapBlockSource.end() && State(it->second.first) && state.
GetRejectCode() > 0 && state.
GetRejectCode() < REJECT_INTERNAL) {
910 State(it->second.first)->rejects.push_back(reject);
911 if (nDoS > 0 && it->second.second)
923 mapBlocksInFlight.count(hash) == mapBlocksInFlight.size()) {
924 if (it != mapBlockSource.end()) {
925 MaybeSetPeerAsAnnouncingHeaderAndIDs(it->second.first, connman);
928 if (it != mapBlockSource.end())
929 mapBlockSource.erase(it);
953 recentRejects->reset();
956 return recentRejects->contains(inv.
hash) ||
958 mapOrphanTransactions.count(inv.
hash) ||
979 static void RelayAddress(
const CAddress& addr,
bool fReachable,
CConnman* connman)
981 unsigned int nRelayNodes = fReachable ? 2 : 1;
986 uint64_t hashAddr = addr.
GetHash();
990 std::array<std::pair<uint64_t, CNode*>,2> best{{{0,
nullptr}, {0,
nullptr}}};
991 assert(nRelayNodes <= best.size());
993 auto sortfunc = [&best, &hasher, nRelayNodes](
CNode* pnode) {
994 if (pnode->
nVersion >= CADDR_TIME_VERSION) {
996 for (
unsigned int i = 0; i < nRelayNodes; i++) {
997 if (hashKey > best[i].first) {
998 std::copy(best.begin() + i, best.begin() + nRelayNodes - 1, best.begin() + i + 1);
999 best[i] = std::make_pair(hashKey, pnode);
1006 auto pushfunc = [&addr, &best, nRelayNodes, &insecure_rand] {
1007 for (
unsigned int i = 0; i < nRelayNodes && best[i].first != 0; i++) {
1008 best[i].second->PushAddress(addr, insecure_rand);
1017 std::deque<CInv>::iterator it = pfrom->
vRecvGetData.begin();
1018 std::vector<CInv> vNotFound;
1027 const CInv &inv = *it;
1029 if (interruptMsgProc)
1038 std::shared_ptr<const CBlock> a_recent_block;
1039 std::shared_ptr<const CBlockHeaderAndShortTxIDs> a_recent_compact_block;
1040 bool fWitnessesPresentInARecentCompactBlock;
1042 LOCK(cs_most_recent_block);
1043 a_recent_block = most_recent_block;
1044 a_recent_compact_block = most_recent_compact_block;
1045 fWitnessesPresentInARecentCompactBlock = fWitnessesPresentInMostRecentCompactBlock;
1062 static const int nOneMonth = 30 * 24 * 60 * 60;
1070 LogPrintf(
"%s: ignoring request from peer=%i for old block that isn't in the main chain\n", __func__, pfrom->
GetId());
1076 static const int nOneWeek = 7 * 24 * 60 * 60;
1089 std::shared_ptr<const CBlock> pblock;
1090 if (a_recent_block && a_recent_block->GetHash() == (*mi).second->GetBlockHash()) {
1091 pblock = a_recent_block;
1094 std::shared_ptr<CBlock> pblockRead = std::make_shared<CBlock>();
1096 assert(!
"cannot load block from disk");
1097 pblock = pblockRead;
1101 connman->
PushMessage(pfrom, msgMaker.Make( SERIALIZE_TRANSACTION_NO_WITNESS,
1107 bool sendMerkleBlock =
false;
1112 sendMerkleBlock =
true;
1116 if (sendMerkleBlock) {
1124 typedef std::pair<unsigned int, uint256> PairType;
1127 pfrom, msgMaker.Make( SERIALIZE_TRANSACTION_NO_WITNESS,
1139 bool fPeerWantsWitness = State(pfrom->
GetId())->fWantsCmpctWitness;
1140 int nSendFlags = (fPeerWantsWitness ? 0 : SERIALIZE_TRANSACTION_NO_WITNESS);
1141 if (CanDirectFetch(consensusParams) && mi->second->nHeight >=
chainActive.
Height() - MAX_CMPCTBLOCK_DEPTH) {
1142 if ((fPeerWantsWitness || !fWitnessesPresentInARecentCompactBlock) && a_recent_compact_block && a_recent_compact_block->header.GetHash() == mi->second->GetBlockHash()) {
1159 std::vector<CInv> vInv;
1170 auto mi = mapRelay.find(inv.
hash);
1171 int nSendFlags = (inv.
type ==
MSG_TX ? SERIALIZE_TRANSACTION_NO_WITNESS : 0);
1172 if (mi != mapRelay.end()) {
1185 vNotFound.push_back(inv);
1199 if (!vNotFound.empty()) {
1212 uint32_t nFetchFlags = 0;
1221 for (
size_t i = 0; i < req.
indexes.size(); i++) {
1225 LogPrintf(
"Peer %d sent us a getblocktxn with out-of-bounds tx indices", pfrom->
GetId());
1232 int nSendFlags = State(pfrom->
GetId())->fWantsCmpctWitness ? 0 : SERIALIZE_TRANSACTION_NO_WITNESS;
1236 bool static ProcessHeadersMessage(
CNode *pfrom,
CConnman *connman,
const std::vector<CBlockHeader>& headers,
const CChainParams& chainparams,
bool punish_duplicate_invalid)
1239 size_t nCount = headers.size();
1246 bool received_new_header =
false;
1250 CNodeState *nodestate = State(pfrom->
GetId());
1261 nodestate->nUnconnectingHeaders++;
1263 LogPrint(
BCLog::NET,
"received header %s: missing prev block %s, sending getheaders (%d) to end (peer=%d, nUnconnectingHeaders=%d)\n",
1264 headers[0].GetHash().ToString(),
1265 headers[0].hashPrevBlock.ToString(),
1267 pfrom->
GetId(), nodestate->nUnconnectingHeaders);
1271 UpdateBlockAvailability(pfrom->
GetId(), headers.back().GetHash());
1273 if (nodestate->nUnconnectingHeaders % MAX_UNCONNECTING_HEADERS == 0) {
1282 if (!hashLastBlock.
IsNull() && header.hashPrevBlock != hashLastBlock) {
1283 LogPrintf(
"height %d : header size %d : hash %s vs %s header index %d\n", header.nHeight, headers.size(), header.hashPrevBlock.ToString(), hashLastBlock.
ToString(), ii);
1285 return error(
"non-continuous headers sequence");
1287 hashLastBlock = header.GetHash();
1294 received_new_header =
true;
1342 return error(
"invalid header received");
1348 CNodeState *nodestate = State(pfrom->
GetId());
1349 if (nodestate->nUnconnectingHeaders > 0) {
1350 LogPrint(
BCLog::NET,
"peer=%d: resetting nUnconnectingHeaders (%d -> 0)\n", pfrom->
GetId(), nodestate->nUnconnectingHeaders);
1352 nodestate->nUnconnectingHeaders = 0;
1362 nodestate->m_last_block_announcement =
GetTime();
1365 if (nCount == MAX_HEADERS_RESULTS) {
1373 bool fCanDirectFetch = CanDirectFetch(chainparams.
GetConsensus());
1377 std::vector<const CBlockIndex*> vToFetch;
1380 while (pindexWalk && !
chainActive.
Contains(pindexWalk) && vToFetch.size() <= MAX_BLOCKS_IN_TRANSIT_PER_PEER) {
1382 !mapBlocksInFlight.count(pindexWalk->
GetBlockHash()) &&
1385 vToFetch.push_back(pindexWalk);
1387 pindexWalk = pindexWalk->
pprev;
1398 std::vector<CInv> vGetData;
1401 if (nodestate->nBlocksInFlight >= MAX_BLOCKS_IN_TRANSIT_PER_PEER) {
1411 if (vGetData.size() > 1) {
1415 if (vGetData.size() > 0) {
1416 if (nodestate->fSupportsDesiredCmpctVersion && vGetData.size() == 1 && mapBlocksInFlight.size() == 1 && pindexLast->
pprev->
IsValid(
BLOCK_VALID_CHAIN)) {
1429 if (nodestate->pindexBestKnownBlock && nodestate->pindexBestKnownBlock->nChainWork <
nMinimumChainWork) {
1439 LogPrintf(
"Disconnecting outbound peer %d -- headers chain has insufficient work\n", pfrom->
GetId());
1448 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) {
1450 nodestate->m_chain_sync.m_protect =
true;
1451 ++g_outbound_peers_with_protect_from_disconnect;
1459 bool static ProcessMessage(
CNode* pfrom,
const std::string& strCommand,
CDataStream& vRecv, int64_t nTimeReceived,
const CChainParams& chainparams,
CConnman* connman,
const std::atomic<bool>& interruptMsgProc)
1464 LogPrintf(
"dropmessagestest DROPPING RECV MESSAGE\n");
1473 if (pfrom->
nVersion >= NO_BLOOM_VERSION) {
1487 std::string strMsg;
unsigned char ccode; std::string strReason;
1490 std::ostringstream ss;
1491 ss << strMsg <<
" code " <<
itostr(ccode) <<
": " << strReason;
1497 ss <<
": hash " << hash.
ToString();
1500 }
catch (
const std::ios_base::failure&) {
1521 uint64_t nNonce = 1;
1522 uint64_t nServiceInt;
1526 std::string strSubVer;
1527 std::string cleanSubVer;
1528 int nStartingHeight = -1;
1531 vRecv >> nVersion >> nServiceInt >> nTime >> addrMe;
1532 nSendVersion =
std::min(nVersion, PROTOCOL_VERSION);
1547 if (nServices & ((1 << 7) | (1 << 5))) {
1558 if (nVersion < MIN_PEER_PROTO_VERSION)
1562 LogPrintf(
"peer=%d using obsolete version %i; disconnecting\n", pfrom->
GetId(), nVersion);
1564 strprintf(
"Version must be %d or greater", MIN_PEER_PROTO_VERSION)));
1569 if (nVersion == 10300)
1572 vRecv >> addrFrom >> nNonce;
1573 if (!vRecv.
empty()) {
1577 if (!vRecv.
empty()) {
1578 vRecv >> nStartingHeight;
1590 if (pfrom->
fInbound && addrMe.IsRoutable())
1622 State(pfrom->
GetId())->fHaveWitness =
true;
1628 UpdatePreferredDownload(pfrom, State(pfrom->
GetId()));
1658 std::string remoteAddr;
1662 LogPrintf(
"receive version message: %s: version %d, blocks=%d, us=%s, peer=%d%s\n",
1667 int64_t nTimeOffset = nTime -
GetTime();
1673 CDataStream finalAlert(
ParseHex(
"60010000000000000000000000ffffff7f00000000ffffff7ffeffff7f01ffffff7f00000000ffffff7f00ffffff7f002f555247454e543a20416c657274206b657920636f6d70726f6d697365642c2075706772616465207265717569726564004630440220653febd6410f470f6bae11cad19c48413becb1ac2c17f908fd0fd53bdc3abd5202206d0e9c96fe88d4a0f01ed9dedae2b6f9e00da94cad0fecaae66ecf689bf71b50"),
SER_NETWORK, PROTOCOL_VERSION);
1704 State(pfrom->
GetId())->fCurrentlyConnected =
true;
1707 if (pfrom->
nVersion >= SENDHEADERS_VERSION) {
1714 if (pfrom->
nVersion >= SHORT_IDS_BLOCKS_VERSION) {
1720 bool fAnnounceUsingCMPCTBLOCK =
false;
1721 uint64_t nCMPCTBLOCKVersion = 2;
1724 nCMPCTBLOCKVersion = 1;
1740 std::vector<CAddress> vAddr;
1746 if (vAddr.size() > 1000)
1750 return error(
"message addr size() = %u", vAddr.size());
1754 std::vector<CAddress> vAddrOk;
1756 int64_t nSince = nNow - 10 * 60;
1759 if (interruptMsgProc)
1762 if ((addr.
nServices & REQUIRED_SERVICES) != REQUIRED_SERVICES)
1765 if (addr.
nTime <= 100000000 || addr.
nTime > nNow + 10 * 60)
1766 addr.
nTime = nNow - 5 * 24 * 60 * 60;
1772 RelayAddress(addr, fReachable, connman);
1776 vAddrOk.push_back(addr);
1779 if (vAddr.size() < 1000)
1788 State(pfrom->
GetId())->fPreferHeaders =
true;
1793 bool fAnnounceUsingCMPCTBLOCK =
false;
1794 uint64_t nCMPCTBLOCKVersion = 0;
1795 vRecv >> fAnnounceUsingCMPCTBLOCK >> nCMPCTBLOCKVersion;
1799 if (!State(pfrom->
GetId())->fProvidesHeaderAndIDs) {
1800 State(pfrom->
GetId())->fProvidesHeaderAndIDs =
true;
1801 State(pfrom->
GetId())->fWantsCmpctWitness = nCMPCTBLOCKVersion == 2;
1803 if (State(pfrom->
GetId())->fWantsCmpctWitness == (nCMPCTBLOCKVersion == 2))
1804 State(pfrom->
GetId())->fPreferHeaderAndIDs = fAnnounceUsingCMPCTBLOCK;
1805 if (!State(pfrom->
GetId())->fSupportsDesiredCmpctVersion) {
1807 State(pfrom->
GetId())->fSupportsDesiredCmpctVersion = (nCMPCTBLOCKVersion == 2);
1809 State(pfrom->
GetId())->fSupportsDesiredCmpctVersion = (nCMPCTBLOCKVersion == 1);
1817 std::vector<CInv> vInv;
1819 if (vInv.size() > MAX_INV_SZ)
1823 return error(
"message inv size() = %u", vInv.size());
1830 fBlocksOnly =
false;
1836 for (
CInv &inv : vInv)
1838 if (interruptMsgProc)
1841 bool fAlreadyHave = AlreadyHave(inv);
1845 inv.
type |= nFetchFlags;
1849 UpdateBlockAvailability(pfrom->
GetId(), inv.
hash);
1878 std::vector<CInv> vInv;
1880 if (vInv.size() > MAX_INV_SZ)
1884 return error(
"message getdata size() = %u", vInv.size());
1889 if (vInv.size() > 0) {
1902 vRecv >> locator >> hashStop;
1912 std::shared_ptr<const CBlock> a_recent_block;
1914 LOCK(cs_most_recent_block);
1915 a_recent_block = most_recent_block;
1930 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());
1964 std::shared_ptr<const CBlock> recent_block;
1966 LOCK(cs_most_recent_block);
1967 if (most_recent_block_hash == req.blockhash)
1968 recent_block = most_recent_block;
1972 SendBlockTransactions(*recent_block, req, pfrom, connman);
1980 LogPrintf(
"Peer %d sent us a getblocktxn for a block we don't have", pfrom->
GetId());
1992 LogPrint(
BCLog::NET,
"Peer %d sent us a getblocktxn for a block > %i deep", pfrom->
GetId(), MAX_BLOCKTXN_DEPTH);
1995 inv.hash = req.blockhash;
2005 SendBlockTransactions(block, req, pfrom, connman);
2013 vRecv >> locator >> hashStop;
2017 LogPrint(
BCLog::NET,
"Ignoring getheaders from peer=%d because node is in initial block download\n", pfrom->
GetId());
2021 CNodeState *nodestate = State(pfrom->
GetId());
2029 pindex = (*mi).second;
2040 std::vector<CBlock> vHeaders;
2041 int nLimit = MAX_HEADERS_RESULTS;
2042 LogPrint(
BCLog::NET,
"getheaders %d to %s from peer=%d\n", (pindex ? pindex->nHeight : -1), hashStop.IsNull() ?
"end" : hashStop.ToString(), pfrom->
GetId());
2045 vHeaders.push_back(pindex->GetBlockHeader());
2046 if (--nLimit <= 0 || pindex->GetBlockHash() == hashStop)
2061 nodestate->pindexBestHeaderSent = pindex ? pindex :
chainActive.
Tip();
2076 std::deque<COutPoint> vWorkQueue;
2077 std::vector<uint256> vEraseQueue;
2087 bool fMissingInputs =
false;
2093 std::list<CTransactionRef> lRemovedTxn;
2097 RelayTransaction(tx, connman);
2098 for (
unsigned int i = 0; i < tx.
vout.size(); i++) {
2099 vWorkQueue.emplace_back(inv.
hash, i);
2110 std::set<NodeId> setMisbehaving;
2111 while (!vWorkQueue.empty()) {
2112 auto itByPrev = mapOrphanTransactionsByPrev.find(vWorkQueue.front());
2113 vWorkQueue.pop_front();
2114 if (itByPrev == mapOrphanTransactionsByPrev.end())
2116 for (
auto mi = itByPrev->second.begin();
2117 mi != itByPrev->second.end();
2123 NodeId fromPeer = (*mi)->second.fromPeer;
2124 bool fMissingInputs2 =
false;
2131 if (setMisbehaving.count(fromPeer))
2135 RelayTransaction(orphanTx, connman);
2136 for (
unsigned int i = 0; i < orphanTx.
vout.size(); i++) {
2137 vWorkQueue.emplace_back(orphanHash, i);
2139 vEraseQueue.push_back(orphanHash);
2141 else if (!fMissingInputs2)
2144 if (stateDummy.
IsInvalid(nDos) && nDos > 0)
2148 setMisbehaving.insert(fromPeer);
2154 vEraseQueue.push_back(orphanHash);
2160 recentRejects->insert(orphanHash);
2167 for (
uint256 hash : vEraseQueue)
2168 EraseOrphanTx(hash);
2170 else if (fMissingInputs)
2172 bool fRejectedParents =
false;
2175 fRejectedParents =
true;
2179 if (!fRejectedParents) {
2184 if (!AlreadyHave(_inv)) pfrom->
AskFor(_inv);
2189 unsigned int nMaxOrphanTx = (
unsigned int)
std::max((int64_t)0,
gArgs.
GetArg(
"-maxorphantx", DEFAULT_MAX_ORPHAN_TRANSACTIONS));
2198 recentRejects->insert(tx.
GetHash());
2206 recentRejects->insert(tx.
GetHash());
2207 if (RecursiveDynamicUsage(*ptx) < 100000) {
2210 }
else if (tx.
HasWitness() && RecursiveDynamicUsage(*ptx) < 100000) {
2224 if (!state.
IsInvalid(nDoS) || nDoS == 0) {
2226 RelayTransaction(tx, connman);
2255 vRecv >> cmpctblock;
2257 bool received_new_header =
false;
2270 received_new_header =
true;
2283 LogPrintf(
"Peer %d sent us invalid header via cmpctblock\n", pfrom->
GetId());
2292 bool fProcessBLOCKTXN =
false;
2297 bool fRevertToHeaderProcessing =
false;
2301 std::shared_ptr<CBlock> pblock = std::make_shared<CBlock>();
2302 bool fBlockReconstructed =
false;
2310 CNodeState *nodestate = State(pfrom->
GetId());
2315 nodestate->m_last_block_announcement =
GetTime();
2318 std::map<uint256, std::pair<NodeId, std::list<QueuedBlock>::iterator> >::iterator blockInFlightIt = mapBlocksInFlight.find(pindex->
GetBlockHash());
2319 bool fAlreadyInFlight = blockInFlightIt != mapBlocksInFlight.end();
2326 if (fAlreadyInFlight) {
2329 std::vector<CInv> vInv(1);
2337 if (!fAlreadyInFlight && !CanDirectFetch(chainparams.GetConsensus()))
2340 if (
IsWitnessEnabled(pindex->
pprev, chainparams.GetConsensus()) && !nodestate->fSupportsDesiredCmpctVersion) {
2349 if ((!fAlreadyInFlight && nodestate->nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER) ||
2350 (fAlreadyInFlight && blockInFlightIt->second.first == pfrom->
GetId())) {
2351 std::list<QueuedBlock>::iterator* queuedBlockIt =
nullptr;
2352 if (!MarkBlockAsInFlight(pfrom->
GetId(), pindex->
GetBlockHash(), pindex, &queuedBlockIt)) {
2353 if (!(*queuedBlockIt)->partialBlock)
2354 (*queuedBlockIt)->partialBlock.reset(
new PartiallyDownloadedBlock(&
mempool));
2362 PartiallyDownloadedBlock& partialBlock = *(*queuedBlockIt)->partialBlock;
2367 LogPrintf(
"Peer %d sent us invalid compact block\n", pfrom->
GetId());
2371 std::vector<CInv> vInv(1);
2378 for (
size_t i = 0; i < cmpctblock.BlockTxCount(); i++) {
2385 txn.
blockhash = cmpctblock.header.GetHash();
2387 fProcessBLOCKTXN =
true;
2398 PartiallyDownloadedBlock tempBlock(&
mempool);
2404 std::vector<CTransactionRef> dummy;
2405 status = tempBlock.
FillBlock(*pblock, dummy);
2407 fBlockReconstructed =
true;
2411 if (fAlreadyInFlight) {
2414 std::vector<CInv> vInv(1);
2420 fRevertToHeaderProcessing =
true;
2425 if (fProcessBLOCKTXN)
2426 return ProcessMessage(pfrom,
NetMsgType::BLOCKTXN, blockTxnMsg, nTimeReceived, chainparams, connman, interruptMsgProc);
2428 if (fRevertToHeaderProcessing) {
2434 return ProcessHeadersMessage(pfrom, connman, {cmpctblock.header}, chainparams,
false);
2437 if (fBlockReconstructed) {
2442 mapBlockSource.emplace(pblock->GetHash(), std::make_pair(pfrom->
GetId(),
false));
2444 bool fNewBlock =
false;
2459 mapBlockSource.erase(pblock->GetHash());
2467 MarkBlockAsReceived(pblock->GetHash());
2478 std::shared_ptr<CBlock> pblock = std::make_shared<CBlock>();
2479 bool fBlockRead =
false;
2483 std::map<uint256, std::pair<NodeId, std::list<QueuedBlock>::iterator> >::iterator it = mapBlocksInFlight.find(resp.blockhash);
2484 if (it == mapBlocksInFlight.end() || !it->second.second->partialBlock ||
2485 it->second.first != pfrom->
GetId()) {
2490 PartiallyDownloadedBlock& partialBlock = *it->second.second->partialBlock;
2493 MarkBlockAsReceived(resp.blockhash);
2495 LogPrintf(
"Peer %d sent us invalid compact block/non-matching block transactions\n", pfrom->
GetId());
2499 std::vector<CInv> invs;
2520 MarkBlockAsReceived(resp.blockhash);
2527 mapBlockSource.emplace(resp.blockhash, std::make_pair(pfrom->
GetId(),
false));
2531 bool fNewBlock =
false;
2543 mapBlockSource.erase(pblock->GetHash());
2555 std::vector<CBlockHeader> headers;
2559 if (nCount > MAX_HEADERS_RESULTS) {
2562 return error(
"headers message size = %u", nCount);
2564 headers.resize(nCount);
2565 for (
unsigned int n = 0; n < nCount; n++) {
2566 headers[n].hashStateRoot =
uint256S(
"9514771014c9ae803d8cea2731b2063e83de44802b40dce2d06acd02d0ff65e9");
2567 headers[n].hashUTXORoot =
uint256S(
"21b463e3b52f6201c0ad6c991be0485b6ef8c092e64583ffa655cc1b171fe856");
2568 vRecv >> headers[n];
2578 return ProcessHeadersMessage(pfrom, connman, headers, chainparams, should_punish);
2587 std::shared_ptr<CBlock> pblock = std::make_shared<CBlock>();
2593 bool forceProcessing =
false;
2594 const uint256 hash(pblock->GetHash());
2599 forceProcessing |= MarkBlockAsReceived(hash);
2602 mapBlockSource.emplace(hash, std::make_pair(pfrom->
GetId(),
true));
2604 bool fNewBlock =
false;
2613 mapBlockSource.erase(pblock->GetHash());
2669 if (pfrom->
nVersion > BIP0031_VERSION)
2691 int64_t pingUsecEnd = nTimeReceived;
2694 bool bPingFinished =
false;
2695 std::string sProblem;
2697 if (nAvail >=
sizeof(nonce)) {
2704 bPingFinished =
true;
2706 if (pingUsecTime > 0) {
2712 sProblem =
"Timing mishap";
2716 sProblem =
"Nonce mismatch";
2719 bPingFinished =
true;
2720 sProblem =
"Nonce zero";
2724 sProblem =
"Unsolicited pong without ping";
2728 bPingFinished =
true;
2729 sProblem =
"Short payload";
2732 if (!(sProblem.empty())) {
2740 if (bPingFinished) {
2751 if (!filter.IsWithinSizeConstraints())
2770 std::vector<unsigned char> vData;
2776 if (vData.size() > MAX_SCRIPT_ELEMENT_SIZE) {
2805 vRecv >> newFeeFilter;
2830 static bool SendRejectsAndCheckIfBanned(
CNode* pnode,
CConnman* connman)
2833 CNodeState &state = *State(pnode->
GetId());
2835 for (
const CBlockReject& reject : state.rejects) {
2838 state.rejects.clear();
2840 if (state.fShouldBan) {
2841 state.fShouldBan =
false;
2871 bool fMoreWork =
false;
2886 std::list<CNetMessage> msgs;
2921 const uint256& hash = msg.GetMessageHash();
2924 LogPrintf(
"%s(%s, %u bytes): CHECKSUM ERROR expected %s was %s\n", __func__,
2935 fRet = ProcessMessage(pfrom, strCommand, vRecv, msg.nTime, chainparams, connman, interruptMsgProc);
2936 if (interruptMsgProc)
2941 catch (
const std::ios_base::failure&
e)
2944 if (strstr(e.what(),
"end of data"))
2947 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());
2949 else if (strstr(e.what(),
"size too large"))
2952 LogPrintf(
"%s(%s, %u bytes): Exception '%s' caught\n", __func__,
SanitizeString(strCommand), nMessageSize, e.what());
2954 else if (strstr(e.what(),
"non-canonical ReadCompactSize()"))
2957 LogPrintf(
"%s(%s, %u bytes): Exception '%s' caught\n", __func__,
SanitizeString(strCommand), nMessageSize, e.what());
2964 catch (
const std::exception& e) {
2975 SendRejectsAndCheckIfBanned(pfrom, connman);
2984 CNodeState &state = *State(pto->
GetId());
2994 if (state.pindexBestKnownBlock !=
nullptr && state.pindexBestKnownBlock->nChainWork >=
chainActive.
Tip()->
nChainWork) {
2995 if (state.m_chain_sync.m_timeout != 0) {
2996 state.m_chain_sync.m_timeout = 0;
2997 state.m_chain_sync.m_work_header =
nullptr;
2998 state.m_chain_sync.m_sent_getheaders =
false;
3000 }
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)) {
3005 state.m_chain_sync.m_timeout = time_in_seconds + CHAIN_SYNC_TIMEOUT;
3007 state.m_chain_sync.m_sent_getheaders =
false;
3008 }
else if (state.m_chain_sync.m_timeout > 0 && time_in_seconds > state.m_chain_sync.m_timeout) {
3012 if (state.m_chain_sync.m_sent_getheaders) {
3014 LogPrintf(
"Disconnecting outbound peer %d for old chain, best known block = %s\n", pto->
GetId(), state.pindexBestKnownBlock !=
nullptr ? state.pindexBestKnownBlock->GetBlockHash().ToString() :
"<none>");
3017 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());
3019 state.m_chain_sync.m_sent_getheaders =
true;
3020 constexpr int64_t HEADERS_RESPONSE_TIME = 120;
3026 state.m_chain_sync.m_timeout = time_in_seconds + HEADERS_RESPONSE_TIME;
3036 if (extra_peers > 0) {
3049 CNodeState *state = State(pnode->
GetId());
3050 if (state ==
nullptr)
return;
3052 if (state->m_chain_sync.m_protect)
return;
3053 if (state->m_last_block_announcement < oldest_block_announcement || (state->m_last_block_announcement == oldest_block_announcement && pnode->
GetId() > worst_peer)) {
3054 worst_peer = pnode->
GetId();
3055 oldest_block_announcement = state->m_last_block_announcement;
3058 if (worst_peer != -1) {
3059 bool disconnected = connman->
ForNode(worst_peer, [&](
CNode *pnode) {
3065 CNodeState &state = *State(pnode->
GetId());
3066 if (time_in_seconds - pnode->
nTimeConnected > MINIMUM_CONNECT_TIME && state.nBlocksInFlight == 0) {
3067 LogPrint(
BCLog::NET,
"disconnecting extra outbound peer=%d (last block announcement received at time %d)\n", pnode->
GetId(), oldest_block_announcement);
3089 if (connman ==
nullptr)
return;
3091 int64_t time_in_seconds =
GetTime();
3099 if (TipMayBeStale(consensusParams)) {
3100 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);
3118 bool operator()(std::set<uint256>::iterator
a, std::set<uint256>::iterator
b)
3140 bool pingSend =
false;
3151 while (nonce == 0) {
3156 if (pto->
nVersion > BIP0031_VERSION) {
3170 if (SendRejectsAndCheckIfBanned(pto, connman))
3172 CNodeState &state = *State(pto->
GetId());
3186 std::vector<CAddress> vAddr;
3193 vAddr.push_back(addr);
3195 if (vAddr.size() >= 1000)
3213 bool fFetch = state.fPreferredDownload || (nPreferredDownload == 0 && !pto->
fClient && !pto->
fOneShot);
3217 state.fSyncStarted =
true;
3228 if (pindexStart->
pprev)
3229 pindexStart = pindexStart->
pprev;
3255 std::vector<CBlock> vHeaders;
3256 bool fRevertToInv = ((!state.fPreferHeaders &&
3260 ProcessBlockAvailability(pto->
GetId());
3262 if (!fRevertToInv) {
3263 bool fFoundStartingHeader =
false;
3273 fRevertToInv =
true;
3276 if (pBestIndex !=
nullptr && pindex->
pprev != pBestIndex) {
3288 fRevertToInv =
true;
3291 pBestIndex = pindex;
3292 if (fFoundStartingHeader) {
3294 vHeaders.push_back(pindex->GetBlockHeader());
3295 }
else if (PeerHasHeader(&state, pindex)) {
3297 }
else if (pindex->pprev ==
nullptr || PeerHasHeader(&state, pindex->pprev)) {
3300 fFoundStartingHeader =
true;
3301 vHeaders.push_back(pindex->GetBlockHeader());
3305 fRevertToInv =
true;
3310 if (!fRevertToInv && !vHeaders.empty()) {
3311 if (vHeaders.size() == 1 && state.fPreferHeaderAndIDs) {
3315 vHeaders.front().GetHash().ToString(), pto->
GetId());
3317 int nSendFlags = state.fWantsCmpctWitness ? 0 : SERIALIZE_TRANSACTION_NO_WITNESS;
3319 bool fGotBlockFromCache =
false;
3321 LOCK(cs_most_recent_block);
3322 if (most_recent_block_hash == pBestIndex->
GetBlockHash()) {
3323 if (state.fWantsCmpctWitness || !fWitnessesPresentInMostRecentCompactBlock)
3329 fGotBlockFromCache =
true;
3332 if (!fGotBlockFromCache) {
3339 state.pindexBestHeaderSent = pBestIndex;
3340 }
else if (state.fPreferHeaders) {
3341 if (vHeaders.size() > 1) {
3344 vHeaders.front().GetHash().ToString(),
3345 vHeaders.back().GetHash().ToString(), pto->
GetId());
3348 vHeaders.front().GetHash().ToString(), pto->
GetId());
3351 state.pindexBestHeaderSent = pBestIndex;
3353 fRevertToInv =
true;
3374 if (!PeerHasHeader(&state, pindex)) {
3387 std::vector<CInv> vInv;
3395 if (vInv.size() == MAX_INV_SZ) {
3405 fSendTrickle =
true;
3428 for (
const auto& txinfo : vtxinfo) {
3429 const uint256& hash = txinfo.tx->GetHash();
3433 if (txinfo.feeRate.GetFeePerK() < filterrate)
3440 vInv.push_back(inv);
3441 if (vInv.size() == MAX_INV_SZ) {
3452 std::vector<std::set<uint256>::iterator> vInvTx;
3455 vInvTx.push_back(it);
3465 std::make_heap(vInvTx.begin(), vInvTx.end(), compareInvMempoolOrder);
3468 unsigned int nRelayedTransactions = 0;
3470 while (!vInvTx.empty() && nRelayedTransactions < INVENTORY_BROADCAST_MAX) {
3472 std::pop_heap(vInvTx.begin(), vInvTx.end(), compareInvMempoolOrder);
3473 std::set<uint256>::iterator it = vInvTx.back();
3487 if (filterrate && txinfo.feeRate.GetFeePerK() < filterrate) {
3493 nRelayedTransactions++;
3496 while (!vRelayExpiration.empty() && vRelayExpiration.front().first < nNow)
3498 mapRelay.erase(vRelayExpiration.front().second);
3499 vRelayExpiration.pop_front();
3502 auto ret = mapRelay.insert(std::make_pair(hash, std::move(txinfo.tx)));
3504 vRelayExpiration.push_back(std::make_pair(nNow + 15 * 60 * 1000000, ret.first));
3507 if (vInv.size() == MAX_INV_SZ) {
3520 if (state.nStallingSince && state.nStallingSince < nNow - 1000000 * BLOCK_STALLING_TIMEOUT) {
3524 LogPrintf(
"Peer=%d is stalling block download, disconnecting\n", pto->
GetId());
3533 if (state.vBlocksInFlight.size() > 0) {
3534 QueuedBlock &queuedBlock = state.vBlocksInFlight.front();
3535 int nOtherPeersWithValidatedDownloads = nPeersWithValidatedDownloads - (state.nBlocksInFlightValidHeaders > 0);
3537 LogPrintf(
"Timeout downloading block %s from peer=%d, disconnecting\n", queuedBlock.hash.ToString(), pto->
GetId());
3546 if (nNow > state.nHeadersSyncTimeout && nSyncStarted == 1 && (nPreferredDownload - state.fPreferredDownload >= 1)) {
3553 LogPrintf(
"Timeout downloading headers from peer=%d, disconnecting\n", pto->
GetId());
3557 LogPrintf(
"Timeout downloading headers from whitelisted peer=%d, not disconnecting\n", pto->
GetId());
3563 state.fSyncStarted =
false;
3565 state.nHeadersSyncTimeout = 0;
3582 std::vector<CInv> vGetData;
3584 std::vector<const CBlockIndex*> vToDownload;
3586 FindNextBlocksToDownload(pto->
GetId(), MAX_BLOCKS_IN_TRANSIT_PER_PEER - state.nBlocksInFlight, vToDownload, staller, consensusParams);
3594 if (state.nBlocksInFlight == 0 && staller != -1) {
3595 if (State(staller)->nStallingSince == 0) {
3596 State(staller)->nStallingSince = nNow;
3608 if (!AlreadyHave(inv))
3611 vGetData.push_back(inv);
3612 if (vGetData.size() >= 1000)
3623 if (!vGetData.empty())
3635 static CFeeRate default_feerate(DEFAULT_MIN_RELAY_TX_FEE);
3637 CAmount filterToSend = filterRounder.
round(currentFilter);
3649 (currentFilter < 3 * pto->lastSentFeeFilter / 4 || currentFilter > 4 * pto->
lastSentFeeFilter / 3)) {
3663 mapOrphanTransactions.clear();
3664 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 ...
CAmount GetFeePerK() const
Return the fee in liu for a size of 1000 bytes.
enum ReadStatus_t ReadStatus
const char * PING
The ping message is sent periodically to help confirm that the receiving peer is still connected...
CFeeRate GetMinFee(size_t sizelimit) const
The minimum fee to get into the mempool, which may itself not be enough for larger-sized transactions...
unsigned int LimitOrphanTxSize(unsigned int nMaxOrphans) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
bool error(const char *fmt, const Args &...args)
std::atomic< uint64_t > nPingNonceSent
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
const char * BLOCKTXN
Contains a BlockTransactions.
bool fPruneMode
True if we're running in -prune mode.
uint64_t GetLocalNonce() const
bool HaveCoinInCache(const COutPoint &outpoint) const
Check if we have the given utxo already loaded in this cache.
bool contains(const std::vector< unsigned char > &vKey) const
ReadStatus FillBlock(CBlock &block, const std::vector< CTransactionRef > &vtx_missing)
ServiceFlags
nServices flags
CCriticalSection cs_filter
unsigned int GetReceiveFloodSize() const
int64_t GetTransactionWeight(const CTransaction &tx)
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)
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)
bool IsArgSet(const std::string &strArg)
Return true if the given argument has been manually set.
void SetIP(const CNetAddr &ip)
void WakeMessageHandler()
void SetServices(const CService &addr, ServiceFlags nServices)
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
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.
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.
All parent headers found, difficulty matches, timestamp >= median previous, checkpoint.
std::vector< uint256 > vInventoryBlockToSend
bool MoneyRange(const CAmount &nValue)
void AskFor(const CInv &inv)
const Consensus::Params & GetConsensus() const
bool CorruptionPossible() const
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()
Only first tx is coinbase, 2 <= coinbase input script length <= 100, transactions valid...
bool IsOutboundDisconnectionCandidate(const CNode *node)
void PushMessage(CNode *pnode, CSerializedNetMsg &&msg)
bool GetBoolArg(const std::string &strArg, bool fDefault)
Return boolean argument or default value.
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
assert(len-trim+(2 *lenIndices)<=WIDTH)
CChainParams defines various tweakable parameters of a given instance of the Fabcoin system...
size_t DynamicMemoryUsage() const
void Inventory(const uint256 &)
Double ended buffer combining vector and stream-like interfaces.
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)
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)
if(a.IndicesBefore(b, len, lenIndices))
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.
std::vector< TxMempoolInfo > infoAll() const
ServiceFlags nServicesExpected
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.
std::string ToString() const
int64_t CAmount
Amount in lius (Can be negative)
int64_t GetnPowTargetSpacing(uint32_t nHeight=0) const
bool ReadBlockFromDisk(Block &block, const CDiskBlockPos &pos, const Consensus::Params &consensusParams)
Functions for disk access for blocks.
#define AssertLockHeld(cs)
std::atomic< int64_t > nPingUsecTime
CBlockIndex * Tip() const
Returns the index entry for the tip of this chain, or nullptr if none.
std::atomic< int64_t > nMinPingUsecTime
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)
Outputs do not overspend inputs, no double spends, coinbase output ok, no immature coinbase spends...
int Height() const
Return the maximal height in the chain.
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.
unsigned int nStatus
Verification status of this block. See enum BlockStatus.
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...
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).
std::vector< CTransactionRef > txn
An input of a transaction.
TxMempoolInfo info(const uint256 &hash) const
size_t GetAddressCount() const
bool IsPeerAddrLocalGood(CNode *pnode)
bool IsTxAvailable(size_t index) const
A combination of a network address (CNetAddr) and a (TCP) port.
bool OutboundTargetReached(bool historicalBlockServingLimit)
check if the outbound target is reached
uint256 uint256S(const char *str)
std::vector< CAddress > GetAddresses()
CRollingBloomFilter filterInventoryKnown
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 ...
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) ...
CMainSignals & GetMainSignals()
std::string ToString() const
std::vector< uint256 > vBlockHashesToAnnounce
const char * ADDR
The addr (IP address) message relays connection information for peers on the network.
std::atomic< int64_t > nTimeBestReceived(0)
void AddNewAddresses(const std::vector< CAddress > &vAddr, const CAddress &addrFrom, int64_t nTimePenalty=0)
const CMessageHeader::MessageStartChars & MessageStart() const
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
const char * NOTFOUND
The notfound message is a reply to a getdata message which requested an object the receiving node doe...
Parameters that influence chain consensus.
int GetSendVersion() const
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 ...
int GetMyStartingHeight() const
ServiceFlags GetLocalServices() const
void ForEachNode(Callable &&func)
int GetRecvVersion() const
CRollingBloomFilter addrKnown
bool AcceptToMemoryPool(CTxMemPool &pool, CValidationState &state, const CTransactionRef &tx, bool fLimitFree, bool *pfMissingInputs, std::list< CTransactionRef > *plTxnReplaced, bool fOverrideMempoolLimit, const CAmount nAbsurdFee, bool rawTx)
(try to) add transaction to memory pool plTxnReplaced will be appended to with all transactions repla...
const char * REJECT
The reject message informs the receiving node that one of its previous messages has been rejected...
bool CheckIncomingNonce(uint64_t nonce)
bool exists(uint256 hash) const
const char * GETBLOCKS
The getblocks message requests an inv message that provides block header hashes starting from a parti...
std::string GetRejectReason() const
const int64_t nTimeConnected
unsigned int GetRejectCode() const
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,...)
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
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::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::string GetAddrName() 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::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.
std::string GetArg(const std::string &strArg, const std::string &strDefault)
Return string argument or default value.
void UpdateLastBlockAnnounceTime(NodeId node, int64_t time_in_seconds)
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)
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)
bool Contains(const CBlockIndex *pindex) const
Efficiently check whether a block is present in this chain.
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 liu per kilobyte: CAmount / kB.
std::atomic_bool fSuccessfullyConnected
void GetRandBytes(unsigned char *buf, int num)
Functions to gather random data via the OpenSSL PRNG.
std::atomic< int > nVersion
bool IsValid(enum BlockStatus nUpTo=BLOCK_VALID_TRANSACTIONS) const
Check whether this block index entry is valid up to the passed validity level.
bool IsWitnessEnabled(const CBlockIndex *pindexPrev, const Consensus::Params ¶ms)
Check whether witness commitments are required for block.
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
const uint256 & GetHash() const
int GetExtraOutboundCount()
CSipHasher GetDeterministicRandomizer(uint64_t id) const
Get a unique deterministic randomizer.
dev::WithExisting max(dev::WithExisting _a, dev::WithExisting _b)
int64_t GetTime()
GetTimeMicros() and GetTimeMillis() both return the system time, but in different units...
PeerLogicValidation(CConnman *connman, CScheduler &scheduler)
struct evm_uint160be address(struct evm_env *env)
void AddToCompactExtraTransactions(const CTransactionRef &tx)
CBlockLocator GetLocator(const CBlockIndex *pindex=nullptr) const
Return a CBlockLocator that refers to a block in this chain (by default the tip). ...
const char * TX
The tx message transmits a single transaction.
The basic transaction that is broadcasted on the network and contained in blocks. ...
void MarkAddressGood(const CAddress &addr)
int nHeight
height of the entry in the chain. The genesis block has height 0
Information about a peer.
std::vector< int > vHeightInFlight
CAmount round(CAmount currentMinFee)
Quantize a minimum fee for privacy purpose before broadcast.
full block available in blk*.dat
std::string ToString() const
void AddTimeData(const CNetAddr &ip, int64_t nOffsetSample)
int64_t GetBlockTime() const
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
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...
uint256 GetBlockHash() const
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 > GetKey() const
std::vector< unsigned char > ParseHex(const char *psz)