aboutsummaryrefslogtreecommitdiff
path: root/src/net_processing.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/net_processing.cpp')
-rw-r--r--src/net_processing.cpp43
1 files changed, 37 insertions, 6 deletions
diff --git a/src/net_processing.cpp b/src/net_processing.cpp
index 6de152ae8..dee17a733 100644
--- a/src/net_processing.cpp
+++ b/src/net_processing.cpp
@@ -731,6 +731,25 @@ void Misbehaving(NodeId pnode, int howmuch)
}
+// Dogecoin - 1.14 specific fix: do not request headers from a peer we are
+// already requesting headers from, unless forced.
+void RequestHeadersFrom(CNode* pto, CConnman& connman, const CBlockIndex* pindex, uint256 untilHash, bool fforceQuery)
+{
+ if (pto->nPendingHeaderRequests > 0) {
+ if (fforceQuery) {
+ LogPrint("net", "forcing getheaders request (%d) to peer=%d (%d open)\n",
+ pindex->nHeight, pto->id, pto->nPendingHeaderRequests);
+ } else {
+ LogPrint("net", "dropped getheaders request (%d) to peer=%d\n", pindex->nHeight, pto->id);
+ return;
+ }
+ }
+
+ const CNetMsgMaker msgMaker(pto->GetSendVersion());
+ connman.PushMessage(pto, msgMaker.Make(NetMsgType::GETHEADERS, chainActive.GetLocator(pindex), untilHash));
+ pto->nPendingHeaderRequests += 1;
+
+}
@@ -1560,7 +1579,8 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
// fell back to inv we probably have a reorg which we should get the headers for first,
// we now only provide a getheaders response here. When we receive the headers, we will
// then ask for the blocks we need.
- connman.PushMessage(pfrom, msgMaker.Make(NetMsgType::GETHEADERS, chainActive.GetLocator(pindexBestHeader), inv.hash));
+ // Dogecoin: We force this check, in case we're only connected to nodes that send invs
+ RequestHeadersFrom(pfrom, connman, pindexBestHeader, inv.hash, true);
LogPrint("net", "getheaders (%d) %s to peer=%d\n", pindexBestHeader->nHeight, inv.hash.ToString(), pfrom->id);
}
}
@@ -1968,7 +1988,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
if (mapBlockIndex.find(cmpctblock.header.hashPrevBlock) == mapBlockIndex.end()) {
// Doesn't connect (or is genesis), instead of DoSing in AcceptBlockHeader, request deeper headers
if (!IsInitialBlockDownload())
- connman.PushMessage(pfrom, msgMaker.Make(NetMsgType::GETHEADERS, chainActive.GetLocator(pindexBestHeader), uint256()));
+ RequestHeadersFrom(pfrom, connman, pindexBestHeader, uint256(), true);
return true;
}
}
@@ -2225,6 +2245,9 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
{
std::vector<CBlockHeader> headers;
+ if (pfrom->nPendingHeaderRequests > 0)
+ pfrom->nPendingHeaderRequests -= 1;
+
// Bypass the normal CBlock deserialization, as we don't want to risk deserializing 2000 full blocks.
unsigned int nCount = ReadCompactSize(vRecv);
if (nCount > MAX_HEADERS_RESULTS) {
@@ -2258,7 +2281,8 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
// nUnconnectingHeaders gets reset back to 0.
if (mapBlockIndex.find(headers[0].hashPrevBlock) == mapBlockIndex.end() && nCount < MAX_BLOCKS_TO_ANNOUNCE) {
nodestate->nUnconnectingHeaders++;
- connman.PushMessage(pfrom, msgMaker.Make(NetMsgType::GETHEADERS, chainActive.GetLocator(pindexBestHeader), uint256()));
+ // Dogecoin: allow a single getheaders query before triggering DoS
+ RequestHeadersFrom(pfrom, connman, pindexBestHeader, uint256(), true);
LogPrint("net", "received header %s: missing prev block %s, sending getheaders (%d) to end (peer=%d, nUnconnectingHeaders=%d)\n",
headers[0].GetHash().ToString(),
headers[0].hashPrevBlock.ToString(),
@@ -2312,8 +2336,12 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
// Headers message had its maximum size; the peer may have more headers.
// TODO: optimize: if pindexLast is an ancestor of chainActive.Tip or pindexBestHeader, continue
// from there instead.
+ //
+ // Dogecoin: do not allow multiple getheader queries in parallel at
+ // this point - makes sure that any parallel queries will end here,
+ // preventing "getheaders" spam.
LogPrint("net", "more getheaders (%d) to end to peer=%d (startheight:%d)\n", pindexLast->nHeight, pfrom->id, pfrom->nStartingHeight);
- connman.PushMessage(pfrom, msgMaker.Make(NetMsgType::GETHEADERS, chainActive.GetLocator(pindexLast), uint256()));
+ RequestHeadersFrom(pfrom, connman, pindexLast, uint256(), false);
}
bool fCanDirectFetch = CanDirectFetch(chainparams.GetConsensus(0));
@@ -2539,7 +2567,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
// Relay
pfrom->setKnown.insert(alertHash);
{
-
+
connman.ForEachNode([&alert](CNode* pnode)
{
pnode->PushAlert(alert);
@@ -2912,10 +2940,13 @@ bool SendMessages(CNode* pto, CConnman& connman, const std::atomic<bool>& interr
the peer's known best block. This wouldn't be possible
if we requested starting at pindexBestHeader and
got back an empty response. */
+ // Dogecoin: make sure that if we are already processing an inv
+ // or header message from this peer caused by a new block being
+ // mined at chaintip, we do not send another getheaders request
if (pindexStart->pprev)
pindexStart = pindexStart->pprev;
LogPrint("net", "initial getheaders (%d) to peer=%d (startheight:%d)\n", pindexStart->nHeight, pto->id, pto->nStartingHeight);
- connman.PushMessage(pto, msgMaker.Make(NetMsgType::GETHEADERS, chainActive.GetLocator(pindexStart), uint256()));
+ RequestHeadersFrom(pto, connman, pindexStart, uint256(), false);
}
}