35 using namespace std::chrono_literals;
38 static const uint64_t RANDOMIZER_ID_ADDRESS_RELAY = 0x3cac0035b5866b90ULL;
41 static constexpr
size_t MAX_PCT_ADDR_TO_SEND = 23;
76 std::map<uint256, NodeId> mapBlockSource;
98 std::unique_ptr<CRollingBloomFilter> recentRejects;
99 uint256 hashRecentRejectsChainTip;
106 int nValidatedQueuedBefore;
107 bool fValidatedHeaders;
109 std::map<uint256, std::pair<NodeId, std::list<QueuedBlock>::iterator> > mapBlocksInFlight;
112 int nQueuedValidatedHeaders = 0;
115 int nPreferredDownload = 0;
129 maxSize =
gArgs.
GetArg(
"-blockspamfiltermaxsize", DEFAULT_BLOCK_SPAM_FILTER_MAX_SIZE);
130 maxAvg =
gArgs.
GetArg(
"-blockspamfiltermaxavg", DEFAULT_BLOCK_SPAM_FILTER_MAX_AVG);
133 bool onBlockReceived(
int nHeight) {
134 if(nHeight > 0 && maxSize && maxAvg) {
144 size_t size = points.size();
150 for (
auto point : points) {
151 nBlocks += point.second;
155 double nAvgValue = (double)nBlocks / size;
158 bool banNode = (nAvgValue >= 1.5 * maxAvg && size >= maxAvg) ||
159 (nAvgValue >= maxAvg && nBlocks >= maxSize) ||
160 (nBlocks >= maxSize * 3);
164 return state.
DoS(100,
error(
"block-spam ban node for sending spam"));
171 void addPoint(
int height)
174 if(points.size() == maxSize)
176 points.erase(points.begin());
181 auto mi = points.find(height);
182 if (mi != points.end())
183 occurrence = (*mi).second;
185 points[height] = occurrence;
189 std::map<int,int> points;
206 bool fCurrentlyConnected;
212 const std::string
name;
222 int64_t nStallingSince;
223 std::list<QueuedBlock> vBlocksInFlight;
226 bool fPreferredDownload;
228 uint64_t amt_addr_processed = 0;
230 uint64_t amt_addr_rate_limited = 0;
232 CNodeBlocks nodeBlocks;
234 CNodeState(
CAddress addrIn, std::string addrNameIn) : address(addrIn),
name(addrNameIn) {
235 fCurrentlyConnected =
false;
238 pindexBestKnownBlock =
nullptr;
239 hashLastUnknownBlock.
SetNull();
240 pindexLastCommonBlock =
nullptr;
241 fSyncStarted =
false;
244 fPreferredDownload =
false;
249 std::map<NodeId, CNodeState> mapNodeState;
252 CNodeState* State(
NodeId pnode)
254 std::map<NodeId, CNodeState>::iterator it = mapNodeState.find(pnode);
255 if (it == mapNodeState.end())
260 void UpdatePreferredDownload(
CNode* node, CNodeState* state)
262 nPreferredDownload -= state->fPreferredDownload;
267 nPreferredDownload += state->fPreferredDownload;
270 void PushNodeVersion(
CNode* pnode,
CConnman* connman, int64_t nTime)
293 connman->
PushMessage(pnode, std::move(version_msg));
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);
302 void MarkBlockAsReceived(
const uint256& hash)
304 std::map<uint256, std::pair<NodeId, std::list<QueuedBlock>::iterator> >::iterator itInFlight = mapBlocksInFlight.find(hash);
305 if (itInFlight != mapBlocksInFlight.end()) {
306 CNodeState* state = State(itInFlight->second.first);
307 assert(state !=
nullptr);
308 nQueuedValidatedHeaders -= itInFlight->second.second->fValidatedHeaders;
309 state->vBlocksInFlight.erase(itInFlight->second.second);
310 state->nBlocksInFlight--;
311 state->nStallingSince = 0;
312 mapBlocksInFlight.erase(itInFlight);
319 CNodeState* state = State(nodeid);
320 assert(state !=
nullptr);
323 MarkBlockAsReceived(hash);
325 QueuedBlock newentry = {hash, pindex,
GetTimeMicros(), nQueuedValidatedHeaders, pindex !=
nullptr};
326 nQueuedValidatedHeaders += newentry.fValidatedHeaders;
327 std::list<QueuedBlock>::iterator it = state->vBlocksInFlight.insert(state->vBlocksInFlight.end(), newentry);
328 state->nBlocksInFlight++;
329 mapBlocksInFlight[hash] = std::make_pair(nodeid, it);
337 CNodeState* state = State(nodeid);
338 assert(state !=
nullptr);
340 if (!state->hashLastUnknownBlock.IsNull()) {
343 if (!state->pindexBestKnownBlock || pindex->
nChainWork >= state->pindexBestKnownBlock->nChainWork)
344 state->pindexBestKnownBlock = pindex;
345 state->hashLastUnknownBlock.SetNull();
355 CNodeState* state = State(nodeid);
356 assert(state !=
nullptr);
358 ProcessBlockAvailability(nodeid);
363 if (!state->pindexBestKnownBlock || pindex->
nChainWork >= state->pindexBestKnownBlock->nChainWork)
364 state->pindexBestKnownBlock = pindex;
367 state->hashLastUnknownBlock = hash;
380 vBlocks.reserve(vBlocks.size() + count);
381 CNodeState* state = State(nodeid);
382 assert(state !=
nullptr);
385 ProcessBlockAvailability(nodeid);
392 if (!state->pindexLastCommonBlock) {
400 state->pindexLastCommonBlock =
LastCommonAncestor(state->pindexLastCommonBlock, state->pindexBestKnownBlock);
401 if (state->pindexLastCommonBlock == state->pindexBestKnownBlock)
404 std::vector<const CBlockIndex*> vToFetch;
405 const CBlockIndex* pindexWalk = state->pindexLastCommonBlock;
409 int nWindowEnd = state->pindexLastCommonBlock->
nHeight + BLOCK_DOWNLOAD_WINDOW;
410 int nMaxHeight = std::min<int>(state->pindexBestKnownBlock->nHeight, nWindowEnd + 1);
412 while (pindexWalk->
nHeight < nMaxHeight) {
416 int nToFetch = std::min(nMaxHeight - pindexWalk->
nHeight, std::max<int>(count - vBlocks.size(), 128));
417 vToFetch.resize(nToFetch);
418 pindexWalk = state->pindexBestKnownBlock->
GetAncestor(pindexWalk->
nHeight + nToFetch);
419 vToFetch[nToFetch - 1] = pindexWalk;
420 for (
unsigned int i = nToFetch - 1; i > 0; i--) {
421 vToFetch[i - 1] = vToFetch[i]->
pprev;
434 state->pindexLastCommonBlock = pindex;
435 }
else if (mapBlocksInFlight.count(pindex->
GetBlockHash()) == 0) {
437 if (pindex->
nHeight > nWindowEnd) {
439 if (vBlocks.size() == 0 && waitingfor != nodeid) {
441 nodeStaller = waitingfor;
445 vBlocks.push_back(pindex);
446 if (vBlocks.size() == count) {
449 }
else if (waitingfor == -1) {
451 waitingfor = mapBlocksInFlight[pindex->
GetBlockHash()].first;
465 mapNodeState.emplace_hint(mapNodeState.end(), std::piecewise_construct, std::forward_as_tuple(nodeid), std::forward_as_tuple(addr, std::move(addrName)));
468 PushNodeVersion(pnode, connman,
GetTime());
473 fUpdateConnectionTime =
false;
475 CNodeState* state = State(nodeid);
477 if (state->fSyncStarted)
480 if (state->nMisbehavior == 0 && state->fCurrentlyConnected) {
481 fUpdateConnectionTime =
true;
484 for (
const QueuedBlock& entry : state->vBlocksInFlight)
485 mapBlocksInFlight.erase(entry.hash);
487 nPreferredDownload -= state->fPreferredDownload;
489 mapNodeState.erase(nodeid);
496 CNodeState* state = State(nodeid);
500 stats.
nSyncHeight = state->pindexBestKnownBlock ? state->pindexBestKnownBlock->nHeight : -1;
501 stats.
nCommonHeight = state->pindexLastCommonBlock ? state->pindexLastCommonBlock->nHeight : -1;
502 for (
const QueuedBlock& queue : state->vBlocksInFlight) {
520 if (mapOrphanTransactions.count(hash))
531 unsigned int nMaxSize = tx->
IsShieldedTx() ? MAX_TX_SIZE_AFTER_SAPLING : MAX_STANDARD_TX_SIZE;
532 if (sz >= nMaxSize) {
537 auto ret = mapOrphanTransactions.emplace(hash,
COrphanTx{tx, peer,
GetTime() + ORPHAN_TX_EXPIRE_TIME, g_orphan_list.size()});
539 g_orphan_list.emplace_back(ret.first);
541 mapOrphanTransactionsByPrev[txin.
prevout].insert(ret.first);
545 mapOrphanTransactions.size(), mapOrphanTransactionsByPrev.size());
551 std::map<uint256, COrphanTx>::iterator it = mapOrphanTransactions.find(hash);
552 if (it == mapOrphanTransactions.end())
554 for (
const CTxIn& txin : it->second.tx->vin) {
555 auto itPrev = mapOrphanTransactionsByPrev.find(txin.
prevout);
556 if (itPrev == mapOrphanTransactionsByPrev.end())
558 itPrev->second.erase(it);
559 if (itPrev->second.empty())
560 mapOrphanTransactionsByPrev.erase(itPrev);
563 size_t old_pos = it->second.list_pos;
564 assert(g_orphan_list[old_pos] == it);
565 if (old_pos + 1 != g_orphan_list.size()) {
568 auto it_last = g_orphan_list.back();
569 g_orphan_list[old_pos] = it_last;
570 it_last->second.list_pos = old_pos;
572 g_orphan_list.pop_back();
574 mapOrphanTransactions.erase(it);
582 std::map<uint256, COrphanTx>::iterator iter = mapOrphanTransactions.begin();
583 while (iter != mapOrphanTransactions.end()) {
584 std::map<uint256, COrphanTx>::iterator maybeErase = iter++;
585 if (maybeErase->second.fromPeer == peer) {
586 nErased += EraseOrphanTx(maybeErase->second.tx->GetHash());
597 unsigned int nEvicted = 0;
598 static int64_t nNextSweep;
600 if (nNextSweep <= nNow) {
603 int64_t nMinExpTime = nNow + ORPHAN_TX_EXPIRE_TIME - ORPHAN_TX_EXPIRE_INTERVAL;
604 auto iter = mapOrphanTransactions.begin();
605 while (iter != mapOrphanTransactions.end()) {
606 auto maybeErase = iter++;
607 if (maybeErase->second.nTimeExpire <= nNow) {
608 nErased += EraseOrphanTx(maybeErase->second.tx->GetHash());
610 nMinExpTime = std::min(maybeErase->second.nTimeExpire, nMinExpTime);
614 nNextSweep = nMinExpTime + ORPHAN_TX_EXPIRE_INTERVAL;
618 while (mapOrphanTransactions.size() > nMaxOrphans) {
620 size_t randompos = rng.
randrange(g_orphan_list.size());
621 EraseOrphanTx(g_orphan_list[randompos]->first);
633 CNodeState* state = State(pnode);
634 if (state ==
nullptr)
637 state->nMisbehavior += howmuch;
638 int banscore =
gArgs.
GetArg(
"-banscore", DEFAULT_BANSCORE_THRESHOLD);
639 std::string message_prefixed = message.empty() ?
"" : (
": " + message);
640 if (state->nMisbehavior >= banscore && state->nMisbehavior - howmuch < banscore) {
641 LogPrint(
BCLog::NET,
"%s: %s peer=%d (%d -> %d) BAN THRESHOLD EXCEEDED%s\n", __func__, state->name, pnode, state->nMisbehavior-howmuch, state->nMisbehavior, message_prefixed);
642 state->fShouldBan =
true;
644 LogPrint(
BCLog::NET,
"%s: %s peer=%d (%d -> %d)%s\n", __func__, state->name, pnode, state->nMisbehavior-howmuch, state->nMisbehavior, message_prefixed);
651 CNodeState* state = State(pnode);
652 if (state ==
nullptr)
654 if (state->fShouldBan) {
660 static void CheckBlockSpam(
NodeId nodeId,
const uint256& hashBlock)
663 if (!
gArgs.
GetBoolArg(
"-blockspamfilter", DEFAULT_BLOCK_SPAM_FILTER)) {
667 CNodeState* nodestate =
nullptr;
668 int blockReceivedHeight = 0;
671 nodestate = State(nodeId);
672 if (!nodestate) {
return; }
675 if (!pindex) {
return; }
676 blockReceivedHeight = pindex->
nHeight;
679 nodestate->nodeBlocks.onBlockReceived(blockReceivedHeight);
680 bool nodeStatus =
true;
683 nodeStatus = nodestate->nodeBlocks.updateState(state, nodeStatus);
694 LogPrintf(
"Block spam protection: %s\n", hashBlock.
ToString());
715 std::vector<uint256> vOrphanErase;
721 for (
size_t j = 0; j < tx.
vin.size(); j++) {
722 auto itByPrev = mapOrphanTransactionsByPrev.find(tx.
vin[j].prevout);
723 if (itByPrev == mapOrphanTransactionsByPrev.end())
continue;
724 for (
auto mi = itByPrev->second.begin(); mi != itByPrev->second.end(); ++mi) {
727 vOrphanErase.emplace_back(orphanHash);
733 if (!vOrphanErase.empty()) {
735 for (
uint256& orphanHash : vOrphanErase) {
736 nErased += EraseOrphanTx(orphanHash);
744 const int nNewHeight = pindexNew->
nHeight;
747 if (!fInitialDownload) {
756 pnode->PushInventory(CInv(MSG_BLOCK, hashNewTip));
767 std::map<uint256, NodeId>::iterator it = mapBlockSource.find(hash);
771 if (it != mapBlockSource.end() && State(it->second)) {
778 CheckBlockSpam(it->second, block.
GetHash());
782 if (it != mapBlockSource.end())
783 mapBlockSource.erase(it);
795 assert(recentRejects);
802 recentRejects->reset();
807 if (mapOrphanTransactions.count(inv.
hash))
return true;
810 return recentRejects->contains(inv.
hash) ||
887 static void RelayAddress(
const CAddress& addr,
bool fReachable,
CConnman* connman)
890 unsigned int nRelayNodes = fReachable ? 2 : 1;
895 uint64_t hashAddr = addr.
GetHash();
899 std::array<std::pair<uint64_t, CNode*>,2> best{{{0,
nullptr}, {0,
nullptr}}};
901 auto sortfunc = [&best, &hasher, nRelayNodes](
CNode* pnode) {
903 for (
unsigned int i = 0; i < nRelayNodes; i++) {
904 if (hashKey > best[i].first) {
905 std::copy(best.begin() + i, best.begin() + nRelayNodes - 1, best.begin() + i + 1);
906 best[i] = std::make_pair(hashKey, pnode);
912 auto pushfunc = [&addr, &best, nRelayNodes, &insecure_rand] {
913 for (
unsigned int i = 0; i < nRelayNodes && best[i].first != 0; i++) {
914 best[i].second->PushAddress(addr, insecure_rand);
921 bool static PushTierTwoGetDataRequest(
const CInv& inv,
1030 const auto& mnb = it->second;
1032 int version = !mnb.addr.IsAddrV1Compatible() ? PROTOCOL_VERSION | ADDRV2_FORMAT : PROTOCOL_VERSION;
1070 void static ProcessGetBlockData(
CNode* pfrom,
const CInv& inv,
CConnman* connman,
const std::atomic<bool>& interruptMsgProc)
1087 LogPrint(
BCLog::NET,
"ProcessGetData(): ignoring request from peer=%i for old block that isn't in the main chain\n", pfrom->
GetId());
1096 assert(!
"cannot load block from disk");
1118 for (std::pair<unsigned int, uint256>& pair : merkleBlock.
vMatchedTxn)
1130 std::vector<CInv> vInv;
1139 bool static IsTierTwoInventoryTypeKnown(
int type)
1158 void static ProcessGetData(
CNode* pfrom,
CConnman* connman,
const std::atomic<bool>& interruptMsgProc)
1162 std::deque<CInv>::iterator it = pfrom->
vRecvGetData.begin();
1163 std::vector<CInv> vNotFound;
1168 while (it != pfrom->
vRecvGetData.end() && (it->type ==
MSG_TX || IsTierTwoInventoryTypeKnown(it->type))) {
1169 if (interruptMsgProc)
1175 const CInv &inv = *it;
1179 bool pushed =
false;
1193 pushed = PushTierTwoGetDataRequest(inv, pfrom, connman, msgMaker);
1197 vNotFound.push_back(inv);
1205 const CInv &inv = *it;
1208 ProcessGetBlockData(pfrom, inv, connman, interruptMsgProc);
1214 if (!vNotFound.empty()) {
1227 bool static ProcessMessage(
CNode* pfrom, std::string strCommand,
CDataStream& vRecv, int64_t nTimeReceived,
CConnman* connman, std::atomic<bool>& interruptMsgProc)
1231 LogPrintf(
"dropmessagestest DROPPING RECV MESSAGE\n");
1246 uint64_t nNonce = 1;
1247 uint64_t nServiceInt;
1251 std::string strSubVer;
1252 std::string cleanSubVer;
1253 int nStartingHeight = -1;
1255 vRecv >> nVersion >> nServiceInt >> nTime >> addrMe;
1256 nSendVersion = std::min(nVersion, PROTOCOL_VERSION);
1271 if (nVersion == 10300)
1274 vRecv >> addrFrom >> nNonce;
1275 if (!vRecv.
empty()) {
1279 if (!vRecv.
empty()) {
1280 vRecv >> nStartingHeight;
1282 if (!vRecv.
empty()) {
1286 if (!vRecv.
empty()) {
1291 if (fOtherMasternode) {
1292 LogPrint(
BCLog::NET,
"peer=%d is an inbound masternode connection, not relaying anything to it\n", pfrom->
GetId());
1304 LogPrintf(
"connected to self at %s, disconnecting\n", pfrom->
addr.
ToString());
1319 if (nVersion >= 70923) {
1352 UpdatePreferredDownload(pfrom, State(pfrom->
GetId()));
1361 LogPrintf(
"ProcessMessages: advertising address %s\n", addr.
ToString());
1365 LogPrintf(
"ProcessMessages: advertising address %s\n", addr.
ToString());
1379 std::string remoteAddr;
1383 LogPrint(
BCLog::NET,
"receive version message: %s: version %d, blocks=%d, us=%s, peer=%d%s\n",
1388 int64_t nTimeOffset = nTime -
GetTime();
1391 if (
abs64(nTimeOffset) < 2 * nTimeSlotLength) {
1394 LogPrintf(
"timeOffset (%d seconds) too large. Disconnecting node %s\n",
1415 LogPrintf(
"asking peer for sporks\n");
1440 State(pfrom->
GetId())->fCurrentlyConnected =
true;
1449 LogPrintf(
"New outbound peer connected: version: %d, blocks=%d, peer=%d%s\n",
1477 Misbehaving(pfrom->
GetId(), 20,
"sendrecssigs msg is only accepted every 20 minutes");
1496 LogPrint(
BCLog::NET,
"masternode probe connection first received message is not a MNAUTH, disconnecting peer=%d\n", pfrom->
GetId());
1507 stream_version |= ADDRV2_FORMAT;
1511 std::vector<CAddress> vAddr;
1514 if (vAddr.size() > MAX_ADDR_TO_SEND) {
1521 std::vector<CAddress> vAddrOk;
1523 int64_t nSince = nNow - 10 * 60;
1527 const auto current_time = GetTime<std::chrono::microseconds>();
1536 uint64_t num_proc = 0;
1537 uint64_t num_rate_limit = 0;
1541 if (interruptMsgProc)
1552 if ((addr.
nServices & REQUIRED_SERVICES) != REQUIRED_SERVICES)
1555 if (addr.
nTime <= 100000000 || addr.
nTime > nNow + 10 * 60)
1556 addr.
nTime = nNow - 5 * 24 * 60 * 60;
1558 if (connman->
IsBanned(addr))
continue;
1563 RelayAddress(addr, fReachable, connman);
1567 vAddrOk.push_back(addr);
1569 CNodeState* state = State(pfrom->
GetId());
1570 state->amt_addr_processed += num_proc;
1571 state->amt_addr_rate_limited += num_rate_limit;
1572 LogPrint(
BCLog::NET,
"Received addr: %u addresses (%u processed, %u rate-limited) from peer=%d\n",
1573 vAddr.size(), num_proc, num_rate_limit, pfrom->
GetId());
1575 if (vAddr.size() < 1000)
1582 std::vector<CInv> vInv;
1584 if (vInv.size() > MAX_INV_SZ) {
1592 std::vector<CInv> vToFetch;
1594 for (
unsigned int nInv = 0; nInv < vInv.size(); nInv++) {
1595 const CInv& inv = vInv[nInv];
1597 if (interruptMsgProc)
1608 bool fAlreadyHave = AlreadyHave(inv);
1612 UpdateBlockAvailability(pfrom->
GetId(), inv.
hash);
1615 vToFetch.push_back(inv);
1620 static std::set<int> allowWhileInIBDObjs = {
1626 static std::set<int> disallowedRequestsUntilV6 = {
1629 if (disallowedRequestsUntilV6.count(inv.
type) &&
1636 if (!fAlreadyHave) {
1637 bool allowWhileInIBD = allowWhileInIBDObjs.count(inv.
type);
1639 int64_t doubleRequestDelay = 2 * 60 * 1000000;
1643 doubleRequestDelay = 5 * 1000000;
1646 doubleRequestDelay = 5 * 1000000;
1649 pfrom->
AskFor(inv, doubleRequestDelay);
1656 if (!vToFetch.empty())
1662 std::vector<CInv> vInv;
1664 if (vInv.size() > MAX_INV_SZ) {
1670 if (vInv.size() != 1)
1673 if (vInv.size() > 0)
1677 ProcessGetData(pfrom, connman, interruptMsgProc);
1685 LogPrint(
BCLog::NET,
"getblocks, don't relay blocks inv to masternode connection. peer=%d\n", pfrom->
GetId());
1691 vRecv >> locator >> hashStop;
1693 if (locator.
vHave.size() > MAX_LOCATOR_SZ) {
1715 if (--nLimit <= 0) {
1729 vRecv >> locator >> hashStop;
1731 if (locator.
vHave.size() > MAX_LOCATOR_SZ) {
1756 std::vector<CBlock> vHeaders;
1757 int nLimit = MAX_HEADERS_RESULTS;
1758 LogPrintf(
"getheaders %d to %s from peer=%d\n", (pindex ? pindex->
nHeight : -1), hashStop.
ToString(), pfrom->
GetId());
1761 if (--nLimit <= 0 || pindex->GetBlockHash() == hashStop)
1769 std::deque<COutPoint> vWorkQueue;
1770 std::vector<uint256> vEraseQueue;
1779 bool ignoreFees =
false;
1780 bool fMissingInputs =
false;
1786 if (ptx->ContainsZerocoins()) {
1794 RelayTransaction(tx, connman);
1795 for (
unsigned int i = 0; i < tx.
vout.size(); i++) {
1796 vWorkQueue.emplace_back(inv.
hash, i);
1804 std::set<NodeId> setMisbehaving;
1805 while (!vWorkQueue.empty()) {
1806 auto itByPrev = mapOrphanTransactionsByPrev.find(vWorkQueue.front());
1807 vWorkQueue.pop_front();
1808 if(itByPrev == mapOrphanTransactionsByPrev.end())
1810 for (
auto mi = itByPrev->second.begin();
1811 mi != itByPrev->second.end();
1814 const uint256& orphanHash = orphanTx->GetHash();
1815 NodeId fromPeer = (*mi)->second.fromPeer;
1816 bool fMissingInputs2 =
false;
1823 if (setMisbehaving.count(fromPeer))
1827 RelayTransaction(*orphanTx, connman);
1828 for (
unsigned int i = 0; i < orphanTx->vout.size(); i++) {
1829 vWorkQueue.emplace_back(orphanHash, i);
1831 vEraseQueue.push_back(orphanHash);
1832 }
else if (!fMissingInputs2) {
1834 if(stateDummy.
IsInvalid(nDos) && nDos > 0) {
1837 setMisbehaving.insert(fromPeer);
1843 vEraseQueue.push_back(orphanHash);
1844 assert(recentRejects);
1845 recentRejects->insert(orphanHash);
1851 for (
uint256& hash : vEraseQueue) EraseOrphanTx(hash);
1853 }
else if (fMissingInputs) {
1854 bool fRejectedParents =
false;
1858 std::vector<uint256> unique_parents;
1859 unique_parents.reserve(tx.
vin.size());
1860 for (
const CTxIn& txin : ptx->vin) {
1864 std::sort(unique_parents.begin(), unique_parents.end());
1865 unique_parents.erase(std::unique(unique_parents.begin(), unique_parents.end()), unique_parents.end());
1866 for (
const uint256& parent_txid : unique_parents) {
1867 if (recentRejects->contains(parent_txid)) {
1868 fRejectedParents =
true;
1872 if (!fRejectedParents) {
1873 for (
const uint256& parent_txid : unique_parents) {
1876 if (!AlreadyHave(_inv)) pfrom->
AskFor(_inv);
1881 unsigned int nMaxOrphanTx = (
unsigned int)std::max((int64_t)0,
gArgs.
GetArg(
"-maxorphantx", DEFAULT_MAX_ORPHAN_TRANSACTIONS));
1893 assert(recentRejects);
1894 recentRejects->insert(tx.
GetHash());
1904 RelayTransaction(tx, connman);
1921 std::vector<CBlockHeader> headers;
1925 if (nCount > MAX_HEADERS_RESULTS) {
1930 headers.resize(nCount);
1931 for (
unsigned int n = 0; n < nCount; n++) {
1932 vRecv >> headers[n];
1945 if (pindexLast && header.hashPrevBlock != pindexLast->
GetBlockHash()) {
1969 if (nCount == MAX_HEADERS_RESULTS && pindexLast) {
1973 LogPrintf(
"more getheaders (%d) to end to peer=%d (startheight:%d)\n", pindexLast->
nHeight, pfrom->
GetId(), pfrom->
nStartingHeight);
1980 std::shared_ptr<CBlock> pblock = std::make_shared<CBlock>();
1982 const uint256& hashBlock = pblock->GetHash();
2003 MarkBlockAsReceived(hashBlock);
2004 mapBlockSource.emplace(hashBlock, pfrom->
GetId());
2012 LogPrint(
BCLog::NET,
"%s : Already processed block %s, skipping ProcessNewBlock()\n", __func__, pblock->GetHash().GetHex());
2024 std::vector<CAddress> vAddr = connman->
GetAddresses(MAX_ADDR_TO_SEND, MAX_PCT_ADDR_TO_SEND, nullopt);
2026 for (
const CAddress& addr : vAddr) {
2067 int64_t pingUsecEnd = nTimeReceived;
2070 bool bPingFinished =
false;
2071 std::string sProblem;
2073 if (nAvail >=
sizeof(
nonce)) {
2080 bPingFinished =
true;
2082 if (pingUsecTime > 0) {
2088 sProblem =
"Timing mishap";
2092 sProblem =
"Nonce mismatch";
2095 bPingFinished =
true;
2096 sProblem =
"Nonce zero";
2100 sProblem =
"Unsolicited pong without ping";
2104 bPingFinished =
true;
2105 sProblem =
"Short payload";
2108 if (!(sProblem.empty())) {
2117 if (bPingFinished) {
2143 pfrom->
pfilter->UpdateEmptyFull();
2150 std::vector<unsigned char> vData;
2156 if (vData.size() > MAX_SCRIPT_ELEMENT_SIZE) {
2161 pfrom->
pfilter->insert(vData);
2188 if (std::find(allMessages.begin(), allMessages.end(), strCommand) != allMessages.end()) {
2203 if (state_payments.
IsInvalid(dosScore)) {
2216 if (mnauthState.
IsInvalid(dosScore) && dosScore > 0) {
2231 static bool DisconnectIfBanned(
CNode* pnode,
CConnman* connman)
2234 CNodeState &state = *State(pnode->
GetId());
2236 if (state.fShouldBan) {
2237 state.fShouldBan =
false;
2239 LogPrintf(
"Warning: not punishing whitelisted peer %s!\n", pnode->
addr.
ToString());
2241 LogPrintf(
"Warning: not punishing addnoded peer %s!\n", pnode->
addr.
ToString());
2245 LogPrintf(
"Warning: not banning local peer %s!\n", pnode->
addr.
ToString());
2264 bool fMoreWork =
false;
2267 ProcessGetData(pfrom,
connman, interruptMsgProc);
2279 std::list<CNetMessage> msgs;
2316 LogPrint(
BCLog::NET,
"%s(%s, %u bytes): CHECKSUM ERROR expected %s was %s\n", __func__,
2326 fRet = ProcessMessage(pfrom, strCommand, vRecv, msg.
nTime,
connman, interruptMsgProc);
2327 if (interruptMsgProc)
2331 }
catch (
const std::ios_base::failure& e) {
2332 if (strstr(e.what(),
"end of data")) {
2334 LogPrint(
BCLog::NET,
"ProcessMessages(%s, %u bytes): Exception '%s' caught, normally caused by a message being shorter than its stated length\n",
SanitizeString(strCommand), nMessageSize, e.what());
2335 }
else if (strstr(e.what(),
"size too large")) {
2341 }
catch (
const std::exception& e) {
2353 DisconnectIfBanned(pfrom,
connman);
2367 bool operator()(std::set<uint256>::iterator a, std::set<uint256>::iterator b)
2388 bool pingSend =
false;
2399 while (
nonce == 0) {
2412 if (DisconnectIfBanned(pto,
connman)) {
2416 CNodeState& state = *State(pto->
GetId());
2420 auto current_time = GetTime<std::chrono::microseconds>();
2424 pto->m_next_local_addr_send =
PoissonNextSend(current_time, AVG_LOCAL_ADDRESS_BROADCAST_INTERVAL);
2430 if (pto->m_next_addr_send < current_time) {
2431 pto->m_next_addr_send =
PoissonNextSend(current_time, AVG_ADDRESS_BROADCAST_INTERVAL);
2432 std::vector<CAddress> vAddr;
2435 const char* msg_type;
2439 make_flags = ADDRV2_FORMAT;
2448 vAddr.push_back(addr);
2450 if (vAddr.size() >= 1000) {
2464 bool fFetch = state.fPreferredDownload || (nPreferredDownload == 0 && !pto->
fClient && !pto->
fOneShot);
2468 state.fSyncStarted =
true;
2487 std::vector<CInv> vInv;
2488 std::vector<CInv> vInvWait;
2496 if (vInv.size() == MAX_INV_SZ) {
2505 vInv.emplace_back(tInv);
2506 if (vInv.size() == MAX_INV_SZ) {
2516 fSendTrickle =
true;
2534 for (
const auto& txinfo : vtxinfo) {
2535 const uint256& hash = txinfo.tx->GetHash();
2540 if (!pto->
pfilter->IsRelevantAndUpdate(*txinfo.tx))
continue;
2543 vInv.emplace_back(inv);
2544 if (vInv.size() == MAX_INV_SZ) {
2555 std::vector<std::set<uint256>::iterator> vInvTx;
2558 vInvTx.push_back(it);
2563 std::make_heap(vInvTx.begin(), vInvTx.end(), compareInvMempoolOrder);
2566 unsigned int nRelayedTransactions = 0;
2568 while (!vInvTx.empty() && nRelayedTransactions < INVENTORY_BROADCAST_MAX) {
2570 std::pop_heap(vInvTx.begin(), vInvTx.end(), compareInvMempoolOrder);
2571 std::set<uint256>::iterator it = vInvTx.back();
2586 if (pto->
pfilter && !pto->
pfilter->IsRelevantAndUpdate(*txinfo.tx))
continue;
2589 nRelayedTransactions++;
2590 if (vInv.size() == MAX_INV_SZ) {
2602 current_time = GetTime<std::chrono::microseconds>();
2604 if (state.nStallingSince && state.nStallingSince < nNow - 1000000 * BLOCK_STALLING_TIMEOUT) {
2608 LogPrintf(
"Peer=%d is stalling block download, disconnecting\n", pto->
GetId());
2617 if (state.vBlocksInFlight.size() > 0 && state.vBlocksInFlight.front().nTime < nNow - 500000 *
Params().GetConsensus().nTargetSpacing * (4 + state.vBlocksInFlight.front().nValidatedQueuedBefore)) {
2618 LogPrintf(
"Timeout downloading block %s from peer=%d, disconnecting\n", state.vBlocksInFlight.front().hash.ToString(), pto->
GetId());
2626 std::vector<CInv> vGetData;
2627 if (!pto->
fClient && pto->
CanRelay() && fFetch && state.nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER) {
2628 std::vector<const CBlockIndex*> vToDownload;
2630 FindNextBlocksToDownload(pto->
GetId(), MAX_BLOCKS_IN_TRANSIT_PER_PEER - state.nBlocksInFlight, vToDownload, staller);
2637 if (state.nBlocksInFlight == 0 && staller != -1) {
2638 if (State(staller)->nStallingSince == 0) {
2639 State(staller)->nStallingSince = nNow;
2650 if (!AlreadyHave(inv)) {
2652 vGetData.push_back(inv);
2653 if (vGetData.size() >= 1000) {
2663 if (!vGetData.empty())
2675 mapOrphanTransactions.clear();
2676 mapOrphanTransactionsByPrev.clear();
@ BanReasonNodeMisbehaving
CBudgetManager g_budgetman
const CBlockIndex * LastCommonAncestor(const CBlockIndex *pa, const CBlockIndex *pb)
Find the last common ancestor two blocks have.
@ 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.
const CChainParams & Params()
Return the currently selected parameters.
bool IsArgSet(const std::string &strArg) const
Return true if the given argument has been manually set.
std::string GetArg(const std::string &strArg, const std::string &strDefault) const
Return string argument or default value.
bool GetBoolArg(const std::string &strArg, bool fDefault) const
Return boolean argument or default value.
A CService with information about it as peer.
ServiceFlags nServices
Serialized as uint64_t in V1, and as CompactSize in V2.
uint32_t nTime
Always included in serialization, except in the network format on INIT_PROTO_VERSION.
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
CBlockHeader GetBlockHeader() const
arith_uint256 nChainWork
(memory only) Total amount of work (expected number of hashes) in the chain up to and including this ...
uint256 GetBlockHash() const
int64_t GetBlockTime() const
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
uint32_t nStatus
Verification status of this block. See enum BlockStatus.
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...
bool HaveSeenProposalVote(const uint256 &voteHash) const
bool HaveProposal(const uint256 &propHash) const
CDataStream GetProposalVoteSerialized(const uint256 &voteHash) const
bool ProcessMessage(CNode *pfrom, std::string &strCommand, CDataStream &vRecv, int &banScore)
bool HaveFinalizedBudget(const uint256 &budgetHash) const
CDataStream GetProposalSerialized(const uint256 &propHash) const
CDataStream GetFinalizedBudgetSerialized(const uint256 &budgetHash) const
CDataStream GetFinalizedBudgetVoteSerialized(const uint256 &voteHash) const
bool HaveSeenFinalizedBudgetVote(const uint256 &voteHash) const
CBlockIndex * Next(const CBlockIndex *pindex) const
Find the successor of a block in this chain, or nullptr if the given index is not found or is the tip...
CBlockIndex * Tip(bool fProofOfStake=false) const
Returns the index entry for the tip of this chain, or nullptr if none.
CBlockLocator GetLocator(const CBlockIndex *pindex=nullptr) const
Return a CBlockLocator that refers to a block in this chain (by default the tip).
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.
const Consensus::Params & GetConsensus() const
bool AddNewAddresses(const std::vector< CAddress > &vAddr, const CAddress &addrFrom, int64_t nTimePenalty=0)
unsigned int GetReceiveFloodSize() const
void SetBestHeight(int height)
void ForEachNodeThen(Callable &&pre, CallableAfter &&post)
void SetServices(const CService &addr, ServiceFlags nServices)
std::vector< CAddress > GetAddresses(size_t max_addresses, size_t max_pct, Optional< Network > network)
Return all or many randomly selected addresses, optionally by network.
void PushMessage(CNode *pnode, CSerializedNetMsg &&msg, bool allowOptimisticSend=DEFAULT_ALLOW_OPTIMISTIC_SEND)
void MarkAddressGood(const CAddress &addr)
void RelayInv(CInv &inv, int minProtoVersion=ActiveProtocol())
bool IsBanned(CNetAddr ip)
CSipHasher GetDeterministicRandomizer(uint64_t id)
Get a unique deterministic randomizer.
void Ban(const CNetAddr &netAddr, const BanReason &reason, int64_t bantimeoffset=0, bool sinceUnixEpoch=false)
bool CheckIncomingNonce(uint64_t nonce)
void UpdateQuorumRelayMemberIfNeeded(CNode *pnode)
Update the node to be a iqr member if needed.
void ForEachNode(Callable &&func)
std::string ToString() const
static void PushMNAUTH(CNode *pnode, CConnman &connman)
static bool ProcessMessage(CNode *pnode, const std::string &strCommand, CDataStream &vRecv, CConnman &connman, CValidationState &state)
void Broadcast(CConnman *connman)
std::map< uint256, CMasternodeBroadcast > mapSeenMasternodeBroadcast
bool ProcessMessage(CNode *pfrom, std::string &strCommand, CDataStream &vRecv, int &dosScore)
std::map< uint256, CMasternodePing > mapSeenMasternodePing
std::map< uint256, CMasternodePaymentWinner > mapMasternodePayeeVotes
bool ProcessMessageMasternodePayments(CNode *pfrom, std::string &strCommand, CDataStream &vRecv, CValidationState &state)
bool MessageDispatcher(CNode *pfrom, std::string &strCommand, CDataStream &vRecv)
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).
bool IsRelayable() const
Whether this address should be relayed to other peers even if we can't reach it ourselves.
void SetIP(const CNetAddr &ip)
const uint256 & GetMessageHash() const
void SetVersion(int nVersionIn)
CSerializedNetMsg Make(int nFlags, std::string sCommand, Args &&... args)
Information about a peer.
RecursiveMutex cs_vProcessMsg
CRollingBloomFilter filterInventoryKnown
std::atomic< int > nVersion
void SetSendVersion(int nVersionIn)
std::atomic< bool > m_masternode_connection
std::vector< uint256 > vInventoryBlockToSend
std::atomic_bool fPauseRecv
std::atomic< int64_t > nTimeOffset
void PushAddress(const CAddress &_addr, FastRandomContext &insecure_rand)
RecursiveMutex cs_inventory
std::atomic< bool > fPingQueued
int GetSendVersion() const
void SetAddrLocal(const CService &addrLocalIn)
May not be called more than once.
std::atomic_bool fSuccessfullyConnected
ServiceFlags nServicesExpected
bool DisconnectOldProtocol(int nVersionIn, int nVersionRequired)
uint64_t GetLocalNonce() const
std::atomic< ServiceFlags > nServices
CRollingBloomFilter addrKnown
std::string GetAddrName() const
std::atomic< bool > fFirstMessageIsMNAUTH
std::atomic< bool > m_wants_recsigs
std::atomic< int64_t > m_last_wants_recsigs_recv
void AskFor(const CInv &inv, int64_t doubleRequestDelay=2 *60 *1000000)
int GetMyStartingHeight() const
uint256 sentMNAuthChallenge
std::atomic< int > nStartingHeight
std::atomic_bool fPauseSend
std::atomic< bool > fFirstMessageReceived
std::multimap< int64_t, CInv > mapAskFor
std::unique_ptr< CBloomFilter > pfilter
void PushInventory(const CInv &inv)
std::atomic< int64_t > timeLastMempoolReq
void AddAddressKnown(const CAddress &_addr)
void SetRecvVersion(int nVersionIn)
std::deque< CInv > vRecvGetData
uint256 receivedMNAuthChallenge
std::atomic< int64_t > nMinPingUsecTime
std::atomic< uint64_t > nPingNonceSent
std::vector< CAddress > vAddrToSend
std::set< uint256 > setAskFor
std::atomic< int64_t > nPingUsecStart
std::chrono::microseconds nNextInvSend
ServiceFlags GetLocalServices() const
std::atomic< int64_t > nPingUsecTime
std::vector< uint256 > vBlockRequested
void AddInventoryKnown(const CInv &inv)
std::atomic< bool > m_masternode_probe_connection
std::list< CNetMessage > vProcessMsg
std::atomic_bool m_wants_addrv2
Whether the peer has signaled support for receiving ADDRv2 (BIP155) messages, implying a preference t...
std::atomic_bool fDisconnect
double m_addr_token_bucket
Number of addresses that can be processed from this peer.
std::vector< CInv > vInventoryTierTwoToSend
std::set< uint256 > setInventoryTxToSend
std::chrono::microseconds m_addr_token_timestamp
When m_addr_token_bucket was last updated.
An outpoint - a combination of a transaction hash and an index n into its vout.
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 ...
bool ProcessSpork(CNode *pfrom, std::string &strCommand, CDataStream &vRecv, int &dosScore)
bool IsSporkActive(SporkId nSporkID)
The basic transaction that is broadcasted on the network and contained in blocks.
bool IsShieldedTx() const
const uint256 & GetHash() const
unsigned int GetTotalSize() const
std::vector< CTxOut > vout
An input of a transaction.
CTxMemPool stores valid-according-to-the-current-best-chain transactions that may be included in the ...
RecursiveMutex cs
This mutex needs to be locked when accessing mapTx or other members that are guarded by it.
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
unsigned long size() const
Capture information about block/transaction validation.
unsigned int GetRejectCode() const
bool DoS(int level, bool ret=false, unsigned int chRejectCodeIn=0, std::string strRejectReasonIn="", bool corruptionIn=false, const std::string &strDebugMessageIn="")
std::string GetRejectReason() const
bool operator()(std::set< uint256 >::iterator a, std::set< uint256 >::iterator b)
CompareInvMempoolOrder(CTxMemPool *_mempool)
uint64_t randrange(uint64_t range) noexcept
Generate a random integer in the range [0..range).
void BlockConnected(const std::shared_ptr< const CBlock > &pblock, const CBlockIndex *pindex) override
Notifies listeners of a block being connected.
void FinalizeNode(NodeId nodeid, bool &fUpdateConnectionTime) override
void BlockChecked(const CBlock &block, const CValidationState &state) override
bool SendMessages(CNode *pto, std::atomic< bool > &interrupt) override EXCLUSIVE_LOCKS_REQUIRED(pto -> cs_sendProcessing)
Send queued protocol messages to be sent to a give node.
PeerLogicValidation(CConnman *connman)
void InitializeNode(CNode *pnode) override
void UpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload) override
Notifies listeners when the block chain tip advances.
bool ProcessMessages(CNode *pfrom, std::atomic< bool > &interrupt) override
Process protocol messages received from a given node.
A Span is an object that can refer to a contiguous sequence of objects.
void AddedMasternodeList(const uint256 &hash)
void AddedMasternodeWinner(const uint256 &hash)
void AddedBudgetItem(const uint256 &hash)
unsigned int size() const
std::string ToString() const
std::unique_ptr< CDeterministicMNManager > deterministicMNManager
#define LogPrint(category,...)
CMasternodePayments masternodePayments
Object for who's going to get paid on which blocks.
CMasternodeSync masternodeSync
CMasternodeMan mnodeman
Masternode manager.
const char * QFCOMMITMENT
The qfcommit message is used to propagate LLMQ final commitments.
const char * MNBROADCAST2
The mnbroadcast2 message is used to broadcast masternode startup data to connected peers Supporting B...
const char * FILTERLOAD
The filterload message tells the receiving peer to filter all relayed transactions and requested merk...
const char * MNWINNER
The mnwinner message is used to relay and distribute consensus for masternode payout ordering.
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 * ADDRV2
The addrv2 message relays connection information for peers on the network just like the addr message,...
const char * PONG
The pong message replies to a ping message, proving to the pinging node that the ponging node is stil...
const char * QSENDRECSIGS
The qsendrecsigs message is used to propagate LLMQ intra-quorum partial recovered signatures.
const char * GETADDR
The getaddr message requests an addr message from the receiving node, preferably one with lots of IP ...
const char * FINALBUDGETVOTE
The finalbudgetvote message is used to broadcast or relay finalized budget votes to connected peers.
const char * NOTFOUND
The notfound message is a reply to a getdata message which requested an object the receiving node doe...
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 * QPCOMMITMENT
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 * MNBROADCAST
The mnbroadcast message is used to broadcast masternode startup data to connected peers.
const char * FINALBUDGET
The finalbudget message is used to broadcast or relay finalized budget metadata to connected peers.
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 * MNPING
The mnping message is used to ensure a masternode is still active.
const char * QJUSTIFICATION
const char * BUDGETVOTE
The budgetvote message is used to broadcast or relay budget proposal votes to connected peers.
const char * VERACK
The verack message acknowledges a previously-received version message, informing the connecting node ...
const char * BUDGETPROPOSAL
The budgetproposal message is used to broadcast or relay budget proposal metadata to connected peers.
const char * SENDADDRV2
The sendaddrv2 message signals support for receiving ADDRV2 messages (BIP155).
const char * PING
The ping message is sent periodically to help confirm that the receiving peer is still connected.
const char * SPORK
The spork message is used to send spork values to connected peers.
const char * MERKLEBLOCK
The merkleblock message is a reply to a getdata message which requested a block using the inventory t...
const char * GETSPORKS
The getsporks message is used to request spork data from connected peers.
const char * MNAUTH
The mnauth message is used authenticate MN connections.
const char * INV
The inv message (inventory message) transmits one or more inventories of objects known to the transmi...
std::unique_ptr< CQuorumBlockProcessor > quorumBlockProcessor
std::unique_ptr< CDKGSessionManager > quorumDKGSessionManager
std::unique_ptr< CSigningManager > quorumSigningManager
std::unique_ptr< CChainLocksHandler > chainLocksHandler
CAddress GetLocalAddress(const CNetAddr *paddrPeer, ServiceFlags nLocalServices)
bool IsPeerAddrLocalGood(CNode *pnode)
void AdvertiseLocal(CNode *pnode)
limitedmap< CInv, 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.
void CheckOffsetDisconnectedPeers(const CNetAddr &ip)
bool IsReachable(enum Network net)
bool SeenLocal(const CService &addr)
vote for a local address
unsigned int LimitOrphanTxSize(unsigned int nMaxOrphans)
RecursiveMutex g_cs_orphans
void EraseOrphansFor(NodeId peer)
For random eviction.
class CNetProcessingCleanup instance_of_cnetprocessingcleanup
bool AddOrphanTx(const CTransactionRef &tx, NodeId peer) EXCLUSIVE_LOCKS_REQUIRED(g_cs_orphans)
void Misbehaving(NodeId pnode, int howmuch, const std::string &message) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Increase a node's misbehavior score.
bool GetNodeStateStats(NodeId nodeid, CNodeStateStats &stats)
Get statistics from node state.
bool IsBanned(NodeId pnode)
std::map< uint256, COrphanTx > mapOrphanTransactions GUARDED_BY(g_cs_orphans)
double CountSecondsDouble(SecondsDouble t)
Helper to count the seconds in any std::chrono::duration type.
RecursiveMutex cs_main
Global state.
bool IsProxy(const CNetAddr &addr)
const std::vector< std::string > & getTierTwoNetMessageTypes()
@ MSG_QUORUM_JUSTIFICATION
@ MSG_MASTERNODE_ANNOUNCE
@ MSG_BUDGET_FINALIZED_VOTE
@ MSG_QUORUM_PREMATURE_COMMITMENT
@ MSG_QUORUM_RECOVERED_SIG
@ MSG_QUORUM_FINAL_COMMITMENT
ServiceFlags
nServices flags
void GetRandBytes(unsigned char *buf, int num) noexcept
Overall design of the RNG and entropy sources.
uint64_t GetRand(uint64_t nMax) noexcept
void Shuffle(I first, I last, R &&rng)
More efficient than using std::shuffle on a FastRandomContext.
constexpr deserialize_type deserialize
#define LIMITED_STRING(obj, n)
uint64_t ReadCompactSize(Stream &is, bool range_check=true)
Decode a CompactSize-encoded variable-length integer.
std::map< uint256, CSporkMessage > mapSporks
CSporkManager sporkManager
@ SPORK_22_LLMQ_DKG_MAINTENANCE
@ SPORK_15_NEW_PROTOCOL_ENFORCEMENT_2
@ SPORK_14_NEW_PROTOCOL_ENFORCEMENT
@ SPORK_19_COLDSTAKING_MAINTENANCE
@ SPORK_20_SAPLING_MAINTENANCE
Describes a place in the block chain to another node such that if the other node doesn't have the sam...
std::vector< uint256 > vHave
std::vector< int > vHeightInFlight
uint64_t m_addr_rate_limited
uint64_t m_addr_processed
bool operator()(const I &a, const I &b) const
#define AssertLockNotHeld(cs)
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
#define TRY_LOCK(cs, name)
#define AssertLockHeld(cs)
std::atomic< bool > fMasterNode
void PrintExceptionContinue(const std::exception *pex, const char *pszThread)
bool error(const char *fmt, const Args &... args)
#define EXCLUSIVE_LOCKS_REQUIRED(...)
TierTwoSyncState g_tiertwo_sync_state
int64_t GetAdjustedTime()
void AddTimeData(const CNetAddr &ip, int64_t nOffsetSample, int nOffsetLimit)
int64_t abs64(int64_t n)
Functions to keep track of adjusted P2P time.
std::shared_ptr< const CTransaction > CTransactionRef
const uint256 UINT256_ZERO
constant uint256 instances
std::string FormatStateMessage(const CValidationState &state)
Convert CValidationState to a human-readable message for logging.
std::string HexStr(const Span< const uint8_t > s)
Convert a span of bytes to a lower-case hexadecimal string.
std::string SanitizeString(const std::string &str, int rule)
Remove unsafe chars.
int64_t GetTimeMicros()
Returns the system time (not mockable)
int64_t GetTime()
DEPRECATED Use either GetSystemTimeInSeconds (not mockable) or GetTime<T> (mockable)
int ActiveProtocol()
See whether the protocol update is enforced for connected nodes.
std::unique_ptr< CSporkDB > pSporkDB
Global variable that points to the spork database (protected by cs_main)
CTxMemPool mempool(::minRelayTxFee)
bool IsInitialBlockDownload()
Check whether we are doing an initial block download (synchronizing from disk or network)
bool ProcessNewBlock(const std::shared_ptr< const CBlock > &pblock, const FlatFilePos *dbp)
Process an incoming block.
std::unique_ptr< CCoinsViewCache > pcoinsTip
Global variable that points to the active CCoinsView (protected by cs_main)
std::atomic< bool > fImporting
bool AcceptBlockHeader(const CBlock &block, CValidationState &state, CBlockIndex **ppindex, CBlockIndex *pindexPrev)
bool AcceptToMemoryPool(CTxMemPool &pool, CValidationState &state, const CTransactionRef &tx, bool fLimitFree, bool *pfMissingInputs, bool fOverrideMempoolLimit, bool fRejectInsaneFee, bool ignoreFees)
(try to) add transaction to memory pool
bool ReadBlockFromDisk(CBlock &block, const FlatFilePos &pos)
CBlockIndex * pindexBestHeader
Best header we've seen so far (used for getheaders queries' starting points).
std::atomic< bool > fReindex
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.
CBlockIndex * LookupBlockIndex(const uint256 &hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
CMainSignals & GetMainSignals()