fix(net): verify PoW at header-accept once synced (header-flood DoS)
AcceptBlockHeader called CheckBlockHeader with fCheckPOW=0, so a synced node
stored any well-formed PoW-less header off the tip into mapBlockIndex without
bound (memory/disk DoS). nMinimumChainWork is defined but unenforced and would
not stop tip-siblings anyway (they inherit the tip's chain work). Verify PoW at
header-accept time when not in IBD: forged headers now fail RandomX and the peer
is DoS-banned. IBD keeps fCheckPOW=0 for fast header sync; the full-block
RandomX/target check at connect is unchanged, so no valid header is rejected
(not a consensus-rule change).
fCheckPOW=0 call site is Leto (6a30b40415).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -5443,7 +5443,10 @@ bool AcceptBlockHeader(int32_t *futureblockp,const CBlockHeader& block, CValidat
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (!CheckBlockHeader(futureblockp,*ppindex!=0?(*ppindex)->GetHeight():0,*ppindex, block, state,0)) {
|
// SECURITY (header-flood DoS): once synced, verify PoW at header-accept time so a peer cannot
|
||||||
|
// flood unbounded PoW-less headers into mapBlockIndex (they now fail RandomX -> DoS-ban). During
|
||||||
|
// IBD keep fCheckPOW=0 for fast header sync; the full RandomX/target check runs at block connect.
|
||||||
|
if (!CheckBlockHeader(futureblockp,*ppindex!=0?(*ppindex)->GetHeight():0,*ppindex, block, state, IsInitialBlockDownload() ? 0 : 1)) {
|
||||||
if ( *futureblockp == 0 ) {
|
if ( *futureblockp == 0 ) {
|
||||||
LogPrintf("%s: CheckBlockHeader futureblock=0\n", __func__);
|
LogPrintf("%s: CheckBlockHeader futureblock=0\n", __func__);
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
Reference in New Issue
Block a user