From 3b73e7b8893d5c07e0bf107b0affd8651187af24 Mon Sep 17 00:00:00 2001 From: Pablo Deymonnaz Date: Fri, 13 Mar 2026 15:35:31 -0300 Subject: [PATCH] Document attestation target clamping as a defensive guard not in the spec The spec's justifiability walk-back in get_attestation_target has no lower bound, so it can produce attestations where target.slot < source.slot. These would fail is_valid_vote Rule 5 and be discarded, but producing them wastes work and pollutes the network. Clarify that the clamping to latest_justified is our defensive addition, not spec behavior. --- crates/blockchain/src/store.rs | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/crates/blockchain/src/store.rs b/crates/blockchain/src/store.rs index e15e324..e1c192c 100644 --- a/crates/blockchain/src/store.rs +++ b/crates/blockchain/src/store.rs @@ -693,10 +693,16 @@ pub fn get_attestation_target(store: &Store) -> Checkpoint { .get_block_header(&target_block_root) .expect("parent block exists"); } - // Ensure target is at or after the source (latest_justified) to maintain - // the invariant: source.slot <= target.slot. When a block advances - // latest_justified between safe_target updates (interval 2), the walk-back - // above can land on a slot behind the new justified checkpoint. + // Guard: clamp target to latest_justified (not in the spec). + // + // The spec's walk-back has no lower bound, so it can produce attestations + // where target.slot < source.slot (source = latest_justified). These would + // fail is_valid_vote Rule 5 (target.slot > source.slot) and be discarded, + // but producing them wastes work and pollutes the network. + // + // This happens when a block advances latest_justified between safe_target + // updates (interval 2), causing the walk-back to land behind the new + // justified checkpoint. // // See https://github.com/blockblaz/zeam/blob/697c293879e922942965cdb1da3c6044187ae00e/pkgs/node/src/forkchoice.zig#L654-L659 let latest_justified = store.latest_justified();