fix: apply real DoS score for invalid headers (Misbehaving nDoS/nDoS was always 1)

In the HEADERS handler, an invalid header scored Misbehaving(id, nDoS/nDoS). Because
the call is guarded by `if (nDoS > 0 ...)`, nDoS/nDoS is always exactly 1, so every
invalid header cost a fixed 1 misbehavior point regardless of severity -- it took
~banscore (default 101) invalid headers to ban a peer instead of 1, effectively
disarming the ban backstop against header spam. The two sibling call sites in the
same handler (tx-accept, block-accept) already pass nDoS directly.

Pass the real nDoS so a genuinely-invalid header (e.g. bad-diffbits, DoS 100) bans in
one message. Cannot over-ban honest peers: every DoS>0 header path is genuinely
invalid consensus, and benign/racy headers (unconnectable prevblock, future block,
clock-skew) either score DoS 0 or never reach Misbehaving (double-guarded by
IsInvalid + nDoS>0 + futureblock==0).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-09 04:29:54 +02:00
parent 2e54d9fb4d
commit 4e3c0f8f6f

View File

@@ -7795,7 +7795,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
if (state.IsInvalid(nDoS) && futureblock == 0)
{
if (nDoS > 0 && futureblock == 0)
Misbehaving(pfrom->GetId(), nDoS/nDoS);
Misbehaving(pfrom->GetId(), nDoS);
return error("invalid header received");
}
}