34 #include <boost/thread.hpp>
37 # error "Dogecoin 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;
78 std::map<uint256, std::pair<NodeId, bool>> mapBlockSource;
100 std::unique_ptr<CRollingBloomFilter> recentRejects;
101 uint256 hashRecentRejectsChainTip;
107 bool fValidatedHeaders;
108 std::unique_ptr<PartiallyDownloadedBlock> partialBlock;
110 std::map<uint256, std::pair<NodeId, std::list<QueuedBlock>::iterator> > mapBlocksInFlight;
113 std::list<NodeId> lNodesAnnouncingHeaderAndIDs;
116 int nPreferredDownload = 0;
119 int nPeersWithValidatedDownloads = 0;
122 typedef std::map<uint256, CTransactionRef> MapRelay;
125 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 nStallingSince;
174 std::list<QueuedBlock> vBlocksInFlight;
176 int64_t nDownloadingSince;
178 int nBlocksInFlightValidHeaders;
180 bool fPreferredDownload;
184 bool fPreferHeaderAndIDs;
190 bool fProvidesHeaderAndIDs;
194 bool fWantsCmpctWitness;
199 bool fSupportsDesiredCmpctVersion;
201 CNodeState(
CAddress addrIn, std::string addrNameIn) : address(addrIn), name(addrNameIn) {
202 fCurrentlyConnected =
false;
205 pindexBestKnownBlock = NULL;
206 hashLastUnknownBlock.
SetNull();
207 pindexLastCommonBlock = NULL;
208 pindexBestHeaderSent = NULL;
209 nUnconnectingHeaders = 0;
210 fSyncStarted =
false;
212 nDownloadingSince = 0;
214 nBlocksInFlightValidHeaders = 0;
215 fPreferredDownload =
false;
216 fPreferHeaders =
false;
217 fPreferHeaderAndIDs =
false;
218 fProvidesHeaderAndIDs =
false;
219 fHaveWitness =
false;
220 fWantsCmpctWitness =
false;
221 fSupportsDesiredCmpctVersion =
false;
226 std::map<NodeId, CNodeState> mapNodeState;
229 CNodeState *State(
NodeId pnode) {
230 std::map<NodeId, CNodeState>::iterator it = mapNodeState.find(pnode);
231 if (it == mapNodeState.end())
236 void UpdatePreferredDownload(
CNode* node, CNodeState* state)
238 nPreferredDownload -= state->fPreferredDownload;
243 nPreferredDownload += state->fPreferredDownload;
246 void PushNodeVersion(
CNode *pnode,
CConnman& connman, int64_t nTime)
261 LogPrint(
"net",
"send version message: version %d, blocks=%d, us=%s, them=%s, peer=%d\n", PROTOCOL_VERSION, nNodeStartingHeight, addrMe.
ToString(), addrYou.
ToString(), nodeid);
263 LogPrint(
"net",
"send version message: version %d, blocks=%d, us=%s, peer=%d\n", PROTOCOL_VERSION, nNodeStartingHeight, addrMe.
ToString(), nodeid);
272 mapNodeState.emplace_hint(mapNodeState.end(), std::piecewise_construct, std::forward_as_tuple(nodeid), std::forward_as_tuple(addr, std::move(addrName)));
275 PushNodeVersion(pnode, connman,
GetTime());
278 void FinalizeNode(
NodeId nodeid,
bool& fUpdateConnectionTime) {
279 fUpdateConnectionTime =
false;
281 CNodeState *state = State(nodeid);
283 if (state->fSyncStarted)
286 if (state->nMisbehavior == 0 && state->fCurrentlyConnected) {
287 fUpdateConnectionTime =
true;
290 BOOST_FOREACH(
const QueuedBlock& entry, state->vBlocksInFlight) {
291 mapBlocksInFlight.erase(entry.hash);
294 nPreferredDownload -= state->fPreferredDownload;
295 nPeersWithValidatedDownloads -= (state->nBlocksInFlightValidHeaders != 0);
296 assert(nPeersWithValidatedDownloads >= 0);
298 mapNodeState.erase(nodeid);
300 if (mapNodeState.empty()) {
302 assert(mapBlocksInFlight.empty());
303 assert(nPreferredDownload == 0);
304 assert(nPeersWithValidatedDownloads == 0);
311 bool MarkBlockAsReceived(
const uint256& hash) {
312 std::map<uint256, std::pair<NodeId, std::list<QueuedBlock>::iterator> >::iterator itInFlight = mapBlocksInFlight.find(hash);
313 if (itInFlight != mapBlocksInFlight.end()) {
314 CNodeState *state = State(itInFlight->second.first);
315 state->nBlocksInFlightValidHeaders -= itInFlight->second.second->fValidatedHeaders;
316 if (state->nBlocksInFlightValidHeaders == 0 && itInFlight->second.second->fValidatedHeaders) {
318 nPeersWithValidatedDownloads--;
320 if (state->vBlocksInFlight.begin() == itInFlight->second.second) {
322 state->nDownloadingSince = std::max(state->nDownloadingSince,
GetTimeMicros());
324 state->vBlocksInFlight.erase(itInFlight->second.second);
325 state->nBlocksInFlight--;
326 state->nStallingSince = 0;
327 mapBlocksInFlight.erase(itInFlight);
337 CNodeState *state = State(nodeid);
338 assert(state != NULL);
341 std::map<uint256, std::pair<NodeId, std::list<QueuedBlock>::iterator> >::iterator itInFlight = mapBlocksInFlight.find(hash);
342 if (itInFlight != mapBlocksInFlight.end() && itInFlight->second.first == nodeid) {
343 *pit = &itInFlight->second.second;
348 MarkBlockAsReceived(hash);
350 std::list<QueuedBlock>::iterator it = state->vBlocksInFlight.insert(state->vBlocksInFlight.end(),
351 {hash, pindex, pindex != NULL, std::unique_ptr<PartiallyDownloadedBlock>(pit ? new PartiallyDownloadedBlock(&mempool) : NULL)});
352 state->nBlocksInFlight++;
353 state->nBlocksInFlightValidHeaders += it->fValidatedHeaders;
354 if (state->nBlocksInFlight == 1) {
358 if (state->nBlocksInFlightValidHeaders == 1 && pindex != NULL) {
359 nPeersWithValidatedDownloads++;
361 itInFlight = mapBlocksInFlight.insert(std::make_pair(hash, std::make_pair(nodeid, it))).first;
363 *pit = &itInFlight->second.second;
368 void ProcessBlockAvailability(
NodeId nodeid) {
369 CNodeState *state = State(nodeid);
370 assert(state != NULL);
372 if (!state->hashLastUnknownBlock.IsNull()) {
373 BlockMap::iterator itOld =
mapBlockIndex.find(state->hashLastUnknownBlock);
374 if (itOld !=
mapBlockIndex.end() && itOld->second->nChainWork > 0) {
375 if (state->pindexBestKnownBlock == NULL || itOld->second->nChainWork >= state->pindexBestKnownBlock->nChainWork)
376 state->pindexBestKnownBlock = itOld->second;
377 state->hashLastUnknownBlock.SetNull();
383 void UpdateBlockAvailability(
NodeId nodeid,
const uint256 &hash) {
384 CNodeState *state = State(nodeid);
385 assert(state != NULL);
387 ProcessBlockAvailability(nodeid);
390 if (it !=
mapBlockIndex.end() && it->second->nChainWork > 0) {
392 if (state->pindexBestKnownBlock == NULL || it->second->nChainWork >= state->pindexBestKnownBlock->nChainWork)
393 state->pindexBestKnownBlock = it->second;
396 state->hashLastUnknownBlock = hash;
400 void MaybeSetPeerAsAnnouncingHeaderAndIDs(
NodeId nodeid,
CConnman& connman) {
402 CNodeState* nodestate = State(nodeid);
403 if (!nodestate || !nodestate->fSupportsDesiredCmpctVersion) {
407 if (nodestate->fProvidesHeaderAndIDs) {
408 for (std::list<NodeId>::iterator it = lNodesAnnouncingHeaderAndIDs.begin(); it != lNodesAnnouncingHeaderAndIDs.end(); it++) {
410 lNodesAnnouncingHeaderAndIDs.erase(it);
411 lNodesAnnouncingHeaderAndIDs.push_back(nodeid);
416 bool fAnnounceUsingCMPCTBLOCK =
false;
418 if (lNodesAnnouncingHeaderAndIDs.size() >= 3) {
421 connman.
ForNode(lNodesAnnouncingHeaderAndIDs.front(), [&connman, fAnnounceUsingCMPCTBLOCK, nCMPCTBLOCKVersion](
CNode* pnodeStop){
422 connman.PushMessage(pnodeStop, CNetMsgMaker(pnodeStop->GetSendVersion()).Make(NetMsgType::SENDCMPCT, fAnnounceUsingCMPCTBLOCK, nCMPCTBLOCKVersion));
425 lNodesAnnouncingHeaderAndIDs.pop_front();
427 fAnnounceUsingCMPCTBLOCK =
true;
429 lNodesAnnouncingHeaderAndIDs.push_back(pfrom->
GetId());
442 bool PeerHasHeader(CNodeState *state,
const CBlockIndex *pindex)
444 if (state->pindexBestKnownBlock && pindex == state->pindexBestKnownBlock->GetAncestor(pindex->
nHeight))
446 if (state->pindexBestHeaderSent && pindex == state->pindexBestHeaderSent->GetAncestor(pindex->
nHeight))
460 while (pa != pb && pa && pb) {
472 void FindNextBlocksToDownload(
NodeId nodeid,
unsigned int count, std::vector<const CBlockIndex*>& vBlocks,
NodeId& nodeStaller,
const Consensus::Params& consensusParams) {
476 vBlocks.reserve(vBlocks.size() + count);
477 CNodeState *state = State(nodeid);
478 assert(state != NULL);
481 ProcessBlockAvailability(nodeid);
483 if (state->pindexBestKnownBlock == NULL || state->pindexBestKnownBlock->nChainWork <
chainActive.
Tip()->
nChainWork) {
488 if (state->pindexLastCommonBlock == NULL) {
496 state->pindexLastCommonBlock = LastCommonAncestor(state->pindexLastCommonBlock, state->pindexBestKnownBlock);
497 if (state->pindexLastCommonBlock == state->pindexBestKnownBlock)
500 std::vector<const CBlockIndex*> vToFetch;
501 const CBlockIndex *pindexWalk = state->pindexLastCommonBlock;
505 int nWindowEnd = state->pindexLastCommonBlock->
nHeight + BLOCK_DOWNLOAD_WINDOW;
506 int nMaxHeight = std::min<int>(state->pindexBestKnownBlock->nHeight, nWindowEnd + 1);
508 while (pindexWalk->
nHeight < nMaxHeight) {
512 int nToFetch = std::min(nMaxHeight - pindexWalk->
nHeight, std::max<int>(count - vBlocks.size(), 128));
513 vToFetch.resize(nToFetch);
514 pindexWalk = state->pindexBestKnownBlock->
GetAncestor(pindexWalk->
nHeight + nToFetch);
515 vToFetch[nToFetch - 1] = pindexWalk;
516 for (
unsigned int i = nToFetch - 1; i > 0; i--) {
517 vToFetch[i - 1] = vToFetch[i]->
pprev;
524 BOOST_FOREACH(
const CBlockIndex* pindex, vToFetch) {
535 state->pindexLastCommonBlock = pindex;
536 }
else if (mapBlocksInFlight.count(pindex->
GetBlockHash()) == 0) {
538 if (pindex->
nHeight > nWindowEnd) {
540 if (vBlocks.size() == 0 && waitingfor != nodeid) {
542 nodeStaller = waitingfor;
546 vBlocks.push_back(pindex);
547 if (vBlocks.size() == count) {
550 }
else if (waitingfor == -1) {
552 waitingfor = mapBlocksInFlight[pindex->
GetBlockHash()].first;
562 CNodeState *state = State(nodeid);
566 stats.
nSyncHeight = state->pindexBestKnownBlock ? state->pindexBestKnownBlock->nHeight : -1;
567 stats.
nCommonHeight = state->pindexLastCommonBlock ? state->pindexLastCommonBlock->nHeight : -1;
568 BOOST_FOREACH(
const QueuedBlock& queue, state->vBlocksInFlight) {
598 size_t max_extra_txn =
GetArg(
"-blockreconstructionextratxn", DEFAULT_BLOCK_RECONSTRUCTION_EXTRA_TXN);
599 if (max_extra_txn <= 0)
601 if (!vExtraTxnForCompact.size())
602 vExtraTxnForCompact.resize(max_extra_txn);
603 vExtraTxnForCompact[vExtraTxnForCompactIt] = std::make_pair(tx->GetWitnessHash(), tx);
604 vExtraTxnForCompactIt = (vExtraTxnForCompactIt + 1) % max_extra_txn;
609 const uint256& hash = tx->GetHash();
610 if (mapOrphanTransactions.count(hash))
621 if (sz >= MAX_STANDARD_TX_WEIGHT)
623 LogPrint(
"mempool",
"ignoring large orphan tx (size: %u, hash: %s)\n", sz, hash.
ToString());
627 auto ret = mapOrphanTransactions.emplace(hash,
COrphanTx{tx, peer,
GetTime() + ORPHAN_TX_EXPIRE_TIME});
629 BOOST_FOREACH(
const CTxIn& txin, tx->vin) {
630 mapOrphanTransactionsByPrev[txin.
prevout].insert(ret.first);
635 LogPrint(
"mempool",
"stored orphan tx %s (mapsz %u outsz %u)\n", hash.
ToString(),
636 mapOrphanTransactions.size(), mapOrphanTransactionsByPrev.size());
642 std::map<uint256, COrphanTx>::iterator it = mapOrphanTransactions.find(hash);
643 if (it == mapOrphanTransactions.end())
645 BOOST_FOREACH(
const CTxIn& txin, it->second.tx->vin)
647 auto itPrev = mapOrphanTransactionsByPrev.find(txin.
prevout);
648 if (itPrev == mapOrphanTransactionsByPrev.end())
650 itPrev->second.erase(it);
651 if (itPrev->second.empty())
652 mapOrphanTransactionsByPrev.erase(itPrev);
654 mapOrphanTransactions.erase(it);
661 std::map<uint256, COrphanTx>::iterator iter = mapOrphanTransactions.begin();
662 while (iter != mapOrphanTransactions.end())
664 std::map<uint256, COrphanTx>::iterator maybeErase = iter++;
665 if (maybeErase->second.fromPeer == peer)
667 nErased += EraseOrphanTx(maybeErase->second.tx->GetHash());
670 if (nErased > 0)
LogPrint(
"mempool",
"Erased %d orphan tx from peer=%d\n", nErased, peer);
676 unsigned int nEvicted = 0;
677 static int64_t nNextSweep;
679 if (nNextSweep <= nNow) {
682 int64_t nMinExpTime = nNow + ORPHAN_TX_EXPIRE_TIME - ORPHAN_TX_EXPIRE_INTERVAL;
683 std::map<uint256, COrphanTx>::iterator iter = mapOrphanTransactions.begin();
684 while (iter != mapOrphanTransactions.end())
686 std::map<uint256, COrphanTx>::iterator maybeErase = iter++;
687 if (maybeErase->second.nTimeExpire <= nNow) {
688 nErased += EraseOrphanTx(maybeErase->second.tx->GetHash());
690 nMinExpTime = std::min(maybeErase->second.nTimeExpire, nMinExpTime);
694 nNextSweep = nMinExpTime + ORPHAN_TX_EXPIRE_INTERVAL;
695 if (nErased > 0)
LogPrint(
"mempool",
"Erased %d orphan tx due to expiration\n", nErased);
697 while (mapOrphanTransactions.size() > nMaxOrphans)
701 std::map<uint256, COrphanTx>::iterator it = mapOrphanTransactions.lower_bound(randomhash);
702 if (it == mapOrphanTransactions.end())
703 it = mapOrphanTransactions.begin();
704 EraseOrphanTx(it->first);
716 CNodeState *state = State(pnode);
720 state->nMisbehavior += howmuch;
721 int banscore =
GetArg(
"-banscore", DEFAULT_BANSCORE_THRESHOLD);
722 if (state->nMisbehavior >= banscore && state->nMisbehavior - howmuch < banscore)
724 LogPrintf(
"%s: %s peer=%d (%d -> %d) BAN THRESHOLD EXCEEDED\n", __func__, state->name, pnode, state->nMisbehavior-howmuch, state->nMisbehavior);
725 state->fShouldBan =
true;
727 LogPrintf(
"%s: %s peer=%d (%d -> %d)\n", __func__, state->name, pnode, state->nMisbehavior-howmuch, state->nMisbehavior);
753 std::vector<uint256> vOrphanErase;
755 for (
size_t j = 0; j < tx.
vin.size(); j++) {
756 auto itByPrev = mapOrphanTransactionsByPrev.find(tx.
vin[j].prevout);
757 if (itByPrev == mapOrphanTransactionsByPrev.end())
continue;
758 for (
auto mi = itByPrev->second.begin(); mi != itByPrev->second.end(); ++mi) {
761 vOrphanErase.push_back(orphanHash);
766 if (vOrphanErase.size()) {
768 BOOST_FOREACH(
uint256 &orphanHash, vOrphanErase) {
769 nErased += EraseOrphanTx(orphanHash);
771 LogPrint(
"mempool",
"Erased %d orphan tx included or conflicted by block\n", nErased);
776 static std::shared_ptr<const CBlock> most_recent_block;
777 static std::shared_ptr<const CBlockHeaderAndShortTxIDs> most_recent_compact_block;
778 static uint256 most_recent_block_hash;
781 std::shared_ptr<const CBlockHeaderAndShortTxIDs> pcmpctblock = std::make_shared<const CBlockHeaderAndShortTxIDs> (*pblock,
true);
786 static int nHighestFastAnnounce = 0;
787 if (pindex->
nHeight <= nHighestFastAnnounce)
789 nHighestFastAnnounce = pindex->
nHeight;
792 uint256 hashBlock(pblock->GetHash());
795 LOCK(cs_most_recent_block);
796 most_recent_block_hash = hashBlock;
797 most_recent_block = pblock;
798 most_recent_compact_block = pcmpctblock;
805 ProcessBlockAvailability(pnode->
GetId());
806 CNodeState &state = *State(pnode->
GetId());
809 if (state.fPreferHeaderAndIDs && (!fWitnessEnabled || state.fWantsCmpctWitness) &&
810 !PeerHasHeader(&state, pindex) && PeerHasHeader(&state, pindex->
pprev)) {
812 LogPrint(
"net",
"%s sending header-and-ids %s to peer=%d\n",
"PeerLogicValidation::NewPoWValidBlock",
813 hashBlock.ToString(), pnode->id);
814 connman->PushMessage(pnode, msgMaker.Make(NetMsgType::CMPCTBLOCK, *pcmpctblock));
815 state.pindexBestHeaderSent = pindex;
821 const int nNewHeight = pindexNew->
nHeight;
824 if (!fInitialDownload) {
826 std::vector<uint256> vHashes;
828 while (pindexToAnnounce != pindexFork) {
830 pindexToAnnounce = pindexToAnnounce->
pprev;
831 if (vHashes.size() == MAX_BLOCKS_TO_ANNOUNCE) {
840 BOOST_REVERSE_FOREACH(const uint256& hash, vHashes) {
841 pnode->PushBlockHash(hash);
855 std::map<uint256, std::pair<NodeId, bool>>::iterator it = mapBlockSource.find(hash);
859 if (it != mapBlockSource.end() && State(it->second.first)) {
862 State(it->second.first)->rejects.push_back(reject);
863 if (nDoS > 0 && it->second.second)
875 mapBlocksInFlight.count(hash) == mapBlocksInFlight.size()) {
876 if (it != mapBlockSource.end()) {
877 MaybeSetPeerAsAnnouncingHeaderAndIDs(it->second.first, *
connman);
880 if (it != mapBlockSource.end())
881 mapBlockSource.erase(it);
897 assert(recentRejects);
905 recentRejects->reset();
910 return recentRejects->contains(inv.hash) ||
912 mapOrphanTransactions.count(inv.hash) ||
932 static void RelayAddress(
const CAddress& addr,
bool fReachable,
CConnman& connman)
934 unsigned int nRelayNodes = fReachable ? 2 : 1;
939 uint64_t hashAddr = addr.
GetHash();
943 std::array<std::pair<uint64_t, CNode*>,2> best{{{0,
nullptr}, {0,
nullptr}}};
944 assert(nRelayNodes <= best.size());
946 auto sortfunc = [&best, &hasher, nRelayNodes](
CNode* pnode) {
947 if (pnode->
nVersion >= CADDR_TIME_VERSION) {
949 for (
unsigned int i = 0; i < nRelayNodes; i++) {
950 if (hashKey > best[i].first) {
951 std::copy(best.begin() + i, best.begin() + nRelayNodes - 1, best.begin() + i + 1);
952 best[i] = std::make_pair(hashKey, pnode);
959 auto pushfunc = [&addr, &best, nRelayNodes, &insecure_rand] {
960 for (
unsigned int i = 0; i < nRelayNodes && best[i].first != 0; i++) {
961 best[i].second->PushAddress(addr, insecure_rand);
970 std::deque<CInv>::iterator it = pfrom->
vRecvGetData.begin();
971 std::vector<CInv> vNotFound;
980 const CInv &inv = *it;
982 if (interruptMsgProc)
1000 std::shared_ptr<const CBlock> a_recent_block;
1002 LOCK(cs_most_recent_block);
1003 a_recent_block = most_recent_block;
1011 static const int nOneMonth = 30 * 24 * 60 * 60;
1019 LogPrintf(
"%s: ignoring request from peer=%i for old block that isn't in the main chain\n", __func__, pfrom->
GetId());
1025 static const int nOneWeek = 7 * 24 * 60 * 60;
1028 LogPrint(
"net",
"historical block serving limit reached, disconnect peer=%d\n", pfrom->
GetId());
1041 assert(!
"cannot load block from disk");
1048 bool sendMerkleBlock =
false;
1053 sendMerkleBlock =
true;
1057 if (sendMerkleBlock) {
1065 typedef std::pair<unsigned int, uint256> PairType;
1066 BOOST_FOREACH(PairType& pair, merkleBlock.
vMatchedTxn)
1067 connman.PushMessage(pfrom, msgMaker.Make(SERIALIZE_TRANSACTION_NO_WITNESS,
NetMsgType::
TX, *block.vtx[pair.first]));
1078 bool fPeerWantsWitness = State(pfrom->GetId())->fWantsCmpctWitness;
1079 int nSendFlags = fPeerWantsWitness ? 0 : SERIALIZE_TRANSACTION_NO_WITNESS;
1080 if (CanDirectFetch(consensusParams) && mi->second->nHeight >=
chainActive.
Height() - MAX_CMPCTBLOCK_DEPTH) {
1088 if (inv.
hash == pfrom->hashContinue)
1093 std::vector<CInv> vInv;
1096 pfrom->hashContinue.SetNull();
1104 auto mi = mapRelay.find(inv.
hash);
1105 int nSendFlags = (inv.
type ==
MSG_TX ? SERIALIZE_TRANSACTION_NO_WITNESS : 0);
1106 if (mi != mapRelay.end()) {
1109 }
else if (pfrom->timeLastMempoolReq) {
1113 if (txinfo.tx && txinfo.nTime <= pfrom->timeLastMempoolReq) {
1119 vNotFound.push_back(inv);
1131 pfrom->vRecvGetData.erase(pfrom->vRecvGetData.begin(), it);
1133 if (!vNotFound.empty()) {
1146 uint32_t nFetchFlags = 0;
1155 for (
size_t i = 0; i < req.
indexes.size(); i++) {
1159 LogPrintf(
"Peer %d sent us a getblocktxn with out-of-bounds tx indices", pfrom->
id);
1166 int nSendFlags = State(pfrom->
GetId())->fWantsCmpctWitness ? 0 : SERIALIZE_TRANSACTION_NO_WITNESS;
1170 bool static ProcessMessage(
CNode* pfrom,
const std::string& strCommand,
CDataStream& vRecv, int64_t nTimeReceived,
const CChainParams& chainparams,
CConnman& connman,
const std::atomic<bool>& interruptMsgProc)
1175 LogPrintf(
"dropmessagestest DROPPING RECV MESSAGE\n");
1184 if (pfrom->
nVersion >= NO_BLOOM_VERSION) {
1198 std::string strMsg;
unsigned char ccode; std::string strReason;
1201 std::ostringstream ss;
1202 ss << strMsg <<
" code " <<
itostr(ccode) <<
": " << strReason;
1208 ss <<
": hash " << hash.
ToString();
1211 }
catch (
const std::ios_base::failure&) {
1213 LogPrint(
"net",
"Unparseable reject message received\n");
1232 uint64_t nNonce = 1;
1233 uint64_t nServiceInt;
1237 std::string strSubVer;
1238 std::string cleanSubVer;
1239 int nStartingHeight = -1;
1242 vRecv >> nVersion >> nServiceInt >> nTime >> addrMe;
1243 nSendVersion = std::min(nVersion, PROTOCOL_VERSION);
1251 LogPrint(
"net",
"peer=%d does not offer the expected services (%08x offered, %08x expected); disconnecting\n", pfrom->
id, nServices, pfrom->
nServicesExpected);
1258 if (nVersion < MIN_PEER_PROTO_VERSION)
1261 LogPrintf(
"peer=%d using obsolete version %i; disconnecting\n", pfrom->
id, nVersion);
1263 strprintf(
"Version must be %d or greater", MIN_PEER_PROTO_VERSION)));
1268 if (nVersion == 10300)
1271 vRecv >> addrFrom >> nNonce;
1272 if (!vRecv.
empty()) {
1276 if (!vRecv.
empty()) {
1277 vRecv >> nStartingHeight;
1321 State(pfrom->
GetId())->fHaveWitness =
true;
1327 UpdatePreferredDownload(pfrom, State(pfrom->
GetId()));
1339 LogPrint(
"net",
"ProcessMessages: advertising address %s\n", addr.
ToString());
1343 LogPrint(
"net",
"ProcessMessages: advertising address %s\n", addr.
ToString());
1357 std::string remoteAddr;
1361 LogPrintf(
"receive version message: %s: version %d, blocks=%d, us=%s, peer=%d%s\n",
1366 int64_t nTimeOffset = nTime -
GetTime();
1404 State(pfrom->
GetId())->fCurrentlyConnected =
true;
1407 if (pfrom->
nVersion >= SENDHEADERS_VERSION) {
1414 if (pfrom->
nVersion >= SHORT_IDS_BLOCKS_VERSION) {
1420 bool fAnnounceUsingCMPCTBLOCK =
false;
1421 uint64_t nCMPCTBLOCKVersion = 2;
1424 nCMPCTBLOCKVersion = 1;
1440 std::vector<CAddress> vAddr;
1446 if (vAddr.size() > 1000)
1450 return error(
"message addr size() = %u", vAddr.size());
1454 std::vector<CAddress> vAddrOk;
1456 int64_t nSince = nNow - 10 * 60;
1457 BOOST_FOREACH(
CAddress& addr, vAddr)
1459 if (interruptMsgProc)
1462 if ((addr.
nServices & REQUIRED_SERVICES) != REQUIRED_SERVICES)
1465 if (addr.
nTime <= 100000000 || addr.
nTime > nNow + 10 * 60)
1466 addr.
nTime = nNow - 5 * 24 * 60 * 60;
1472 RelayAddress(addr, fReachable, connman);
1476 vAddrOk.push_back(addr);
1479 if (vAddr.size() < 1000)
1488 State(pfrom->
GetId())->fPreferHeaders =
true;
1493 bool fAnnounceUsingCMPCTBLOCK =
false;
1494 uint64_t nCMPCTBLOCKVersion = 0;
1495 vRecv >> fAnnounceUsingCMPCTBLOCK >> nCMPCTBLOCKVersion;
1499 if (!State(pfrom->
GetId())->fProvidesHeaderAndIDs) {
1500 State(pfrom->
GetId())->fProvidesHeaderAndIDs =
true;
1501 State(pfrom->
GetId())->fWantsCmpctWitness = nCMPCTBLOCKVersion == 2;
1503 if (State(pfrom->
GetId())->fWantsCmpctWitness == (nCMPCTBLOCKVersion == 2))
1504 State(pfrom->
GetId())->fPreferHeaderAndIDs = fAnnounceUsingCMPCTBLOCK;
1505 if (!State(pfrom->
GetId())->fSupportsDesiredCmpctVersion) {
1507 State(pfrom->
GetId())->fSupportsDesiredCmpctVersion = (nCMPCTBLOCKVersion == 2);
1509 State(pfrom->
GetId())->fSupportsDesiredCmpctVersion = (nCMPCTBLOCKVersion == 1);
1517 std::vector<CInv> vInv;
1519 if (vInv.size() > MAX_INV_SZ)
1523 return error(
"message inv size() = %u", vInv.size());
1530 fBlocksOnly =
false;
1536 std::vector<CInv> vToFetch;
1538 for (
unsigned int nInv = 0; nInv < vInv.size(); nInv++)
1540 CInv &inv = vInv[nInv];
1542 if (interruptMsgProc)
1545 bool fAlreadyHave = AlreadyHave(inv);
1546 LogPrint(
"net",
"got inv: %s %s peer=%d\n", inv.
ToString(), fAlreadyHave ?
"have" :
"new", pfrom->
id);
1549 inv.
type |= nFetchFlags;
1553 UpdateBlockAvailability(pfrom->
GetId(), inv.
hash);
1568 LogPrint(
"net",
"transaction (%s) inv sent in violation of protocol peer=%d\n", inv.
hash.
ToString(), pfrom->
id);
1577 if (!vToFetch.empty())
1584 std::vector<CInv> vInv;
1586 if (vInv.size() > MAX_INV_SZ)
1590 return error(
"message getdata size() = %u", vInv.size());
1593 if (
fDebug || (vInv.size() != 1))
1594 LogPrint(
"net",
"received getdata (%u invsz) peer=%d\n", vInv.size(), pfrom->
id);
1596 if ((
fDebug && vInv.size() > 0) || (vInv.size() == 1))
1597 LogPrint(
"net",
"received getdata for: %s peer=%d\n", vInv[0].ToString(), pfrom->
id);
1608 vRecv >> locator >> hashStop;
1618 std::shared_ptr<const CBlock> a_recent_block;
1620 LOCK(cs_most_recent_block);
1621 a_recent_block = most_recent_block;
1636 LogPrint(
"net",
"getblocks %d to %s limit %d from peer=%d\n", (pindex ? pindex->
nHeight : -1), hashStop.
IsNull() ?
"end" : hashStop.
ToString(), nLimit, pfrom->
id);
1670 std::shared_ptr<const CBlock> recent_block;
1672 LOCK(cs_most_recent_block);
1673 if (most_recent_block_hash == req.
blockhash)
1674 recent_block = most_recent_block;
1678 SendBlockTransactions(*recent_block, req, pfrom, connman);
1686 LogPrintf(
"Peer %d sent us a getblocktxn for a block we don't have", pfrom->
id);
1698 LogPrint(
"net",
"Peer %d sent us a getblocktxn for a block > %i deep", pfrom->
id, MAX_BLOCKTXN_DEPTH);
1703 ProcessGetData(pfrom, chainparams.
GetConsensus(it->second->nHeight), connman, interruptMsgProc);
1711 SendBlockTransactions(block, req, pfrom, connman);
1719 vRecv >> locator >> hashStop;
1723 LogPrint(
"net",
"Ignoring getheaders from peer=%d because node is in initial block download\n", pfrom->
id);
1727 CNodeState *nodestate = State(pfrom->
GetId());
1735 pindex = (*mi).second;
1746 std::vector<CBlock> vHeaders;
1747 int nLimit = MAX_HEADERS_RESULTS;
1752 if (--nLimit <= 0 || pindex->GetBlockHash() == hashStop)
1767 nodestate->pindexBestHeaderSent = pindex ? pindex :
chainActive.
Tip();
1778 LogPrint(
"net",
"transaction sent in violation of protocol peer=%d\n", pfrom->
id);
1782 std::deque<COutPoint> vWorkQueue;
1783 std::vector<uint256> vEraseQueue;
1793 bool fMissingInputs =
false;
1799 std::list<CTransactionRef> lRemovedTxn;
1803 RelayTransaction(tx, connman);
1804 for (
unsigned int i = 0; i < tx.
vout.size(); i++) {
1805 vWorkQueue.emplace_back(inv.
hash, i);
1810 LogPrint(
"mempool",
"AcceptToMemoryPool: peer=%d: accepted %s (poolsz %u txn, %u kB)\n",
1816 std::set<NodeId> setMisbehaving;
1817 while (!vWorkQueue.empty()) {
1818 auto itByPrev = mapOrphanTransactionsByPrev.find(vWorkQueue.front());
1819 vWorkQueue.pop_front();
1820 if (itByPrev == mapOrphanTransactionsByPrev.end())
1822 for (
auto mi = itByPrev->second.begin();
1823 mi != itByPrev->second.end();
1829 NodeId fromPeer = (*mi)->second.fromPeer;
1830 bool fMissingInputs2 =
false;
1837 if (setMisbehaving.count(fromPeer))
1841 RelayTransaction(orphanTx, connman);
1842 for (
unsigned int i = 0; i < orphanTx.
vout.size(); i++) {
1843 vWorkQueue.emplace_back(orphanHash, i);
1845 vEraseQueue.push_back(orphanHash);
1847 else if (!fMissingInputs2)
1850 if (stateDummy.
IsInvalid(nDos) && nDos > 0)
1854 setMisbehaving.insert(fromPeer);
1860 vEraseQueue.push_back(orphanHash);
1865 assert(recentRejects);
1866 recentRejects->insert(orphanHash);
1873 BOOST_FOREACH(
uint256 hash, vEraseQueue)
1874 EraseOrphanTx(hash);
1876 else if (fMissingInputs)
1878 bool fRejectedParents =
false;
1879 BOOST_FOREACH(
const CTxIn& txin, tx.
vin) {
1881 fRejectedParents =
true;
1885 if (!fRejectedParents) {
1887 BOOST_FOREACH(
const CTxIn& txin, tx.
vin) {
1890 if (!AlreadyHave(_inv)) pfrom->
AskFor(_inv);
1895 unsigned int nMaxOrphanTx = (
unsigned int)std::max((int64_t)0,
GetArg(
"-maxorphantx", DEFAULT_MAX_ORPHAN_TRANSACTIONS));
1898 LogPrint(
"mempool",
"mapOrphan overflow, removed %u tx\n", nEvicted);
1903 recentRejects->insert(tx.
GetHash());
1910 assert(recentRejects);
1911 recentRejects->insert(tx.
GetHash());
1912 if (RecursiveDynamicUsage(*ptx) < 100000) {
1915 }
else if (tx.
HasWitness() && RecursiveDynamicUsage(*ptx) < 100000) {
1929 if (!state.
IsInvalid(nDoS) || nDoS == 0) {
1931 RelayTransaction(tx, connman);
1960 vRecv >> cmpctblock;
1982 LogPrintf(
"Peer %d sent us invalid header via cmpctblock\n", pfrom->
id);
1991 bool fProcessBLOCKTXN =
false;
1996 bool fRevertToHeaderProcessing =
false;
2001 std::shared_ptr<CBlock> pblock = std::make_shared<CBlock>();
2002 bool fBlockReconstructed =
false;
2010 std::map<uint256, std::pair<NodeId, std::list<QueuedBlock>::iterator> >::iterator blockInFlightIt = mapBlocksInFlight.find(pindex->
GetBlockHash());
2011 bool fAlreadyInFlight = blockInFlightIt != mapBlocksInFlight.end();
2018 if (fAlreadyInFlight) {
2021 std::vector<CInv> vInv(1);
2029 if (!fAlreadyInFlight && !CanDirectFetch(chainparams.GetConsensus(pindex->
pprev->
nHeight)))
2032 CNodeState *nodestate = State(pfrom->
GetId());
2043 if ((!fAlreadyInFlight && nodestate->nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER) ||
2044 (fAlreadyInFlight && blockInFlightIt->second.first == pfrom->
GetId())) {
2045 std::list<QueuedBlock>::iterator* queuedBlockIt = NULL;
2046 if (!MarkBlockAsInFlight(pfrom->
GetId(), pindex->
GetBlockHash(), chainparams.GetConsensus(pindex->
nHeight), pindex, &queuedBlockIt)) {
2047 if (!(*queuedBlockIt)->partialBlock)
2051 LogPrint(
"net",
"Peer sent us compact block we were already syncing!\n");
2061 LogPrintf(
"Peer %d sent us invalid compact block\n", pfrom->
id);
2065 std::vector<CInv> vInv(1);
2072 for (
size_t i = 0; i < cmpctblock.
BlockTxCount(); i++) {
2081 fProcessBLOCKTXN =
true;
2093 ReadStatus status = tempBlock.InitData(cmpctblock, vExtraTxnForCompact);
2098 std::vector<CTransactionRef> dummy;
2099 status = tempBlock.FillBlock(*pblock, dummy);
2101 fBlockReconstructed =
true;
2105 if (fAlreadyInFlight) {
2108 std::vector<CInv> vInv(1);
2115 std::vector<CBlock> headers;
2116 headers.push_back(cmpctblock.
header);
2117 vHeadersMsg << headers;
2118 fRevertToHeaderProcessing =
true;
2123 if (fProcessBLOCKTXN)
2124 return ProcessMessage(pfrom,
NetMsgType::BLOCKTXN, blockTxnMsg, nTimeReceived, chainparams, connman, interruptMsgProc);
2126 if (fRevertToHeaderProcessing)
2127 return ProcessMessage(pfrom,
NetMsgType::HEADERS, vHeadersMsg, nTimeReceived, chainparams, connman, interruptMsgProc);
2129 if (fBlockReconstructed) {
2134 mapBlockSource.emplace(pblock->GetHash(), std::make_pair(pfrom->
GetId(),
false));
2136 bool fNewBlock =
false;
2147 MarkBlockAsReceived(pblock->GetHash());
2158 std::shared_ptr<CBlock> pblock = std::make_shared<CBlock>();
2159 bool fBlockRead =
false;
2163 std::map<uint256, std::pair<NodeId, std::list<QueuedBlock>::iterator> >::iterator it = mapBlocksInFlight.find(resp.
blockhash);
2164 if (it == mapBlocksInFlight.end() || !it->second.second->partialBlock ||
2165 it->second.first != pfrom->
GetId()) {
2166 LogPrint(
"net",
"Peer %d sent us block transactions for block we weren't expecting\n", pfrom->
id);
2175 LogPrintf(
"Peer %d sent us invalid compact block/non-matching block transactions\n", pfrom->
id);
2179 std::vector<CInv> invs;
2207 mapBlockSource.emplace(resp.
blockhash, std::make_pair(pfrom->
GetId(),
false));
2211 bool fNewBlock =
false;
2223 std::vector<CBlockHeader> headers;
2227 if (nCount > MAX_HEADERS_RESULTS) {
2230 return error(
"headers message size = %u", nCount);
2232 headers.resize(nCount);
2233 for (
unsigned int n = 0; n < nCount; n++) {
2234 vRecv >> headers[n];
2246 CNodeState *nodestate = State(pfrom->
GetId());
2257 nodestate->nUnconnectingHeaders++;
2259 LogPrint(
"net",
"received header %s: missing prev block %s, sending getheaders (%d) to end (peer=%d, nUnconnectingHeaders=%d)\n",
2260 headers[0].GetHash().ToString(),
2261 headers[0].hashPrevBlock.ToString(),
2263 pfrom->
id, nodestate->nUnconnectingHeaders);
2267 UpdateBlockAvailability(pfrom->
GetId(), headers.back().GetHash());
2269 if (nodestate->nUnconnectingHeaders % MAX_UNCONNECTING_HEADERS == 0) {
2277 if (!hashLastBlock.
IsNull() && header.hashPrevBlock != hashLastBlock) {
2279 return error(
"non-continuous headers sequence");
2281 hashLastBlock = header.GetHash();
2293 return error(
"invalid header received");
2299 CNodeState *nodestate = State(pfrom->
GetId());
2300 if (nodestate->nUnconnectingHeaders > 0) {
2301 LogPrint(
"net",
"peer=%d: resetting nUnconnectingHeaders (%d -> 0)\n", pfrom->
id, nodestate->nUnconnectingHeaders);
2303 nodestate->nUnconnectingHeaders = 0;
2308 if (nCount == MAX_HEADERS_RESULTS) {
2316 bool fCanDirectFetch = CanDirectFetch(chainparams.GetConsensus(0));
2320 std::vector<const CBlockIndex*> vToFetch;
2323 while (pindexWalk && !
chainActive.
Contains(pindexWalk) && vToFetch.size() <= MAX_BLOCKS_IN_TRANSIT_PER_PEER) {
2325 !mapBlocksInFlight.count(pindexWalk->
GetBlockHash()) &&
2328 vToFetch.push_back(pindexWalk);
2330 pindexWalk = pindexWalk->
pprev;
2337 LogPrint(
"net",
"Large reorg, won't direct fetch to %s (%d)\n",
2341 std::vector<CInv> vGetData;
2343 BOOST_REVERSE_FOREACH(
const CBlockIndex *pindex, vToFetch) {
2344 if (nodestate->nBlocksInFlight >= MAX_BLOCKS_IN_TRANSIT_PER_PEER) {
2351 LogPrint(
"net",
"Requesting block %s from peer=%d\n",
2354 if (vGetData.size() > 1) {
2355 LogPrint(
"net",
"Downloading blocks toward %s (%d) via headers direct fetch\n",
2358 if (vGetData.size() > 0) {
2359 if (nodestate->fSupportsDesiredCmpctVersion && vGetData.size() == 1 && mapBlocksInFlight.size() == 1 && pindexLast->
pprev->
IsValid(
BLOCK_VALID_CHAIN)) {
2372 std::shared_ptr<CBlock> pblock = std::make_shared<CBlock>();
2375 LogPrint(
"net",
"received block %s peer=%d\n", pblock->GetHash().ToString(), pfrom->
id);
2382 const uint256 hash(pblock->GetHash());
2387 forceProcessing |= MarkBlockAsReceived(hash);
2390 mapBlockSource.emplace(hash, std::make_pair(pfrom->
GetId(),
true));
2392 bool fNewBlock =
false;
2407 LogPrint(
"net",
"Ignoring \"getaddr\" from outbound connection. peer=%d\n", pfrom->
id);
2414 LogPrint(
"net",
"Ignoring repeated \"getaddr\". peer=%d\n", pfrom->
id);
2422 BOOST_FOREACH(
const CAddress &addr, vAddr)
2431 LogPrint(
"net",
"mempool request with bloom filters disabled, disconnect peer=%d\n", pfrom->
GetId());
2438 LogPrint(
"net",
"mempool request with bandwidth limit reached, disconnect peer=%d\n", pfrom->
GetId());
2450 if (pfrom->
nVersion > BIP0031_VERSION)
2472 int64_t pingUsecEnd = nTimeReceived;
2475 bool bPingFinished =
false;
2476 std::string sProblem;
2478 if (nAvail >=
sizeof(nonce)) {
2485 bPingFinished =
true;
2487 if (pingUsecTime > 0) {
2493 sProblem =
"Timing mishap";
2497 sProblem =
"Nonce mismatch";
2500 bPingFinished =
true;
2501 sProblem =
"Nonce zero";
2505 sProblem =
"Unsolicited pong without ping";
2509 bPingFinished =
true;
2510 sProblem =
"Short payload";
2513 if (!(sProblem.empty())) {
2514 LogPrint(
"net",
"pong peer=%d: %s, %x expected, %x received, %u bytes\n",
2521 if (bPingFinished) {
2532 if (pfrom->
setKnown.count(alertHash) == 0)
2583 std::vector<unsigned char> vData;
2589 if (vData.size() > MAX_SCRIPT_ELEMENT_SIZE) {
2618 vRecv >> newFeeFilter;
2624 LogPrint(
"net",
"received: feefilter of %s from peer=%d\n",
CFeeRate(newFeeFilter).ToString(), pfrom->
id);
2643 static bool SendRejectsAndCheckIfBanned(
CNode* pnode,
CConnman& connman)
2646 CNodeState &state = *State(pnode->
GetId());
2648 BOOST_FOREACH(
const CBlockReject& reject, state.rejects) {
2651 state.rejects.clear();
2653 if (state.fShouldBan) {
2654 state.fShouldBan =
false;
2684 bool fMoreWork =
false;
2699 std::list<CNetMessage> msgs;
2737 LogPrintf(
"%s(%s, %u bytes): CHECKSUM ERROR expected %s was %s\n", __func__,
2748 fRet = ProcessMessage(pfrom, strCommand, vRecv, msg.
nTime, chainparams, connman, interruptMsgProc);
2749 if (interruptMsgProc)
2754 catch (
const std::ios_base::failure& e)
2757 if (strstr(e.what(),
"end of data"))
2760 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());
2762 else if (strstr(e.what(),
"size too large"))
2765 LogPrintf(
"%s(%s, %u bytes): Exception '%s' caught\n", __func__,
SanitizeString(strCommand), nMessageSize, e.what());
2767 else if (strstr(e.what(),
"non-canonical ReadCompactSize()"))
2770 LogPrintf(
"%s(%s, %u bytes): Exception '%s' caught\n", __func__,
SanitizeString(strCommand), nMessageSize, e.what());
2777 catch (
const std::exception& e) {
2788 SendRejectsAndCheckIfBanned(pfrom, connman);
2802 bool operator()(std::set<uint256>::iterator a, std::set<uint256>::iterator b)
2824 bool pingSend =
false;
2835 while (nonce == 0) {
2840 if (pto->
nVersion > BIP0031_VERSION) {
2854 if (SendRejectsAndCheckIfBanned(pto, connman))
2856 CNodeState &state = *State(pto->
GetId());
2870 std::vector<CAddress> vAddr;
2877 vAddr.push_back(addr);
2879 if (vAddr.size() >= 1000)
2897 bool fFetch = state.fPreferredDownload || (nPreferredDownload == 0 && !pto->
fClient && !pto->
fOneShot);
2901 state.fSyncStarted =
true;
2911 if (pindexStart->
pprev)
2912 pindexStart = pindexStart->
pprev;
2938 std::vector<CBlock> vHeaders;
2939 bool fRevertToInv = ((!state.fPreferHeaders &&
2943 ProcessBlockAvailability(pto->
id);
2945 if (!fRevertToInv) {
2946 bool fFoundStartingHeader =
false;
2956 fRevertToInv =
true;
2959 if (pBestIndex != NULL && pindex->
pprev != pBestIndex) {
2971 fRevertToInv =
true;
2974 pBestIndex = pindex;
2975 if (fFoundStartingHeader) {
2977 vHeaders.push_back(pindex->
GetBlockHeader(consensusParams,
false));
2978 }
else if (PeerHasHeader(&state, pindex)) {
2980 }
else if (pindex->
pprev == NULL || PeerHasHeader(&state, pindex->
pprev)) {
2983 fFoundStartingHeader =
true;
2984 vHeaders.push_back(pindex->
GetBlockHeader(consensusParams,
false));
2988 fRevertToInv =
true;
2993 if (!fRevertToInv && !vHeaders.empty()) {
2994 if (vHeaders.size() == 1 && state.fPreferHeaderAndIDs) {
2997 LogPrint(
"net",
"%s sending header-and-ids %s to peer=%d\n", __func__,
2998 vHeaders.front().GetHash().ToString(), pto->
id);
3000 int nSendFlags = state.fWantsCmpctWitness ? 0 : SERIALIZE_TRANSACTION_NO_WITNESS;
3002 bool fGotBlockFromCache =
false;
3004 LOCK(cs_most_recent_block);
3005 if (most_recent_block_hash == pBestIndex->
GetBlockHash()) {
3006 if (state.fWantsCmpctWitness)
3012 fGotBlockFromCache =
true;
3015 if (!fGotBlockFromCache) {
3022 state.pindexBestHeaderSent = pBestIndex;
3023 }
else if (state.fPreferHeaders) {
3024 if (vHeaders.size() > 1) {
3025 LogPrint(
"net",
"%s: %u headers, range (%s, %s), to peer=%d\n", __func__,
3027 vHeaders.front().GetHash().ToString(),
3028 vHeaders.back().GetHash().ToString(), pto->
id);
3030 LogPrint(
"net",
"%s: sending header %s to peer=%d\n", __func__,
3031 vHeaders.front().GetHash().ToString(), pto->
id);
3034 state.pindexBestHeaderSent = pBestIndex;
3036 fRevertToInv =
true;
3052 LogPrint(
"net",
"Announcing block %s not on main chain (tip=%s)\n",
3057 if (!PeerHasHeader(&state, pindex)) {
3059 LogPrint(
"net",
"%s: sending inv peer=%d hash=%s\n", __func__,
3070 std::vector<CInv> vInv;
3078 if (vInv.size() == MAX_INV_SZ) {
3088 fSendTrickle =
true;
3111 for (
const auto& txinfo : vtxinfo) {
3112 const uint256& hash = txinfo.tx->GetHash();
3116 if (txinfo.feeRate.GetFeePerK() < filterrate)
3123 vInv.push_back(inv);
3124 if (vInv.size() == MAX_INV_SZ) {
3135 std::vector<std::set<uint256>::iterator> vInvTx;
3138 vInvTx.push_back(it);
3148 std::make_heap(vInvTx.begin(), vInvTx.end(), compareInvMempoolOrder);
3151 unsigned int nRelayedTransactions = 0;
3153 while (!vInvTx.empty() && nRelayedTransactions < INVENTORY_BROADCAST_MAX) {
3155 std::pop_heap(vInvTx.begin(), vInvTx.end(), compareInvMempoolOrder);
3156 std::set<uint256>::iterator it = vInvTx.back();
3170 if (filterrate && txinfo.feeRate.GetFeePerK() < filterrate) {
3176 nRelayedTransactions++;
3179 while (!vRelayExpiration.empty() && vRelayExpiration.front().first < nNow)
3181 mapRelay.erase(vRelayExpiration.front().second);
3182 vRelayExpiration.pop_front();
3185 auto ret = mapRelay.insert(std::make_pair(hash, std::move(txinfo.tx)));
3187 vRelayExpiration.push_back(std::make_pair(nNow + 15 * 60 * 1000000, ret.first));
3190 if (vInv.size() == MAX_INV_SZ) {
3203 if (state.nStallingSince && state.nStallingSince < nNow - 1000000 * BLOCK_STALLING_TIMEOUT) {
3207 LogPrintf(
"Peer=%d is stalling block download, disconnecting\n", pto->
id);
3216 if (state.vBlocksInFlight.size() > 0) {
3217 QueuedBlock &queuedBlock = state.vBlocksInFlight.front();
3218 int nOtherPeersWithValidatedDownloads = nPeersWithValidatedDownloads - (state.nBlocksInFlightValidHeaders > 0);
3219 if (nNow > state.nDownloadingSince + consensusParams.
nPowTargetSpacing * (BLOCK_DOWNLOAD_TIMEOUT_BASE + BLOCK_DOWNLOAD_TIMEOUT_PER_PEER * nOtherPeersWithValidatedDownloads)) {
3220 LogPrintf(
"Timeout downloading block %s from peer=%d, disconnecting\n", queuedBlock.hash.ToString(), pto->
id);
3229 std::vector<CInv> vGetData;
3231 std::vector<const CBlockIndex*> vToDownload;
3233 FindNextBlocksToDownload(pto->
GetId(), MAX_BLOCKS_IN_TRANSIT_PER_PEER - state.nBlocksInFlight, vToDownload, staller, consensusParams);
3234 BOOST_FOREACH(
const CBlockIndex *pindex, vToDownload) {
3237 MarkBlockAsInFlight(pto->
GetId(), pindex->
GetBlockHash(), consensusParams, pindex);
3241 if (state.nBlocksInFlight == 0 && staller != -1) {
3242 if (State(staller)->nStallingSince == 0) {
3243 State(staller)->nStallingSince = nNow;
3244 LogPrint(
"net",
"Stall started peer=%d\n", staller);
3255 if (!AlreadyHave(inv))
3259 vGetData.push_back(inv);
3260 if (vGetData.size() >= 1000)
3271 if (!vGetData.empty())
3278 if (pto->
nVersion >= FEEFILTER_VERSION &&
GetBoolArg(
"-feefilter", DEFAULT_FEEFILTER) &&
3283 static CFeeRate default_feerate(DEFAULT_MIN_RELAY_TX_FEE);
3285 CAmount filterToSend = filterRounder.
round(currentFilter);
3287 if (
GetArg(
"-limitfreerelay", DEFAULT_LIMITFREERELAY) <= 0)
3298 (currentFilter < 3 * pto->lastSentFeeFilter / 4 || currentFilter > 4 * pto->
lastSentFeeFilter / 3)) {
3331 mapOrphanTransactions.clear();
3332 mapOrphanTransactionsByPrev.clear();
@ BanReasonNodeMisbehaving
CCriticalSection cs_mapAlerts
map< uint256, CAlert > mapAlerts
bool MoneyRange(const CAmount &nValue)
int64_t CAmount
Amount in satoshis (Can be negative)
enum ReadStatus_t ReadStatus
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...
@ BLOCK_VALID_CHAIN
Outputs do not overspend inputs, no double spends, coinbase output ok, no immature coinbase spends,...
@ BLOCK_VALID_TRANSACTIONS
Only first tx is coinbase, 2 <= coinbase input script length <= 100, transactions valid,...
@ BLOCK_VALID_SCRIPTS
Scripts & signatures ok. Implies all parents are also at least SCRIPTS.
@ BLOCK_VALID_TREE
All parent headers found, difficulty matches, timestamp >= median previous, checkpoint.
@ BLOCK_HAVE_DATA
full block available in blk*.dat
const CChainParams & Params()
Return the currently selected parameters.
std::vector< CTransactionRef > txn
std::vector< uint16_t > indexes
A CService with information about it as peer.
An alert is a combination of a serialized CUnsignedAlert and a signature.
bool AppliesTo(int nVersion, const std::string &strSubVerIn) const
bool ProcessAlert(const std::vector< unsigned char > &alertKey, bool fThread=true)
size_t BlockTxCount() const
std::vector< CTransactionRef > vtx
The block chain is a tree shaped structure starting with the genesis block at the root,...
CBlockIndex * pprev
pointer to the index of the predecessor of this block
arith_uint256 nChainWork
(memory only) Total amount of work (expected number of hashes) in the chain up to and including this ...
CBlockHeader GetBlockHeader(const Consensus::Params &consensusParams, bool fCheckPOW=true) const
uint256 GetBlockHash() const
int64_t GetBlockTime() const
unsigned int nStatus
Verification status of this block. See enum BlockStatus.
unsigned int nTx
Number of transactions in this block.
bool IsValid(enum BlockStatus nUpTo=BLOCK_VALID_TRANSACTIONS) const
Check whether this block index entry is valid up to the passed validity level.
CBlockIndex * GetAncestor(int height)
Efficiently find an ancestor of this block.
int nHeight
height of the entry in the chain. The genesis block has height 0
unsigned int nChainTx
(memory only) Number of transactions in the chain up to and including this block.
BloomFilter is a probabilistic filter which SPV clients provide so that we can filter the transaction...
bool IsWithinSizeConstraints() const
True if the size is <= MAX_BLOOM_FILTER_SIZE and the number of hash functions is <= MAX_HASH_FUNCS (c...
void insert(const std::vector< unsigned char > &vKey)
bool IsRelevantAndUpdate(const CTransaction &tx)
Also adds any outputs which match the filter to the filter (to match their spending txes)
void UpdateEmptyFull()
Checks for empty and full filters to avoid wasting cpu.
CBlockLocator GetLocator(const CBlockIndex *pindex=NULL) const
Return a CBlockLocator that refers to a block in this chain (by default the tip).
CBlockIndex * Next(const CBlockIndex *pindex) const
Find the successor of a block in this chain, or NULL if the given index is not found or is the tip.
CBlockIndex * Tip() const
Returns the index entry for the tip of this chain, or NULL if none.
int Height() const
Return the maximal height in the chain.
bool Contains(const CBlockIndex *pindex) const
Efficiently check whether a block is present in this chain.
CChainParams defines various tweakable parameters of a given instance of the Bitcoin system.
const CMessageHeader::MessageStartChars & MessageStart() const
const Consensus::Params & GetConsensus(uint32_t nTargetHeight) const
bool HaveCoinsInCache(const uint256 &txid) const
Check if we have the given tx already loaded in this cache.
bool ForNode(NodeId id, std::function< bool(CNode *pnode)> func)
unsigned int GetReceiveFloodSize() const
void SetBestHeight(int height)
void ForEachNodeThen(Callable &&pre, CallableAfter &&post)
void SetServices(const CService &addr, ServiceFlags nServices)
size_t GetAddressCount() const
void AddNewAddresses(const std::vector< CAddress > &vAddr, const CAddress &addrFrom, int64_t nTimePenalty=0)
std::vector< CAddress > GetAddresses()
CSipHasher GetDeterministicRandomizer(uint64_t id) const
Get a unique deterministic randomizer.
void MarkAddressGood(const CAddress &addr)
void WakeMessageHandler()
bool OutboundTargetReached(bool historicalBlockServingLimit)
check if the outbound target is reached
void Ban(const CNetAddr &netAddr, const BanReason &reason, int64_t bantimeoffset=0, bool sinceUnixEpoch=false)
bool CheckIncomingNonce(uint64_t nonce)
void PushMessage(CNode *pnode, CSerializedNetMsg &&msg)
void ForEachNode(Callable &&func)
Wrapped boost mutex: supports recursive locking, but no waiting TODO: We should move away from using ...
Double ended buffer combining vector and stream-like interfaces.
Fee rate in satoshis per kilobyte: CAmount / kB.
CAmount GetFeePerK() const
Return the fee in satoshis for a size of 1000 bytes.
std::string ToString() const
Used to relay blocks as header + vector<merkle branch> to filtered nodes.
std::vector< std::pair< unsigned int, uint256 > > vMatchedTxn
Public only for unit testing and relay testing (not relayed)
void SetIP(const CNetAddr &ip)
const uint256 & GetMessageHash() const
void SetVersion(int nVersionIn)
CSerializedNetMsg Make(int nFlags, std::string sCommand, Args &&... args) const
Information about a peer.
CRollingBloomFilter filterInventoryKnown
std::atomic< int > nVersion
void SetSendVersion(int nVersionIn)
std::vector< uint256 > vInventoryBlockToSend
std::atomic_bool fPauseRecv
std::atomic< int64_t > nTimeOffset
CCriticalSection cs_inventory
void PushAddress(const CAddress &_addr, FastRandomContext &insecure_rand)
std::atomic< bool > fPingQueued
int GetSendVersion() const
CCriticalSection cs_feeFilter
void SetAddrLocal(const CService &addrLocalIn)
May not be called more than once.
std::vector< CAlert > vAlertToSend
std::atomic_bool fSuccessfullyConnected
ServiceFlags nServicesExpected
uint64_t GetLocalNonce() const
std::atomic< ServiceFlags > nServices
CRollingBloomFilter addrKnown
std::string GetAddrName() const
int GetMyStartingHeight() const
CCriticalSection cs_filter
std::atomic< int > nStartingHeight
void PushAlert(const CAlert &_alert)
std::atomic_bool fPauseSend
std::multimap< int64_t, CInv > mapAskFor
void PushInventory(const CInv &inv)
CCriticalSection cs_vProcessMsg
int64_t nextSendTimeFeeFilter
std::atomic< int64_t > timeLastMempoolReq
void AddAddressKnown(const CAddress &_addr)
void SetRecvVersion(int nVersionIn)
std::deque< CInv > vRecvGetData
std::atomic< int64_t > nLastTXTime
std::atomic< int64_t > nMinPingUsecTime
std::atomic< uint64_t > nPingNonceSent
std::vector< CAddress > vAddrToSend
std::set< uint256 > setAskFor
CAmount lastSentFeeFilter
std::atomic< int64_t > nPingUsecStart
ServiceFlags GetLocalServices() const
std::set< uint256 > setKnown
std::atomic< int64_t > nPingUsecTime
void AddInventoryKnown(const CInv &inv)
std::list< CNetMessage > vProcessMsg
CCriticalSection cs_SubVer
std::atomic< int64_t > nLastBlockTime
std::vector< uint256 > vBlockHashesToAnnounce
std::atomic_bool fDisconnect
void AskFor(const CInv &inv)
std::set< uint256 > setInventoryTxToSend
int64_t nNextLocalAddrSend
RollingBloomFilter is a probabilistic "keep track of most recently inserted" set.
void insert(const std::vector< unsigned char > &vKey)
bool contains(const std::vector< unsigned char > &vKey) const
A combination of a network address (CNetAddr) and a (TCP) port.
std::string ToString() const
std::vector< unsigned char > GetKey() const
uint64_t Finalize() const
Compute the 64-bit SipHash-2-4 of the data written so far.
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 ...
The basic transaction that is broadcasted on the network and contained in blocks.
const std::vector< CTxOut > vout
const uint256 & GetHash() const
const std::vector< CTxIn > vin
An input of a transaction.
CTxMemPool stores valid-according-to-the-current-best-chain transactions that may be included in the ...
CFeeRate GetMinFee(size_t sizelimit) const
The minimum fee to get into the mempool, which may itself not be enough for larger-sized transactions...
size_t DynamicMemoryUsage() const
std::vector< TxMempoolInfo > infoAll() const
bool CompareDepthAndScore(const uint256 &hasha, const uint256 &hashb)
bool exists(uint256 hash) 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...
TxMempoolInfo info(const uint256 &hash) const
Capture information about block/transaction validation.
unsigned int GetRejectCode() const
std::string GetRejectReason() const
bool CorruptionPossible() const
bool operator()(std::set< uint256 >::iterator a, std::set< uint256 >::iterator b)
CompareInvMempoolOrder(CTxMemPool *_mempool)
CAmount round(CAmount currentMinFee)
Quantize a minimum fee for privacy purpose before broadcast.
ReadStatus InitData(const CBlockHeaderAndShortTxIDs &cmpctblock, const std::vector< std::pair< uint256, CTransactionRef >> &extra_txn)
bool IsTxAvailable(size_t index) const
ReadStatus FillBlock(CBlock &block, const std::vector< CTransactionRef > &vtx_missing)
virtual void BlockChecked(const CBlock &block, const CValidationState &state)
virtual void NewPoWValidBlock(const CBlockIndex *pindex, const std::shared_ptr< const CBlock > &pblock)
PeerLogicValidation(CConnman *connmanIn)
virtual void UpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload)
virtual void SyncTransaction(const CTransaction &tx, const CBlockIndex *pindex, int nPosInBlock)
std::string ToString() const
Bitcoin protocol message types.
const char * FILTERLOAD
The filterload message tells the receiving peer to filter all relayed transactions and requested merk...
const char * BLOCK
The block message transmits a single serialized block.
const char * FILTERCLEAR
The filterclear message tells the receiving peer to remove a previously-set bloom filter.
const char * HEADERS
The headers message sends one or more block headers to a node which previously requested certain head...
const char * SENDHEADERS
Indicates that a node prefers to receive new block announcements via a "headers" message rather than ...
const char * PONG
The pong message replies to a ping message, proving to the pinging node that the ponging node is stil...
const char * SENDCMPCT
Contains a 1-byte bool and 8-byte LE version number.
const char * GETADDR
The getaddr message requests an addr message from the receiving node, preferably one with lots of IP ...
const char * NOTFOUND
The notfound message is a reply to a getdata message which requested an object the receiving node doe...
const char * CMPCTBLOCK
Contains a CBlockHeaderAndShortTxIDs object - providing a header and list of "short txids".
const char * MEMPOOL
The mempool message requests the TXIDs of transactions that the receiving node has verified as valid ...
const char * TX
The tx message transmits a single transaction.
const char * FILTERADD
The filteradd message tells the receiving peer to add a single element to a previously-set bloom filt...
const char * ADDR
The addr (IP address) message relays connection information for peers on the network.
const char * VERSION
The version message provides information about the transmitting node to the receiving node at the beg...
const char * GETBLOCKS
The getblocks message requests an inv message that provides block header hashes starting from a parti...
const char * FEEFILTER
The feefilter message tells the receiving peer not to inv us any txs which do not meet the specified ...
const char * GETHEADERS
The getheaders message requests a headers message that provides block headers starting from a particu...
const char * GETDATA
The getdata message requests one or more data objects from another node.
const char * VERACK
The verack message acknowledges a previously-received version message, informing the connecting node ...
const char * BLOCKTXN
Contains a BlockTransactions.
const char * ALERT
The alert message warns nodes of problems that may affect them or the rest of the network.
const char * PING
The ping message is sent periodically to help confirm that the receiving peer is still connected.
const char * MERKLEBLOCK
The merkleblock message is a reply to a getdata message which requested a block using the inventory t...
const char * REJECT
The reject message informs the receiving node that one of its previous messages has been rejected.
const char * GETBLOCKTXN
Contains a BlockTransactionsRequest Peer should respond with "blocktxn" message.
const char * INV
The inv message (inventory message) transmits one or more inventories of objects known to the transmi...
CAddress GetLocalAddress(const CNetAddr *paddrPeer, ServiceFlags nLocalServices)
bool IsPeerAddrLocalGood(CNode *pnode)
void AdvertiseLocal(CNode *pnode)
limitedmap< uint256, int64_t > mapAlreadyAskedFor(MAX_INV_SZ)
int64_t PoissonNextSend(int64_t nNow, int average_interval_seconds)
Return a timestamp in the future (in microseconds) for exponentially distributed events.
std::string strSubVersion
Subversion as sent to the P2P network in version messages.
bool IsReachable(enum Network net)
check whether a given network is one we can probably connect to
bool SeenLocal(const CService &addr)
vote for a local address
std::atomic< int64_t > nTimeBestReceived(0)
void AddToCompactExtraTransactions(const CTransactionRef &tx)
void Misbehaving(NodeId pnode, int howmuch)
Increase a node's misbehavior score.
void UnregisterNodeSignals(CNodeSignals &nodeSignals)
Unregister a network node.
class CNetProcessingCleanup instance_of_cnetprocessingcleanup
void EraseOrphansFor(NodeId peer) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
unsigned int LimitOrphanTxSize(unsigned int nMaxOrphans) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
std::map< uint256, COrphanTx > mapOrphanTransactions GUARDED_BY(cs_main)
void RegisterNodeSignals(CNodeSignals &nodeSignals)
Register with a network node to receive its signals.
bool ProcessMessages(CNode *pfrom, CConnman &connman, const std::atomic< bool > &interruptMsgProc)
Process protocol messages received from a given node.
bool SendMessages(CNode *pto, CConnman &connman, const std::atomic< bool > &interruptMsgProc)
Send queued protocol messages to be sent to a give node.
bool AddOrphanTx(const CTransactionRef &tx, NodeId peer) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
uint32_t GetFetchFlags(CNode *pfrom, const CBlockIndex *pprev, const Consensus::Params &chainparams)
bool GetNodeStateStats(NodeId nodeid, CNodeStateStats &stats)
Get statistics from node state.
bool IsProxy(const CNetAddr &addr)
const uint32_t MSG_WITNESS_FLAG
getdata message type flags
@ MSG_FILTERED_BLOCK
Defined in BIP37.
@ MSG_CMPCT_BLOCK
Defined in BIP152.
@ MSG_WITNESS_BLOCK
Defined in BIP144.
@ MSG_WITNESS_TX
Defined in BIP144.
ServiceFlags
nServices flags
uint64_t GetRand(uint64_t nMax)
void GetRandBytes(unsigned char *buf, int num)
Functions to gather random data via the OpenSSL PRNG.
#define LIMITED_STRING(obj, n)
uint64_t ReadCompactSize(Stream &is)
Describes a place in the block chain to another node such that if the other node doesn't have the sam...
boost::signals2::signal< void(const uint256 &)> Inventory
Notifies listeners about an inventory item being seen on the network.
static const int SYNC_TRANSACTION_NOT_IN_BLOCK
A posInBlock value for SyncTransaction calls for tranactions not included in connected blocks such as...
boost::signals2::signal< void(int64_t nBestBlockTime, CConnman *connman)> Broadcast
Tells listeners to broadcast their data.
boost::signals2::signal< void(CNode *, CConnman &)> InitializeNode
boost::signals2::signal< bool(CNode *, CConnman &, std::atomic< bool > &), CombinerAll > ProcessMessages
boost::signals2::signal< bool(CNode *, CConnman &, std::atomic< bool > &), CombinerAll > SendMessages
boost::signals2::signal< void(NodeId, bool &)> FinalizeNode
std::vector< int > vHeightInFlight
Parameters that influence chain consensus.
int64_t nPowTargetSpacing
bool operator()(const I &a, const I &b)
#define TRY_LOCK(cs, name)
#define AssertLockHeld(cs)
#define EXCLUSIVE_LOCKS_REQUIRED(...)
int64_t GetAdjustedTime()
void AddTimeData(const CNetAddr &ip, int64_t nOffsetSample)
int64_t GetTransactionWeight(const CTransaction &tx)
Compute the weight of a transaction, as defined by BIP 141.
std::shared_ptr< const CTransaction > CTransactionRef
std::string GetArg(const std::string &strArg, const std::string &strDefault)
Return string argument or default value.
bool GetBoolArg(const std::string &strArg, bool fDefault)
Return boolean argument or default value.
void PrintExceptionContinue(const std::exception *pex, const char *pszThread)
bool IsArgSet(const std::string &strArg)
Return true if the given argument has been manually set.
#define LogPrint(category,...)
bool error(const char *fmt, const Args &... args)
string SanitizeString(const string &str, int rule)
std::string itostr(int n)
#define PAIRTYPE(t1, t2)
This is needed because the foreach macro can't get over the comma in pair<t1, t2>
std::string HexStr(const T itbegin, const T itend, bool fSpaces=false)
int64_t GetTime()
GetTimeMicros() and GetTimeMillis() both return the system time, but in different units.
CCoinsViewCache * pcoinsTip
Global variable that points to the active CCoinsView (protected by cs_main)
CCriticalSection cs_main
Global state.
bool ProcessNewBlock(const CChainParams &chainparams, const std::shared_ptr< const CBlock > pblock, bool fForceProcessing, bool *fNewBlock)
Process an incoming block.
bool ProcessNewBlockHeaders(const std::vector< CBlockHeader > &headers, CValidationState &state, const CChainParams &chainparams, const CBlockIndex **ppindex)
Process incoming block headers.
CTxMemPool mempool(::minRelayTxFee)
CFeeRate minRelayTxFee
A fee rate smaller than this is considered zero fee (for relaying, mining and transaction creation)
bool IsInitialBlockDownload()
Check whether we are doing an initial block download (synchronizing from disk or network)
bool AcceptToMemoryPool(CTxMemPool &pool, CValidationState &state, const CTransactionRef &tx, bool fLimitFree, bool *pfMissingInputs, std::list< CTransactionRef > *plTxnReplaced, bool fOverrideMempoolLimit, const CAmount nAbsurdFee)
(try to) add transaction to memory pool plTxnReplaced will be appended to with all transactions repla...
std::string FormatStateMessage(const CValidationState &state)
Convert CValidationState to a human-readable message for logging.
bool ActivateBestChain(CValidationState &state, const CChainParams &chainparams, std::shared_ptr< const CBlock > pblock)
Make the best chain active, in multiple steps.
bool fPruneMode
True if we're running in -prune mode.
bool ReadBlockFromDisk(CBlock &block, const CDiskBlockPos &pos, const Consensus::Params &consensusParams, bool fCheckPOW)
bool IsWitnessEnabled(const CBlockIndex *pindexPrev, const Consensus::Params ¶ms)
Check whether witness commitments are required for block.
CBlockIndex * pindexBestHeader
Best header we've seen so far (used for getheaders queries' starting points).
CChain chainActive
The currently-connected chain of blocks (protected by cs_main).
CBlockIndex * FindForkInGlobalIndex(const CChain &chain, const CBlockLocator &locator)
Find the last common block between the parameter chain and a locator.
std::atomic_bool fImporting
CMainSignals & GetMainSignals()