Describe the bug
EXECUTION_ENGINE_INVALID is treated as a peer attributable failure in range sync (isPeerAttributableFailure). When a batch fails MAX_BATCH_PROCESSING_ATTEMPTS times with it, shouldReportPeerOnBatchError reports every peer that served a failed attempt with LowToleranceError (-10), so a peer is banned (-50) after 5 rounds.
This is correct when a peer serves a block with a bad payload, but the same verdict is produced when our own execution client is wrong. On glamsterdam-devnet-9 (2026-09-04, genesis resync) besu 26.9-develop marked a canonical payload INVALID after a "World State Root does not match" on block 4334 and kept its descendants in the bad block cache, returning INVALID without re-execution (reported to besu). Lodestar retried the batch, every retry was served by other peers with the correct blocks (same roots, hash verified) and every round penalized them.
Observed on the besu-2 node over ~2.7 h: 219 peer bans and 1140 batch processing errors with the head stuck at slot 4832. The four other nodes resyncing at the same time with the same peer set had 7 to 21 bans.
Expected behavior
When independent peers serve identical data for a batch and the execution client still returns INVALID, the peers are not at fault and should not be penalized. Batch.failedProcessingAttempts already records the peers per attempt, and since #10025/#10028 the rejected block is dropped from the seen cache and re-downloaded, so the retries do compare independent peers.
Options
- do not report peers for
EXECUTION_ENGINE_INVALID once two or more distinct peers served the same block roots for the failing batch
- or report
EXECUTION_ENGINE_INVALID with MidToleranceError so it alone cannot ban a peer, and keep LowToleranceError for failures that prove bad content (INVALID_SIGNATURE, INVALID_STATE_ROOT, non-linear segments)
Additional context
Describe the bug
EXECUTION_ENGINE_INVALIDis treated as a peer attributable failure in range sync (isPeerAttributableFailure). When a batch failsMAX_BATCH_PROCESSING_ATTEMPTStimes with it,shouldReportPeerOnBatchErrorreports every peer that served a failed attempt withLowToleranceError(-10), so a peer is banned (-50) after 5 rounds.This is correct when a peer serves a block with a bad payload, but the same verdict is produced when our own execution client is wrong. On glamsterdam-devnet-9 (2026-09-04, genesis resync) besu 26.9-develop marked a canonical payload
INVALIDafter a "World State Root does not match" on block 4334 and kept its descendants in the bad block cache, returningINVALIDwithout re-execution (reported to besu). Lodestar retried the batch, every retry was served by other peers with the correct blocks (same roots, hash verified) and every round penalized them.Observed on the besu-2 node over ~2.7 h: 219 peer bans and 1140 batch processing errors with the head stuck at slot 4832. The four other nodes resyncing at the same time with the same peer set had 7 to 21 bans.
Expected behavior
When independent peers serve identical data for a batch and the execution client still returns
INVALID, the peers are not at fault and should not be penalized.Batch.failedProcessingAttemptsalready records the peers per attempt, and since #10025/#10028 the rejected block is dropped from the seen cache and re-downloaded, so the retries do compare independent peers.Options
EXECUTION_ENGINE_INVALIDonce two or more distinct peers served the same block roots for the failing batchEXECUTION_ENGINE_INVALIDwithMidToleranceErrorso it alone cannot ban a peer, and keepLowToleranceErrorfor failures that prove bad content (INVALID_SIGNATURE,INVALID_STATE_ROOT, non-linear segments)Additional context
lodestar_sync_range_batch_process_error_total{code})