Skip anti-spam difficulty check during IBD

The anti-spam check in ProcessBlock used GetLastSyncCheckpoint() which
pointed to genesis after our reset. When processing PoS blocks,
GetLastBlockIndex(genesis, true) returned NULL (no PoS blocks at genesis),
causing a crash or Misbehaving(100) which banned the seed node.

Fix: skip the entire anti-spam check during IBD - hardcoded checkpoints
already guarantee chain integrity. Also add NULL safety for the PoS
case after IBD completes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-16 20:19:39 -07:00
parent a4bfc6012a
commit 3f823e8583
+23 -29
View File
@@ -2552,39 +2552,33 @@ bool ProcessBlock(CNode* pfrom, CBlock* pblock)
if (!pblock->CheckBlock(true, true, !IsInitialBlockDownload()))
return error("ProcessBlock() : CheckBlock FAILED");
CBlockIndex* pcheckpoint = Checkpoints::GetLastSyncCheckpoint();
if(pcheckpoint && fDebug)
// Anti-spam difficulty check: skip during IBD (hardcoded checkpoints guarantee integrity)
// and skip when sync checkpoint is genesis (no PoS history to compute min stake from).
if (!IsInitialBlockDownload())
{
const CBlockIndex* pindexLastPos = GetLastBlockIndex(pcheckpoint, true);
if(pindexLastPos)
CBlockIndex* pcheckpoint = Checkpoints::GetLastSyncCheckpoint();
if (pcheckpoint && pcheckpoint->nHeight > 0 && pblock->hashPrevBlock != hashBestChain && !Checkpoints::WantedByPendingSyncCheckpoint(hash))
{
printf("ProcessBlock(): Last POS Block Height: %d \n", pindexLastPos->nHeight);
}
else
{
printf("ProcessBlock(): Previous POS block not found.\n");
}
}
int64_t deltaTime = pblock->GetBlockTime() - pcheckpoint->nTime;
CBigNum bnNewBlock;
bnNewBlock.SetCompact(pblock->nBits);
CBigNum bnRequired;
if (pcheckpoint && pblock->hashPrevBlock != hashBestChain && !Checkpoints::WantedByPendingSyncCheckpoint(hash))
{
// Extra checks to prevent "fill up memory by spamming with bogus blocks"
int64_t deltaTime = pblock->GetBlockTime() - pcheckpoint->nTime;
CBigNum bnNewBlock;
bnNewBlock.SetCompact(pblock->nBits);
CBigNum bnRequired;
if (pblock->IsProofOfStake())
{
const CBlockIndex* pindexLastPos = GetLastBlockIndex(pcheckpoint, true);
if (pindexLastPos)
bnRequired.SetCompact(ComputeMinStake(pindexLastPos->nBits, deltaTime, pblock->nTime));
}
else
bnRequired.SetCompact(ComputeMinWork(GetLastBlockIndex(pcheckpoint, false)->nBits, deltaTime));
if (pblock->IsProofOfStake())
bnRequired.SetCompact(ComputeMinStake(GetLastBlockIndex(pcheckpoint, true)->nBits, deltaTime, pblock->nTime));
else
bnRequired.SetCompact(ComputeMinWork(GetLastBlockIndex(pcheckpoint, false)->nBits, deltaTime));
if (bnNewBlock > bnRequired)
{
if (pfrom)
pfrom->Misbehaving(100);
return error("ProcessBlock() : block with too little %s", pblock->IsProofOfStake()? "proof-of-stake" : "proof-of-work");
if (bnRequired != 0 && bnNewBlock > bnRequired)
{
if (pfrom)
pfrom->Misbehaving(100);
return error("ProcessBlock() : block with too little %s", pblock->IsProofOfStake()? "proof-of-stake" : "proof-of-work");
}
}
}