Skip to content

Attestation target can walk behind the head's justified checkpoint; other clients clamp, Verity skips the vote #44

Description

@adust09

What

The attestation duty is skipped with SOURCE_AFTER_TARGET when the target walk-back lands behind the head chain's justified checkpoint. In the 2026-09-11 three-node devnet5 run (PR #42) it fired at slots 16 and 64 (twice):

WARN duty not performed slot=64 interval=321 error=the duty would produce a rejected value: SOURCE_AFTER_TARGET

Why

Verity's attestation_target / attestation_data are a faithful transcription of leanSpec validator_duties.py (0b7d33ec), including the spot where leanSpec asserts source.slot <= target.slot. The assert condition is reachable: the persisted fork-choice tree of that run (dumped from the node's RocksDB) shows the head chain 62 → 59 → 51 → 50 → 49 → 45 → 42 with finalized 42 and the head state's justified at 49. The three-step walk-back from 62 lands on 50; 50 and 49 are not justifiable relative to finalized 42 (deltas 8 and 7), so the justifiability walk continues to 45 — behind the source at 49. Nothing in the spec bounds the second walk by the justified slot, and a sparse chain (three nodes, one proposer per slot, many orphans) makes the three-step walk cover many slots.

ethlambda (crates/blockchain/src/store.rs, get_attestation_target_with_checkpoints) and ream (crates/common/fork_choice/lean/src/store.rs) both clamp the target to the head's justified checkpoint in this case, with a comment that it is "not in the spec" (ethlambda cites zeam doing the same). Verity returns the vote as a rejection and casts nothing, so its validator's weight is missing from those slots.

Fix direction

Match the other clients: when the walked target's slot is below the head state's justified slot, return the justified checkpoint as the target (and log it). Keep the SourceAfterTarget rejection as the assertion it is, now unreachable from the duty path. Worth raising upstream on leanSpec as well, since the reference implementation would assert here.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions