Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 21 additions & 4 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,20 @@ Fork choice head update
(Store buffer fields are `new_payloads`/`known_payloads`; the accessors are named
`extract_latest_new_attestations`/`extract_latest_known_attestations`.)

### Asynchronous `engine_newPayload` (beacon)
`crates/blockchain/src/beacon_new_payload.rs`. On the running actor a pre-gloas
block (optimistic candidate) imports as optimistic and a gloas envelope applies
as `NOT_VALIDATED` before the EL answers; `engine_newPayload` goes out first from
a tokio task that reports back with a `NewPayloadAnswered` message, applied as
`optimistic-sync.md` applies a verdict. Sent parent-before-child, at most
`MAX_NEW_PAYLOADS_IN_FLIGHT` in flight; `forkchoiceUpdated` names the newest
payload on the head's chain whose request is not queued or in flight (so catch-up
still feeds the EL a head); at most `MAX_PAYLOADS_AWAITING_VERDICT` wait (past
that the import is held). No answer:
kept optimistic, re-asked once a slot (a documented deviation). Without a
mailbox (offline replay) and for non-candidates the import still waits inline.
The actor records its own `ActorRef` in a `#[started]` hook for this.

### State Transition Phases
1. **process_slots()**: Advance through empty slots, update historical roots
2. **process_block()**: Validate header → process attestations → update justifications/finality
Expand Down Expand Up @@ -819,10 +833,13 @@ transitions are in `ethlambda-types`, per the section above. Nothing above
the duties. `attestation_data.index` at a gloas slot comes from
`Store::head_payload_status`.
With `--execution-endpoint`, an envelope that passes the consensus checks is
judged by `engine_newPayloadV5` (INVALID with a null `latestValidHash` is a
hash mismatch that refuses only that envelope; INVALID with one condemns the
payload via the execution-chain walk; an engine error keeps the envelope and
retries once a slot, probing with the oldest), and a gloas head sends
applied at once (payload `NOT_VALIDATED`) and judged by `engine_newPayloadV5`
without waiting, like a pre-gloas block (see `beacon_new_payload` below):
INVALID with a null `latestValidHash` is a hash mismatch (the only answer
Engine API V2+ gives one) that takes the envelope back out and refuses only
that copy; INVALID with one condemns the payload via the execution-chain
walk; no answer keeps it applied and re-asks once a slot. Blocks built on a
FULL payload wait for its answer, not just its envelope. A gloas head sends
`engine_forkchoiceUpdatedV4` with the custody columns (head hash by the head
node's FULL or EMPTY status, finalized and safe from the checkpoint blocks'
`bid.parent_block_hash`, safe being a fallback for fast confirmation). Building
Expand Down
285 changes: 276 additions & 9 deletions crates/blockchain/src/beacon_envelope.rs

Large diffs are not rendered by default.

Loading
Loading