Skip to content

feat(events): add chain_reorg and safe_target chain events#533

Closed
MegaRedHand wants to merge 1 commit into
mainfrom
feat/events-reorg-safe-target
Closed

feat(events): add chain_reorg and safe_target chain events#533
MegaRedHand wants to merge 1 commit into
mainfrom
feat/events-reorg-safe-target

Conversation

@MegaRedHand

@MegaRedHand MegaRedHand commented Jul 21, 2026

Copy link
Copy Markdown
Collaborator

Continues the chain-event pub-sub series (#516 / #517 / #518, all merged). Adds the two cheap follow-up topics, both derived from the existing actor-layer snapshot diff.

Events added

Topic Payload Emitted when
chain_reorg { slot, depth, old_head_block, old_head_state, new_head_block, new_head_state } Fork choice switches to a head off the old head's chain (same recency gate as head)
safe_target { slot, block } The interval-3 fork-choice safe attestation target advances

Notes

  • chain_reorg reuses store::reorg_depth, widened to pub(crate) so the actor diff and block processing share one definition of "reorg". Recency-gated like head (HEAD_EVENT_RECENCY_SLOTS) and emitted just before it, matching beacon ordering; payload mirrors the beacon chain_reorg shape minus epoch/execution_optimistic.
  • safe_target is an ethlambda extension with no beacon analog; ungated since it coalesces to the latest value (the only one that matters).

Testing

cargo fmt, cargo clippy -p ethlambda-blockchain (clean), blockchain lib tests pass, including two new unit tests: chain_event_diff_emits_chain_reorg_before_head and chain_event_diff_emits_safe_target.


Independent PR, based off main. One of three sibling PRs continuing the series — alongside #534 (attestation/aggregate) and #535 (block_gossip), each independently based off main. They touch overlapping regions of events.rs / docs/rpc.md, so whichever two merge later will each need a small conflict rebase. Opened as draft.

Extend the /lean/v0/events stream with two cheap follow-up topics
derived from the actor-layer snapshot diff.

chain_reorg: fork choice switched to a head off the old head's chain.
Reuses store::reorg_depth (widened to pub(crate) so the actor diff and
block processing share one definition of "reorg"); recency-gated like
head and emitted just before it. Mirrors the beacon chain_reorg payload
minus epoch/execution_optimistic.

safe_target: the interval-3 fork-choice safe attestation target
advanced. Ungated since it coalesces to the latest value, the only one
that matters; an ethlambda extension with no beacon analog.
MegaRedHand added a commit that referenced this pull request Jul 24, 2026
Continues the chain-event pub-sub series (#516 / #517 / #518, all
merged). Adds the beacon `block_gossip` analog.

## Event added

| Topic | Payload | Emitted when |
|-------|---------|--------------|
| `block_gossip` | `{ slot, block }` | A block is seen on the network,
before import |

## Notes

- Emitted from the blockchain actor's `NewBlock` handler, **not** a
second P2P-side publisher, so the actor stays the sole event publisher
and the write flow stays one-directional (a core requirement of the
series' design).
- Fires for both gossip'd and by-root-fetched blocks, since both
re-enter through `NewBlock`. Import may pend the block while its parent
chain is fetched, so this precedes import.
- Ungated like `block` (not recency-gated), so subscribers can watch
sync progress. Low-rate (one per block), so the payload is built
unconditionally behind `emit`'s no-subscriber guard.

## Testing

`cargo fmt`, `cargo clippy -p ethlambda-blockchain -p ethlambda-rpc`
(clean), blockchain lib + rpc events tests pass.

---
**Independent PR, based off `main`.** One of three sibling PRs
continuing the series — alongside #533 (`chain_reorg`/`safe_target`) and
#534 (`attestation`/`aggregate`), each independently based off `main`.
They touch overlapping regions of `events.rs` / `docs/rpc.md`, so
whichever two merge later will each need a small conflict rebase. Opened
as draft.
@MegaRedHand

Copy link
Copy Markdown
Collaborator Author

Closing this until the events become relevant

@MegaRedHand
MegaRedHand deleted the feat/events-reorg-safe-target branch July 24, 2026 20:29
MegaRedHand added a commit that referenced this pull request Jul 24, 2026
Continues the chain-event pub-sub series (#516 / #517 / #518, all
merged). Adds the two high-rate topics.

## Events added

| Topic | Payload | Emitted when |
|-------|---------|--------------|
| `attestation` | `{ validator_id, data: AttestationData }` | A single
validator vote passes gossip validation (signature omitted) |
| `aggregate` | `{ participants: [u64], data: AttestationData }` | A
committee-signature aggregate is produced locally or accepted from
gossip (proof omitted) |

Both fire only for messages the store **accepted** (data + signature
validation), so subscribers see the same votes fork choice does. A node
never receives its own aggregate back over gossip, so `aggregate` fires
at two sites: the locally produced `AggregateProduced` path and the
gossip-received path.

## Design points

- The ~3 KB XMSS signature and the SNARK proof bytes are deliberately
**omitted** — too heavy for a high-rate stream.
- The shared broadcast channel capacity is bumped **256 → 8192**. All
topics share one ring buffer, so a subscriber's tolerable stall is
`capacity / total_event_rate` (dominated by the attestation rate), not
per-topic. A per-topic split behind the `EventBus` facade remains the
escape hatch if real devnet rates show the shared window biting — see
the note in `docs/rpc.md`.
- Emission uses the plain, no-subscriber-guarded `emit`. Consequence:
the per-vote `AttestationData` is cloned even when nobody is subscribed
(the guard only skips the send). If that actor-hot-path cost proves
material, a payload-deferral helper can be added in a follow-up.

## Testing

`cargo fmt`, `cargo clippy -p ethlambda-blockchain -p ethlambda-rpc`
(clean), blockchain + rpc lib tests pass, including
`events_streams_attestation_with_nested_data` (verifies the untagged
`data:` nesting over the wire).

---
**Independent PR, based off `main`.** One of three sibling PRs
continuing the series — alongside #533 (`chain_reorg`/`safe_target`) and
#535 (`block_gossip`), each independently based off `main`. They touch
overlapping regions of `events.rs` / `docs/rpc.md`, so whichever two
merge later will each need a small conflict rebase.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant