fix(net): verify RandomX at correct height in AcceptBlockHeader + cap locator

header-pow: AcceptBlockHeader passed the caller's reused *ppindex (and a height
derived from it, ==0 for a new header) to CheckBlockHeader instead of the
header's own local pindex + real height. Post-IBD this made
RandomXValidationRequired(0) false, so CheckRandomXSolution returned true WITHOUT
verifying (and the fRandomXVerified short-circuit could fire on an unverified
header) - silently defeating the header-flood PoW gate from b9fdc7981. Resolve
pindexPrev up-front, pass real height (parent+1) and the local (NULL) pindex so
the post-IBD RandomX check actually runs; IBD stays fast (fCheckPOW=0).
Stability-tested: 303 valid headers accepted across a 4-node RandomX net,
0 false rejects / bans.

#9 (MEDIUM) GETBLOCKS/GETHEADERS deserialized an unbounded CBlockLocator.vHave
(~130k hashes) and scanned it linearly under cs_main with no ban - a
message-thread liveness DoS. Add MAX_LOCATOR_SZ=101 + Misbehaving, matching the
adjacent vInv/headers caps.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-14 11:21:28 -05:00
parent fc06a43dd7
commit 7e9b2c6615
2 changed files with 42 additions and 1 deletions

View File

@@ -130,6 +130,12 @@ static const unsigned int BLOCK_STALLING_TIMEOUT = 2;
* peer's 160-header reply as "tip reached" and stall header sync. Raise only as a coordinated
* network upgrade (with a protocol-version bump). */
static const unsigned int MAX_HEADERS_RESULTS = 160;
/** Maximum number of entries we accept in a CBlockLocator.vHave (GETBLOCKS / GETHEADERS). An honest
* CChain::GetLocator() emits ~10 linear hashes then exponentially-spaced ones, so even a chain of
* 2^91 blocks stays well under this bound (GetLocator reserves 32). Matches upstream Bitcoin Core's
* MAX_LOCATOR_SZ. A larger vHave is a peer trying to make FindForkInGlobalIndex() linearly scan a
* huge list under cs_main (message-thread liveness DoS). */
static const unsigned int MAX_LOCATOR_SZ = 101;
/** Size of the "block download window": how far ahead of our current height do we fetch?
* Larger windows tolerate larger download speed differences between peer, but increase the potential
* degree of disordering of blocks on disk (which make reindexing and in the future perhaps pruning