41 #include <boost/thread.hpp> 46 # error "Dash Core cannot be compiled without assertions." 69 map<uint256, NodeId> mapBlockSource;
91 boost::scoped_ptr<CRollingBloomFilter> recentRejects;
92 uint256 hashRecentRejectsChainTip;
98 bool fValidatedHeaders;
100 map<uint256, pair<NodeId, list<QueuedBlock>::iterator> > mapBlocksInFlight;
103 int nPreferredDownload = 0;
107 int nPeersWithValidatedDownloads = 0;
117 struct CBlockReject {
118 unsigned char chRejectCode;
119 string strRejectReason;
133 bool fCurrentlyConnected;
139 const std::string
name;
141 std::vector<CBlockReject> rejects;
153 int64_t nHeadersSyncTimeout;
155 int64_t nStallingSince;
156 list<QueuedBlock> vBlocksInFlight;
158 int64_t nDownloadingSince;
160 int nBlocksInFlightValidHeaders;
162 bool fPreferredDownload;
166 CNodeState(
CAddress addrIn, std::string addrNameIn) : address(addrIn),
name(addrNameIn) {
167 fCurrentlyConnected =
false;
170 pindexBestKnownBlock = NULL;
171 hashLastUnknownBlock.
SetNull();
172 pindexLastCommonBlock = NULL;
173 pindexBestHeaderSent = NULL;
174 fSyncStarted =
false;
175 nHeadersSyncTimeout = 0;
177 nDownloadingSince = 0;
179 nBlocksInFlightValidHeaders = 0;
180 fPreferredDownload =
false;
181 fPreferHeaders =
false;
186 map<NodeId, CNodeState> mapNodeState;
189 CNodeState *State(
NodeId pnode) {
190 map<NodeId, CNodeState>::iterator it = mapNodeState.find(pnode);
191 if (it == mapNodeState.end())
196 void UpdatePreferredDownload(
CNode* node, CNodeState* state)
198 nPreferredDownload -= state->fPreferredDownload;
203 nPreferredDownload += state->fPreferredDownload;
206 void PushNodeVersion(
CNode *pnode,
CConnman& connman, int64_t nTime)
221 LogPrint(
"net",
"send version message: version %d, blocks=%d, us=%s, them=%s, peer=%d\n",
PROTOCOL_VERSION, nNodeStartingHeight, addrMe.
ToString(), addrYou.
ToString(), nodeid);
228 std::string addrName = pnode->
addrName;
232 mapNodeState.emplace_hint(mapNodeState.end(), std::piecewise_construct, std::forward_as_tuple(nodeid), std::forward_as_tuple(addr, std::move(addrName)));
235 PushNodeVersion(pnode, connman,
GetTime());
238 void FinalizeNode(
NodeId nodeid,
bool& fUpdateConnectionTime) {
239 fUpdateConnectionTime =
false;
241 CNodeState *state = State(nodeid);
243 if (state->fSyncStarted)
246 if (state->nMisbehavior == 0 && state->fCurrentlyConnected) {
247 fUpdateConnectionTime =
true;
250 BOOST_FOREACH(
const QueuedBlock& entry, state->vBlocksInFlight) {
251 mapBlocksInFlight.erase(entry.hash);
254 nPreferredDownload -= state->fPreferredDownload;
255 nPeersWithValidatedDownloads -= (state->nBlocksInFlightValidHeaders != 0);
256 assert(nPeersWithValidatedDownloads >= 0);
258 mapNodeState.erase(nodeid);
260 if (mapNodeState.empty()) {
262 assert(mapBlocksInFlight.empty());
263 assert(nPreferredDownload == 0);
264 assert(nPeersWithValidatedDownloads == 0);
270 bool MarkBlockAsReceived(
const uint256& hash) {
271 map<uint256, pair<NodeId, list<QueuedBlock>::iterator> >::iterator itInFlight = mapBlocksInFlight.find(hash);
272 if (itInFlight != mapBlocksInFlight.end()) {
273 CNodeState *state = State(itInFlight->second.first);
274 state->nBlocksInFlightValidHeaders -= itInFlight->second.second->fValidatedHeaders;
275 if (state->nBlocksInFlightValidHeaders == 0 && itInFlight->second.second->fValidatedHeaders) {
277 nPeersWithValidatedDownloads--;
279 if (state->vBlocksInFlight.begin() == itInFlight->second.second) {
281 state->nDownloadingSince = std::max(state->nDownloadingSince,
GetTimeMicros());
283 state->vBlocksInFlight.erase(itInFlight->second.second);
284 state->nBlocksInFlight--;
285 state->nStallingSince = 0;
286 mapBlocksInFlight.erase(itInFlight);
294 CNodeState *state = State(nodeid);
295 assert(state != NULL);
298 MarkBlockAsReceived(hash);
300 QueuedBlock newentry = {hash, pindex, pindex != NULL};
301 list<QueuedBlock>::iterator it = state->vBlocksInFlight.insert(state->vBlocksInFlight.end(), newentry);
302 state->nBlocksInFlight++;
303 state->nBlocksInFlightValidHeaders += newentry.fValidatedHeaders;
304 if (state->nBlocksInFlight == 1) {
308 if (state->nBlocksInFlightValidHeaders == 1 && pindex != NULL) {
309 nPeersWithValidatedDownloads++;
311 mapBlocksInFlight[hash] = std::make_pair(nodeid, it);
315 void ProcessBlockAvailability(
NodeId nodeid) {
316 CNodeState *state = State(nodeid);
317 assert(state != NULL);
319 if (!state->hashLastUnknownBlock.IsNull()) {
320 BlockMap::iterator itOld =
mapBlockIndex.find(state->hashLastUnknownBlock);
321 if (itOld !=
mapBlockIndex.end() && itOld->second->nChainWork > 0) {
322 if (state->pindexBestKnownBlock == NULL || itOld->second->nChainWork >= state->pindexBestKnownBlock->nChainWork)
323 state->pindexBestKnownBlock = itOld->second;
324 state->hashLastUnknownBlock.SetNull();
330 void UpdateBlockAvailability(
NodeId nodeid,
const uint256 &hash) {
331 CNodeState *state = State(nodeid);
332 assert(state != NULL);
334 ProcessBlockAvailability(nodeid);
337 if (it !=
mapBlockIndex.end() && it->second->nChainWork > 0) {
339 if (state->pindexBestKnownBlock == NULL || it->second->nChainWork >= state->pindexBestKnownBlock->nChainWork)
340 state->pindexBestKnownBlock = it->second;
343 state->hashLastUnknownBlock = hash;
354 bool PeerHasHeader(CNodeState *state,
CBlockIndex *pindex)
356 if (state->pindexBestKnownBlock && pindex == state->pindexBestKnownBlock->GetAncestor(pindex->
nHeight))
358 if (state->pindexBestHeaderSent && pindex == state->pindexBestHeaderSent->GetAncestor(pindex->
nHeight))
372 while (pa != pb && pa && pb) {
388 vBlocks.reserve(vBlocks.size() +
count);
389 CNodeState *state = State(nodeid);
390 assert(state != NULL);
393 ProcessBlockAvailability(nodeid);
400 if (state->pindexLastCommonBlock == NULL) {
408 state->pindexLastCommonBlock = LastCommonAncestor(state->pindexLastCommonBlock, state->pindexBestKnownBlock);
409 if (state->pindexLastCommonBlock == state->pindexBestKnownBlock)
412 std::vector<CBlockIndex*> vToFetch;
413 CBlockIndex *pindexWalk = state->pindexLastCommonBlock;
418 int nMaxHeight = std::min<int>(state->pindexBestKnownBlock->nHeight, nWindowEnd + 1);
420 while (pindexWalk->
nHeight < nMaxHeight) {
424 int nToFetch = std::min(nMaxHeight - pindexWalk->
nHeight, std::max<int>(
count - vBlocks.size(), 128));
425 vToFetch.resize(nToFetch);
426 pindexWalk = state->pindexBestKnownBlock->GetAncestor(pindexWalk->
nHeight + nToFetch);
427 vToFetch[nToFetch - 1] = pindexWalk;
428 for (
unsigned int i = nToFetch - 1; i > 0; i--) {
429 vToFetch[i - 1] = vToFetch[i]->
pprev;
443 state->pindexLastCommonBlock = pindex;
444 }
else if (mapBlocksInFlight.count(pindex->
GetBlockHash()) == 0) {
446 if (pindex->
nHeight > nWindowEnd) {
448 if (vBlocks.size() == 0 && waitingfor != nodeid) {
450 nodeStaller = waitingfor;
454 vBlocks.push_back(pindex);
455 if (vBlocks.size() ==
count) {
458 }
else if (waitingfor == -1) {
460 waitingfor = mapBlocksInFlight[pindex->
GetBlockHash()].first;
470 CNodeState *state = State(nodeid);
474 stats.
nSyncHeight = state->pindexBestKnownBlock ? state->pindexBestKnownBlock->nHeight : -1;
475 stats.
nCommonHeight = state->pindexLastCommonBlock ? state->pindexLastCommonBlock->nHeight : -1;
476 BOOST_FOREACH(
const QueuedBlock& queue, state->vBlocksInFlight) {
507 if (mapOrphanTransactions.count(hash))
520 LogPrint(
"mempool",
"ignoring large orphan tx (size: %u, hash: %s)\n", sz, hash.
ToString());
524 mapOrphanTransactions[hash].tx = tx;
525 mapOrphanTransactions[hash].fromPeer = peer;
526 BOOST_FOREACH(
const CTxIn& txin, tx.vin)
527 mapOrphanTransactionsByPrev[txin.
prevout.
hash].insert(hash);
529 LogPrint(
"mempool",
"stored orphan tx %s (mapsz %u prevsz %u)\n", hash.
ToString(),
530 mapOrphanTransactions.size(), mapOrphanTransactionsByPrev.size());
536 map<uint256, COrphanTx>::iterator it = mapOrphanTransactions.find(hash);
537 if (it == mapOrphanTransactions.end())
539 BOOST_FOREACH(
const CTxIn& txin, it->second.tx.vin)
541 map<uint256, set<uint256> >::iterator itPrev = mapOrphanTransactionsByPrev.find(txin.
prevout.
hash);
542 if (itPrev == mapOrphanTransactionsByPrev.end())
544 itPrev->second.erase(hash);
545 if (itPrev->second.empty())
546 mapOrphanTransactionsByPrev.erase(itPrev);
548 mapOrphanTransactions.erase(it);
554 map<uint256, COrphanTx>::iterator iter = mapOrphanTransactions.begin();
555 while (iter != mapOrphanTransactions.end())
557 map<uint256, COrphanTx>::iterator maybeErase = iter++;
558 if (maybeErase->second.fromPeer == peer)
564 if (nErased > 0)
LogPrint(
"mempool",
"Erased %d orphan tx from peer %d\n", nErased, peer);
570 unsigned int nEvicted = 0;
571 while (mapOrphanTransactions.size() > nMaxOrphans)
575 map<uint256, COrphanTx>::iterator it = mapOrphanTransactions.lower_bound(randomhash);
576 if (it == mapOrphanTransactions.end())
577 it = mapOrphanTransactions.begin();
590 CNodeState *state = State(pnode);
594 state->nMisbehavior += howmuch;
596 if (state->nMisbehavior >= banscore && state->nMisbehavior - howmuch < banscore)
598 LogPrintf(
"%s: %s (%d -> %d) BAN THRESHOLD EXCEEDED\n", __func__, state->name, state->nMisbehavior-howmuch, state->nMisbehavior);
599 state->fShouldBan =
true;
601 LogPrintf(
"%s: %s (%d -> %d)\n", __func__, state->name, state->nMisbehavior-howmuch, state->nMisbehavior);
622 const int nNewHeight = pindexNew->
nHeight;
625 if (!fInitialDownload) {
627 std::vector<uint256> vHashes;
629 while (pindexToAnnounce != pindexFork) {
631 pindexToAnnounce = pindexToAnnounce->
pprev;
641 BOOST_REVERSE_FOREACH(const uint256& hash, vHashes) {
642 pnode->PushBlockHash(hash);
655 std::map<uint256, NodeId>::iterator it = mapBlockSource.find(hash);
659 if (it != mapBlockSource.end() && State(it->second)) {
662 State(it->second)->rejects.push_back(reject);
667 if (it != mapBlockSource.end())
668 mapBlockSource.erase(it);
683 assert(recentRejects);
691 recentRejects->reset();
694 return recentRejects->contains(inv.hash) ||
696 mapOrphanTransactions.count(inv.hash) ||
754 int nRelayNodes = fReachable ? 2 : 1;
762 uint64_t hashAddr = addr.
GetHash();
765 std::multimap<uint256, CNode*> mapMix;
767 auto sortfunc = [&mapMix, &hashRand](
CNode* pnode) {
769 unsigned int nPointer;
770 memcpy(&nPointer, &pnode,
sizeof(nPointer));
773 mapMix.emplace(hashKey, pnode);
777 auto pushfunc = [&addr, &mapMix, &nRelayNodes] {
778 for (
auto mi = mapMix.begin(); mi != mapMix.end() && nRelayNodes-- > 0; ++mi)
779 mi->second->PushAddress(addr);
787 std::deque<CInv>::iterator it = pfrom->
vRecvGetData.begin();
788 vector<CInv> vNotFound;
797 const CInv &inv = *it;
800 if (interruptMsgProc)
814 static const int nOneMonth = 30 * 24 * 60 * 60;
822 LogPrintf(
"%s: ignoring request from peer=%i for old block that isn't in the main chain\n", __func__, pfrom->
GetId());
828 static const int nOneWeek = 7 * 24 * 60 * 60;
831 LogPrint(
"net",
"historical block serving limit reached, disconnect peer=%d\n", pfrom->
GetId());
843 assert(!
"cannot load block from disk");
859 typedef std::pair<unsigned int, uint256> PairType;
860 BOOST_FOREACH(PairType& pair, merkleBlock.
vMatchedTxn)
888 map<CInv, CDataStream>::iterator mi =
mapRelay.find(inv);
957 BOOST_FOREACH(
uint256& hash, vecVoteHashes) {
1002 LogPrint(
"net",
"ProcessGetData -- MSG_GOVERNANCE_OBJECT: inv = %s\n", inv.
ToString());
1004 bool topush =
false;
1013 LogPrint(
"net",
"ProcessGetData -- MSG_GOVERNANCE_OBJECT: topush = %d, inv = %s\n", topush, inv.
ToString());
1022 bool topush =
false;
1049 vNotFound.push_back(inv);
1062 if (!vNotFound.empty()) {
1083 LogPrintf(
"dropmessagestest DROPPING RECV MESSAGE\n");
1096 }
else if (
GetBoolArg(
"-enforcenodebloom",
false)) {
1123 uint64_t nNonce = 1;
1124 uint64_t nServiceInt;
1128 std::string strSubVer;
1129 int nStartingHeight = -1;
1132 vRecv >> nVersion >> nServiceInt >> nTime >> addrMe;
1141 LogPrint(
"net",
"peer=%d does not offer the expected services (%08x offered, %08x expected); disconnecting\n", pfrom->
id, nServices, pfrom->
nServicesExpected);
1151 LogPrintf(
"peer=%d using obsolete version %i; disconnecting\n", pfrom->
id, nVersion);
1158 if (nVersion == 10300)
1161 vRecv >> addrFrom >> nNonce;
1162 if (!vRecv.
empty()) {
1165 if (!vRecv.
empty()) {
1166 vRecv >> nStartingHeight;
1178 if (pfrom->
fInbound && addrMe.IsRoutable())
1207 UpdatePreferredDownload(pfrom, State(pfrom->
GetId()));
1240 item.second.
RelayTo(pfrom, connman);
1247 LogPrintf(
"receive version message: %s: version %d, blocks=%d, us=%s, peer=%d%s\n",
1274 State(pfrom->
GetId())->fCurrentlyConnected =
true;
1290 vector<CAddress> vAddr;
1296 if (vAddr.size() > 1000)
1300 return error(
"message addr size() = %u", vAddr.size());
1304 vector<CAddress> vAddrOk;
1306 int64_t nSince = nNow - 10 * 60;
1307 BOOST_FOREACH(
CAddress& addr, vAddr)
1309 if (interruptMsgProc)
1315 if (addr.
nTime <= 100000000 || addr.
nTime > nNow + 10 * 60)
1316 addr.
nTime = nNow - 5 * 24 * 60 * 60;
1325 vAddrOk.push_back(addr);
1328 if (vAddr.size() < 1000)
1337 State(pfrom->
GetId())->fPreferHeaders =
true;
1349 return error(
"message inv size() = %u", vInv.size());
1356 fBlocksOnly =
false;
1360 std::vector<CInv> vToFetch;
1363 for (
unsigned int nInv = 0; nInv < vInv.size(); nInv++)
1365 const CInv &inv = vInv[nInv];
1372 if (interruptMsgProc)
1378 LogPrint(
"net",
"got inv: %s %s peer=%d\n", inv.
ToString(), fAlreadyHave ?
"have" :
"new", pfrom->
id);
1381 UpdateBlockAvailability(pfrom->
GetId(), inv.
hash);
1402 CNodeState *nodestate = State(pfrom->
GetId());
1405 vToFetch.push_back(inv);
1417 LogPrint(
"net",
"transaction (%s) inv sent in violation of protocol peer=%d\n", inv.
hash.
ToString(), pfrom->
id);
1426 if (!vToFetch.empty())
1439 return error(
"message getdata size() = %u", vInv.size());
1442 if (
fDebug || (vInv.size() != 1))
1443 LogPrint(
"net",
"received getdata (%u invsz) peer=%d\n", vInv.size(), pfrom->
id);
1445 if ((
fDebug && vInv.size() > 0) || (vInv.size() == 1))
1446 LogPrint(
"net",
"received getdata for: %s peer=%d\n", vInv[0].ToString(), pfrom->
id);
1457 vRecv >> locator >> hashStop;
1468 LogPrint(
"net",
"getblocks %d to %s limit %d from peer=%d\n", (pindex ? pindex->
nHeight : -1), hashStop.IsNull() ?
"end" : hashStop.ToString(), nLimit, pfrom->
id);
1501 vRecv >> locator >> hashStop;
1505 LogPrint(
"net",
"Ignoring getheaders from peer=%d because node is in initial block download\n", pfrom->
id);
1509 CNodeState *nodestate = State(pfrom->
GetId());
1517 pindex = (*mi).second;
1528 vector<CBlock> vHeaders;
1530 LogPrint(
"net",
"getheaders %d to %s from peer=%d\n", (pindex ? pindex->nHeight : -1), hashStop.ToString(), pfrom->
id);
1533 vHeaders.push_back(pindex->GetBlockHeader());
1534 if (--nLimit <= 0 || pindex->
GetBlockHash() == hashStop)
1541 nodestate->pindexBestHeaderSent = pindex ? pindex :
chainActive.
Tip();
1552 LogPrint(
"net",
"transaction sent in violation of protocol peer=%d\n", pfrom->
id);
1556 vector<uint256> vWorkQueue;
1557 vector<uint256> vEraseQueue;
1567 vRecv >> txLockRequest;
1589 LogPrint(
"privatesend",
"DSTX -- Already have %s, skipping...\n", hashTx.
ToString());
1608 LogPrint(
"privatesend",
"DSTX -- CheckSignature() failed for %s\n", hashTx.
ToString());
1619 bool fMissingInputs =
false;
1628 LogPrintf(
"DSTX -- Masternode transaction accepted, txid=%s, peer=%d\n",
1632 LogPrintf(
"TXLOCKREQUEST -- Transaction Lock Request accepted, txid=%s, peer=%d\n",
1639 vWorkQueue.push_back(inv.hash);
1643 LogPrint(
"mempool",
"AcceptToMemoryPool: peer=%d: accepted %s (poolsz %u txn, %u kB)\n",
1649 set<NodeId> setMisbehaving;
1650 for (
unsigned int i = 0; i < vWorkQueue.size(); i++)
1652 map<uint256, set<uint256> >::iterator itByPrev = mapOrphanTransactionsByPrev.find(vWorkQueue[i]);
1653 if (itByPrev == mapOrphanTransactionsByPrev.end())
1655 for (set<uint256>::iterator mi = itByPrev->second.begin();
1656 mi != itByPrev->second.end();
1659 const uint256& orphanHash = *mi;
1660 const CTransaction& orphanTx = mapOrphanTransactions[orphanHash].tx;
1661 NodeId fromPeer = mapOrphanTransactions[orphanHash].fromPeer;
1662 bool fMissingInputs2 =
false;
1669 if (setMisbehaving.count(fromPeer))
1675 vWorkQueue.push_back(orphanHash);
1676 vEraseQueue.push_back(orphanHash);
1678 else if (!fMissingInputs2)
1681 if (stateDummy.
IsInvalid(nDos) && nDos > 0)
1685 setMisbehaving.insert(fromPeer);
1691 vEraseQueue.push_back(orphanHash);
1692 assert(recentRejects);
1693 recentRejects->insert(orphanHash);
1699 BOOST_FOREACH(
uint256 hash, vEraseQueue)
1702 else if (fMissingInputs)
1710 LogPrint(
"mempool",
"mapOrphan overflow, removed %u tx\n", nEvicted);
1712 assert(recentRejects);
1713 recentRejects->insert(tx.
GetHash());
1738 if (!state.
IsInvalid(nDoS) || nDoS == 0) {
1764 std::vector<CBlockHeader> headers;
1771 return error(
"headers message size = %u", nCount);
1773 headers.resize(nCount);
1774 for (
unsigned int n = 0;
n < nCount;
n++) {
1775 vRecv >> headers[
n];
1784 if (!hashLastBlock.
IsNull() && header.hashPrevBlock != hashLastBlock) {
1786 return error(
"non-continuous headers sequence");
1788 hashLastBlock = header.
GetHash();
1800 return error(
"invalid header received");
1822 return error(
"detected bad peer for initial headers sync, disconnecting %d", pfrom->
id);
1831 bool fCanDirectFetch = CanDirectFetch(chainparams.
GetConsensus());
1832 CNodeState *nodestate = State(pfrom->
GetId());
1836 vector<CBlockIndex *> vToFetch;
1841 !mapBlocksInFlight.count(pindexWalk->
GetBlockHash())) {
1843 vToFetch.push_back(pindexWalk);
1845 pindexWalk = pindexWalk->
pprev;
1852 LogPrint(
"net",
"Large reorg, won't direct fetch to %s (%d)\n",
1856 vector<CInv> vGetData;
1858 BOOST_REVERSE_FOREACH(
CBlockIndex *pindex, vToFetch) {
1865 LogPrint(
"net",
"Requesting block %s from peer=%d\n",
1868 if (vGetData.size() > 1) {
1869 LogPrint(
"net",
"Downloading blocks toward %s (%d) via headers direct fetch\n",
1872 if (vGetData.size() > 0) {
1886 LogPrint(
"net",
"received block %s peer=%d\n", inv.hash.ToString(), pfrom->
id);
1895 const uint256 hash(block.GetHash());
1900 forceProcessing |= MarkBlockAsReceived(hash);
1903 mapBlockSource.emplace(hash, pfrom->
GetId());
1905 bool fNewBlock =
false;
1906 ProcessNewBlock(chainparams, &block, forceProcessing, NULL, &fNewBlock);
1920 LogPrint(
"net",
"Ignoring \"getaddr\" from outbound connection. peer=%d\n", pfrom->
id);
1926 BOOST_FOREACH(
const CAddress &addr, vAddr)
1935 LogPrint(
"net",
"mempool request with bandwidth limit reached, disconnect peer=%d\n", pfrom->
GetId());
1941 std::vector<uint256> vtxid;
1944 BOOST_FOREACH(
uint256& hash, vtxid) {
1949 if (!fInMemPool)
continue;
1952 vInv.push_back(inv);
1958 if (vInv.size() > 0)
1987 int64_t pingUsecEnd = nTimeReceived;
1990 bool bPingFinished =
false;
1991 std::string sProblem;
1993 if (nAvail >=
sizeof(nonce)) {
2000 bPingFinished =
true;
2002 if (pingUsecTime > 0) {
2008 sProblem =
"Timing mishap";
2012 sProblem =
"Nonce mismatch";
2015 bPingFinished =
true;
2016 sProblem =
"Nonce zero";
2020 sProblem =
"Unsolicited pong without ping";
2024 bPingFinished =
true;
2025 sProblem =
"Short payload";
2028 if (!(sProblem.empty())) {
2029 LogPrint(
"net",
"pong peer=%d: %s, %x expected, %x received, %u bytes\n",
2036 if (bPingFinished) {
2048 if (pfrom->
setKnown.count(alertHash) == 0)
2050 if (alert.ProcessAlert(chainparams.
AlertKey()))
2056 alert.RelayTo(pnode, connman);
2078 if (!filter.IsWithinSizeConstraints())
2097 vector<unsigned char> vData;
2132 string strMsg;
unsigned char ccode;
string strReason;
2136 ss << strMsg <<
" code " <<
itostr(ccode) <<
": " << strReason;
2142 ss <<
": hash " << hash.
ToString();
2145 }
catch (
const std::ios_base::failure&) {
2147 LogPrint(
"net",
"Unparseable reject message received\n");
2155 BOOST_FOREACH(
const std::string
msg, allMessages) {
2156 if(
msg == strCommand) {
2195 bool fMoreWork =
false;
2210 std::list<CNetMessage> msgs;
2248 LogPrintf(
"%s(%s, %u bytes): CHECKSUM ERROR expected %s was %s\n", __func__,
2259 fRet =
ProcessMessage(pfrom, strCommand, vRecv,
msg.nTime, connman, interruptMsgProc);
2260 if (interruptMsgProc)
2265 catch (
const std::ios_base::failure& e)
2268 if (strstr(e.what(),
"end of data"))
2271 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());
2273 else if (strstr(e.what(),
"size too large"))
2276 LogPrintf(
"%s(%s, %u bytes): Exception '%s' caught\n", __func__,
SanitizeString(strCommand), nMessageSize, e.what());
2283 catch (
const std::exception& e) {
2308 bool pingSend =
false;
2319 while (nonce == 0) {
2350 vector<CAddress> vAddr;
2357 vAddr.push_back(addr);
2359 if (vAddr.size() >= 1000)
2371 CNodeState &state = *State(pto->
GetId());
2372 if (state.fShouldBan) {
2384 state.fShouldBan =
false;
2387 BOOST_FOREACH(
const CBlockReject& reject, state.rejects)
2389 state.rejects.clear();
2394 bool fFetch = state.fPreferredDownload || (nPreferredDownload == 0 && !pto->
fClient && !pto->
fOneShot);
2398 state.fSyncStarted =
true;
2409 if (pindexStart->
pprev)
2410 pindexStart = pindexStart->
pprev;
2447 vector<CBlock> vHeaders;
2450 ProcessBlockAvailability(pto->
id);
2452 if (!fRevertToInv) {
2453 bool fFoundStartingHeader =
false;
2463 fRevertToInv =
true;
2466 if (pBestIndex != NULL && pindex->
pprev != pBestIndex) {
2478 fRevertToInv =
true;
2481 pBestIndex = pindex;
2482 if (fFoundStartingHeader) {
2484 vHeaders.push_back(pindex->GetBlockHeader());
2485 }
else if (PeerHasHeader(&state, pindex)) {
2487 }
else if (pindex->pprev == NULL || PeerHasHeader(&state, pindex->pprev)) {
2490 fFoundStartingHeader =
true;
2491 vHeaders.push_back(pindex->GetBlockHeader());
2495 fRevertToInv =
true;
2514 LogPrint(
"net",
"Announcing block %s not on main chain (tip=%s)\n",
2521 if (!PeerHasHeader(&state, pindex)) {
2523 LogPrint(
"net",
"%s: sending inv peer=%d hash=%s\n", __func__,
2527 }
else if (!vHeaders.empty()) {
2528 if (vHeaders.size() > 1) {
2529 LogPrint(
"net",
"%s: %u headers, range (%s, %s), to peer=%d\n", __func__,
2531 vHeaders.front().GetHash().ToString(),
2532 vHeaders.back().GetHash().ToString(), pto->
id);
2534 LogPrint(
"net",
"%s: sending header %s to peer=%d\n", __func__,
2535 vHeaders.front().GetHash().ToString(), pto->
id);
2538 state.pindexBestHeaderSent = pBestIndex;
2547 vector<CInv> vInvWait;
2551 fSendTrickle =
true;
2575 LogPrint(
"net",
"SendMessages -- queued inv(vInvWait): %s index=%d peer=%d\n", inv.
ToString(), vInvWait.size(), pto->
id);
2576 vInvWait.push_back(inv);
2583 LogPrint(
"net",
"SendMessages -- queued inv: %s index=%d peer=%d\n", inv.
ToString(), vInv.size(), pto->
id);
2584 vInv.push_back(inv);
2585 if (vInv.size() >= 1000)
2587 LogPrint(
"net",
"SendMessages -- pushing inv's: count=%d peer=%d\n", vInv.size(), pto->
id);
2594 if (!vInv.empty()) {
2595 LogPrint(
"net",
"SendMessages -- pushing tailing inv's: count=%d peer=%d\n", vInv.size(), pto->
id);
2605 LogPrintf(
"Peer=%d is stalling block download, disconnecting\n", pto->
id);
2613 if (!pto->
fDisconnect && state.vBlocksInFlight.size() > 0) {
2614 QueuedBlock &queuedBlock = state.vBlocksInFlight.front();
2615 int nOtherPeersWithValidatedDownloads = nPeersWithValidatedDownloads - (state.nBlocksInFlightValidHeaders > 0);
2617 LogPrintf(
"Timeout downloading block %s from peer=%d, disconnecting\n", queuedBlock.hash.ToString(), pto->
id);
2622 if (state.fSyncStarted && state.nHeadersSyncTimeout < std::numeric_limits<int64_t>::max()) {
2625 if (nNow > state.nHeadersSyncTimeout && nSyncStarted == 1 && (nPreferredDownload - state.fPreferredDownload >= 1)) {
2632 LogPrintf(
"Timeout downloading headers from peer=%d, disconnecting\n", pto->
GetId());
2636 LogPrintf(
"Timeout downloading headers from whitelisted peer=%d, not disconnecting\n", pto->
GetId());
2642 state.fSyncStarted =
false;
2644 state.nHeadersSyncTimeout = 0;
2650 state.nHeadersSyncTimeout = std::numeric_limits<int64_t>::max();
2658 vector<CInv> vGetData;
2660 vector<CBlockIndex*> vToDownload;
2665 MarkBlockAsInFlight(pto->
GetId(), pindex->
GetBlockHash(), consensusParams, pindex);
2669 if (state.nBlocksInFlight == 0 && staller != -1) {
2670 if (State(staller)->nStallingSince == 0) {
2671 State(staller)->nStallingSince = nNow;
2672 LogPrint(
"net",
"Stall started peer=%d\n", staller);
2685 LogPrint(
"net",
"SendMessages -- GETDATA -- requesting inv = %s peer=%d\n", inv.
ToString(), pto->
id);
2686 vGetData.push_back(inv);
2687 if (vGetData.size() >= 1000)
2690 LogPrint(
"net",
"SendMessages -- GETDATA -- pushed size = %lu peer=%d\n", vGetData.size(), pto->
id);
2695 LogPrint(
"net",
"SendMessages -- GETDATA -- already have inv = %s peer=%d\n", inv.
ToString(), pto->
id);
2700 if (!vGetData.empty()) {
2702 LogPrint(
"net",
"SendMessages -- GETDATA -- pushed size = %lu peer=%d\n", vGetData.size(), pto->
id);
2715 mapOrphanTransactions.clear();
2716 mapOrphanTransactionsByPrev.clear();
arith_uint256 nChainWork
(memory only) Total amount of work (expected number of hashes) in the chain up to and including this ...
static void EraseOrphanTx(uint256 hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
void ProcessSpork(CNode *pfrom, std::string &strCommand, CDataStream &vRecv, CConnman &connman)
bool GetBlockHash(uint256 &hashRet, int nBlockHeight)
unsigned int LimitOrphanTxSize(unsigned int nMaxOrphans) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
void MarkAddressGood(const CAddress &addr)
int GetMyStartingHeight() const
CMasternodeSync masternodeSync
CRollingBloomFilter addrKnown
CPrivateSendServer privateSendServer
void Ban(const CNetAddr &netAddr, const BanReason &reason, int64_t bantimeoffset=0, bool sinceUnixEpoch=false)
std::set< uint256 > setAskFor
const std::vector< unsigned char > & AlertKey() const
std::vector< CAddress > vAddrToSend
CRollingBloomFilter filterInventoryKnown
boost::signals2::signal< void(NodeId, bool &)> FinalizeNode
std::atomic_bool fPauseSend
void RegisterNodeSignals(CNodeSignals &nodeSignals)
void RelayTransaction(const CTransaction &tx)
static const unsigned int AVG_ADDRESS_BROADCAST_INTERVAL
static const int32_t CURRENT_VERSION
boost::signals2::signal< void(CNode *, CConnman &)> InitializeNode
void PushMessageWithVersion(CNode *pnode, int nVersion, const std::string &sCommand, Args &&... args)
std::vector< uint256 > vBlockHashesFromINV
#define TRY_LOCK(cs, name)
bool IsMnbRecoveryRequested(const uint256 &hash)
std::vector< uint256 > vBlockHashesToAnnounce
void queryHashes(std::vector< uint256 > &vtxid)
std::string GetRejectReason() const
static const unsigned int AVG_LOCAL_ADDRESS_BROADCAST_INTERVAL
const char * MASTERNODEPAYMENTVOTE
boost::signals2::signal< bool(CNode *, CConnman &, std::atomic< bool > &), CombinerAll > SendMessages
std::vector< unsigned char > GetKey() const
bool GetTxLockVote(const uint256 &hash, CTxLockVote &txLockVoteRet)
#define MESSAGE_START_SIZE
static const ServiceFlags REQUIRED_SERVICES
uint64_t ReadCompactSize(Stream &is)
void AcceptLockRequest(const CTxLockRequest &txLockRequest)
static bool AlreadyHave(const CInv &inv) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
bool GetNodeStateStats(NodeId nodeid, CNodeStateStats &stats)
uint64_t GetHash(const uint256 &salt) const
int64_t GetBlockProofEquivalentTime(const CBlockIndex &to, const CBlockIndex &from, const CBlockIndex &tip, const Consensus::Params ¶ms)
bool HaveObjectForHash(uint256 nHash)
static const int64_t BLOCK_DOWNLOAD_TIMEOUT_BASE
void RandAddSeedPerfmon()
static constexpr int64_t HEADERS_DOWNLOAD_TIMEOUT_PER_HEADER
const Consensus::Params & GetConsensus() const
static const CAmount COIN
bool IsValid(enum BlockStatus nUpTo=BLOCK_VALID_TRANSACTIONS) const
Check whether this block index entry is valid up to the passed validity level.
bool Get(const COutPoint &outpoint, CMasternode &masternodeRet)
Versions of Find that are safe to use from outside the class.
static const unsigned int MIN_BLOCKS_TO_KEEP
static const unsigned int MAX_REJECT_MESSAGE_LENGTH
std::atomic_bool fPauseRecv
std::string HexStr(const T itbegin, const T itend, bool fSpaces=false)
static int64_t nTimeOffset
static const int BIP0031_VERSION
BIP 0031, pong message, is enabled for all versions AFTER this one.
int64_t nNextLocalAddrSend
void PrintExceptionContinue(const std::exception *pex, const char *pszThread)
CAddress GetLocalAddress(const CNetAddr *paddrPeer, ServiceFlags nLocalServices)
static const int SENDHEADERS_VERSION
"sendheaders" command and announcing blocks with headers starts with this version ...
std::map< uint256, CMasternodePing > mapSeenMasternodePing
void ProcessMessage(CNode *pfrom, std::string &strCommand, CDataStream &vRecv, CConnman &connman)
bool AcceptToMemoryPool(CTxMemPool &pool, CValidationState &state, const CTransaction &tx, bool fLimitFree, bool *pfMissingInputs, bool fOverrideMempoolLimit, bool fRejectAbsurdFee, bool fDryRun)
static void RelayAddress(const CAddress &addr, bool fReachable, CConnman &connman)
std::vector< int > vHeightInFlight
bool AlreadyHave(const uint256 &hash)
bool SerializeVoteForHash(uint256 nHash, CDataStream &ss)
bool HaveCoins(const uint256 &txid) const
bool SeenLocal(const CService &addr)
std::map< uint256, std::pair< int64_t, CMasternodeBroadcast > > mapSeenMasternodeBroadcast
static bool ProcessMessage(CNode *pfrom, string strCommand, CDataStream &vRecv, int64_t nTimeReceived, CConnman &connman, std::atomic< bool > &interruptMsgProc)
std::string ToString(bool fUseGetnameinfo=true) const
void ProcessMessage(CNode *pfrom, std::string &strCommand, CDataStream &vRecv, CConnman &connman)
size_t GetAddressCount() const
ServiceFlags nServicesExpected
static const unsigned int MAX_SCRIPT_ELEMENT_SIZE
class CNetProcessingCleanup instance_of_cnetprocessingcleanup
void AddNewAddresses(const std::vector< CAddress > &vAddr, const CAddress &addrFrom, int64_t nTimePenalty=0)
void EraseOrphansFor(NodeId peer) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
uint64_t GetLocalNonce() const
CCriticalSection cs_mapMasternodeBlocks
std::list< CNetMessage > vProcessMsg
static const unsigned char REJECT_OBSOLETE
boost::signals2::signal< void(const uint256 &)> Inventory
static void AddDSTX(const CDarksendBroadcastTx &dstx)
bool CheckSignature(const CPubKey &pubKeyMasternode)
static const unsigned int DEFAULT_MAX_ORPHAN_TRANSACTIONS
unsigned int GetReceiveFloodSize() const
boost::signals2::signal< void(int64_t nBestBlockTime, CConnman *connman)> Broadcast
arith_uint256 UintToArith256(const uint256 &a)
void insert(const std::vector< unsigned char > &vKey)
void SetIP(const CNetAddr &ip)
std::vector< CTransaction > vtx
void reserve(size_type n)
bool lookup(uint256 hash, CTransaction &result) const
static const unsigned int REJECT_INTERNAL
bool ProcessNewBlock(const CChainParams &chainparams, const CBlock *pblock, bool fForceProcessing, const CDiskBlockPos *dbp, bool *fNewBlock)
std::atomic_bool fSuccessfullyConnected
bool Contains(const CBlockIndex *pindex) const
std::map< CInv, CDataStream > mapRelay
void RejectLockRequest(const CTxLockRequest &txLockRequest)
std::deque< CInv > vRecvGetData
bool exists(uint256 hash) const
bool ConfirmInventoryRequest(const CInv &inv)
PeerLogicValidation(CConnman *connmanIn)
const char * GetCommand() const
CCoinsViewCache * pcoinsTip
void AddAddressKnown(const CAddress &addr)
static const int64_t BLOCK_DOWNLOAD_TIMEOUT_PER_PEER
virtual void BlockChecked(const CBlock &block, const CValidationState &state)
void UpdateEmptyFull()
Checks for empty and full filters to avoid wasting cpu.
void Misbehaving(NodeId pnode, int howmuch)
static const unsigned int AVG_INVENTORY_BROADCAST_INTERVAL
bool GetBoolArg(const std::string &strArg, bool fDefault)
static const bool DEFAULT_WHITELISTRELAY
void AskFor(const CInv &inv)
void SetRecvVersion(int nVersionIn)
void ForEachNodeThen(const Condition &cond, Callable &&pre, CallableAfter &&post)
bool CheckIncomingNonce(uint64_t nonce)
CMasternodePayments mnpayments
bool DisallowMixing(const COutPoint &outpoint)
static int LogPrint(const char *category, const char *format)
CBlockIndex * pindexBestHeader
const_iterator begin() const
static const int MAX_BLOCKS_IN_TRANSIT_PER_PEER
void UnregisterNodeSignals(CNodeSignals &nodeSignals)
bool IsPeerAddrLocalGood(CNode *pnode)
static const int INIT_PROTO_VERSION
initial proto version, to be increased after version/verack negotiation
size_t DynamicMemoryUsage() const
static const unsigned int MAX_HEADERS_RESULTS
static const unsigned char REJECT_NONSTANDARD
std::vector< uint256 > GetVoteHashes()
static bool error(const char *format)
bool IsProxy(const CNetAddr &addr)
void check(const CCoinsViewCache *pcoins) const
bool IsInitialBlockDownload()
bool OutboundTargetReached(bool historicalBlockServingLimit)
check if the outbound target is reached
void ProcessMessage(CNode *pfrom, std::string &strCommand, CDataStream &vRecv, CConnman &connman)
const std::vector< std::string > & getAllNetMessageTypes()
int64_t nPowTargetSpacing
void PushInventory(const CInv &inv)
void ProcessMessage(CNode *pfrom, std::string &strCommand, CDataStream &vRecv, CConnman &connman)
bool SerializeObjectForHash(uint256 nHash, CDataStream &ss)
std::map< uint256, CMasternodeVerification > mapSeenMasternodeVerification
map< uint256, CAlert > mapAlerts
CMainSignals & GetMainSignals()
void SetBestHeight(int height)
CCriticalSection cs_mapAlerts
uint256 Hash(const T1 pbegin, const T1 pend)
map< uint256, COrphanTx > mapOrphanTransactions GUARDED_BY(cs_main)
std::string ToString() const
ServiceFlags GetLocalServices() const
std::string strSubVersion
void SetServices(const CService &addr, ServiceFlags nServices)
static const unsigned char REJECT_DUPLICATE
const char * MNGOVERNANCEOBJECT
unsigned int GetRejectCode() const
static constexpr int64_t HEADERS_DOWNLOAD_TIMEOUT_BASE
const CMessageHeader::MessageStartChars & MessageStart() const
void ProcessMessage(CNode *pfrom, std::string &strCommand, CDataStream &vRecv)
std::set< uint256 > setKnown
static void ProcessGetData(CNode *pfrom, const Consensus::Params &consensusParams, CConnman &connman, std::atomic< bool > &interruptMsgProc)
CSporkManager sporkManager
std::string ToString() const
CPrivateSendClient privateSendClient
CCriticalSection cs_inventory
std::atomic< int64_t > nLastBlockTime
bool IsReachable(enum Network net)
const char * TXLOCKREQUEST
int64_t PoissonNextSend(int64_t nNow, int average_interval_seconds)
uint256 ArithToUint256(const arith_uint256 &a)
#define EXCLUSIVE_LOCKS_REQUIRED(...)
std::string FormatStateMessage(const CValidationState &state)
const char * MNGOVERNANCEOBJECTVOTE
CCriticalSection cs_mapRelay
uint256 nMinimumChainWork
bool ProcessMessages(CNode *pfrom, CConnman &connman, std::atomic< bool > &interruptMsgProc)
CBlockIndex * Next(const CBlockIndex *pindex) const
const CChainParams & Params()
void * memcpy(void *a, const void *b, size_t c)
void AddInventoryKnown(const CInv &inv)
std::atomic< int64_t > nLastTXTime
static const int MIN_PEER_PROTO_VERSION
disconnect from peers older than this proto version
static const int PROTOCOL_VERSION
const uint256 & GetHash() const
void ProcessMessage(CNode *pfrom, std::string &strCommand, CDataStream &vRecv, CConnman &connman)
bool AddOrphanTx(const CTransaction &tx, NodeId peer) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
bool SendMessages(CNode *pto, CConnman &connman, std::atomic< bool > &interruptMsgProc)
CCriticalSection cs_filter
boost::signals2::signal< bool(CNode *, CConnman &, std::atomic< bool > &), CombinerAll > ProcessMessages
bool ProcessTxLockRequest(const CTxLockRequest &txLockRequest, CConnman &connman)
CBlockIndex * GetAncestor(int height)
Efficiently find an ancestor of this block.
unsigned int nStatus
Verification status of this block. See enum BlockStatus.
CBlockIndex * FindForkInGlobalIndex(const CChain &chain, const CBlockLocator &locator)
int64_t GetAdjustedTime()
uint256 GetBlockHash() const
bool IsRelevantAndUpdate(const CTransaction &tx)
Also adds any outputs which match the filter to the filter (to match their spending txes) ...
virtual void UpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload)
bool ProcessNewBlockHeaders(const std::vector< CBlockHeader > &headers, CValidationState &state, const CChainParams &chainparams, CBlockIndex **ppindex)
#define LIMITED_STRING(obj, n)
static const int CADDR_TIME_VERSION
static const unsigned int MAX_BLOCKS_TO_ANNOUNCE
void PushBlockHashFromINV(const uint256 &hash)
Scripts & signatures ok. Implies all parents are also at least SCRIPTS.
void GetRandBytes(unsigned char *buf, int num)
static const unsigned int MAX_SUBVERSION_LENGTH
CBlockIndex * Tip() const
bool HaveVoteForHash(uint256 nHash)
int64_t nTimeBestReceived
void ProcessMessage(CNode *pfrom, std::string &strCommand, CDataStream &vRecv, CConnman &connman)
static const int PING_INTERVAL
std::multimap< int64_t, CInv > mapAskFor
static const int NO_BLOOM_VERSION
"filter*" commands are disabled without NODE_BLOOM after and including this version ...
int64_t GetBlockTime() const
static const unsigned int DEFAULT_BANSCORE_THRESHOLD
std::string GetArg(const std::string &strArg, const std::string &strDefault)
bool GetTxLockRequest(const uint256 &txHash, CTxLockRequest &txLockRequestRet)
void PrioritiseTransaction(const uint256 hash, const std::string strHash, double dPriorityDelta, const CAmount &nFeeDelta)
CBlockIndex * pprev
pointer to the index of the predecessor of this block
static const unsigned int BLOCK_STALLING_TIMEOUT
int64_t GetTime()
For unit testing.
int64_t DelayGetHeadersTime() const
CGovernanceManager governance
bool ReadBlockFromDisk(CBlock &block, const CDiskBlockPos &pos, const Consensus::Params &consensusParams)
CBlockLocator GetLocator(const CBlockIndex *pindex=NULL) const
static const unsigned char REJECT_MALFORMED
std::map< uint256, CMasternodePaymentVote > mapMasternodePaymentVotes
void AddTimeData(const CNetAddr &ip, int64_t nOffsetSample)
std::vector< CAddress > GetAddresses()
bool RelayTo(CNode *pnode, CConnman &connman) const
int nHeight
height of the entry in the chain. The genesis block has height 0
static const bool DEFAULT_WHITELISTFORCERELAY
std::string ToStringShort() const
static const unsigned int MAX_INV_SZ
limitedmap< uint256, int64_t > mapAlreadyAskedFor(MAX_INV_SZ)
void ForEachNode(const Condition &cond, Callable &&func)
void PushAddress(const CAddress &addr)
std::map< uint256, CSporkMessage > mapSporks
void SetSendVersion(int nVersionIn)
void AdvertiseLocal(CNode *pnode)
static CDarksendBroadcastTx GetDSTX(const uint256 &hash)
void PushMessage(CNode *pnode, const std::string &sCommand, Args &&... args)
std::map< int, CMasternodeBlockPayees > mapMasternodeBlocks
static const unsigned int BLOCK_DOWNLOAD_WINDOW
string SanitizeString(const string &str, int rule)
std::atomic< int > nVersion
std::vector< std::pair< unsigned int, uint256 > > vMatchedTxn
std::vector< CInv > vInventoryToSend
std::string itostr(int n)
int atoi(const std::string &str)
bool HasVerifiedPaymentVote(uint256 hashIn)
map< string, string > mapArgs
uint64_t GetRand(uint64_t nMax)
CCriticalSection cs_vProcessMsg