Skip to content

feat(rpc): emit single_attestation on /eth/v1/events - #757

Draft
MegaRedHand wants to merge 2 commits into
feat/beacon-gloas-eventsfrom
feat/beacon-single-attestation-event
Draft

MegaRedHand wants to merge 2 commits into
feat/beacon-gloas-eventsfrom
feat/beacon-single-attestation-event

Conversation

@MegaRedHand

Copy link
Copy Markdown
Collaborator

Motivation

ethPandaOps' contributoor (the xatu sentry behind lab.ethpandaops.io) subscribes to single_attestation and never to attestation. ethlambda accepted a single_attestation subscription but never sent anything on it, so the lab shows no attestation data for our nodes, while Lighthouse nodes running the same contributoor config do send it.

Stacked on #748, whose GossipEventSink this reuses.

Description

Two commits, so the second can be dropped on its own:

  1. Gossip (feat(rpc): emit single_attestation for gossip-accepted subnet attestations): subnet attestations are validated in ethlambda-p2p and never reach the chain actor, so publish_gossip_event (p2p/src/beacon/verdict.rs) reports an accepted one as GossipEvent::SingleAttestation, which the event bus maps to ChainEvent::SingleAttestation on Topic::SingleAttestation. This is the highest-rate event the node has, so the attestation is cloned only when a client is subscribed, and the payload is boxed. The payload is the existing electra SingleAttestation container, so the JSON is the spec's.
  2. API (feat(rpc): emit single_attestation for API-submitted attestations): POST /eth/v2/beacon/pool/attestations reports each attestation that passed validation and was handed to the network actor, the spec's "(from P2P or API)" half. Kept separate because emitting our own validators' attestations, with near-zero propagation time, can link validator indices to the node (why contributoor makes the topic opt-in). Dropping it would need a line in docs/spec_deviations.md.

docs/rpc.md moves single_attestation from "never emitted" to the emitted table.

Note for the lab: contributoor derives the subnet as committee_index % 64, which only equals the real subnet with 64 committees per slot. On Sepolia (1 committee per slot) it drops every attestation, so this shows up on mainnet and Hoodi only.

How to test

  • cargo test -p ethlambda-blockchain --lib events (spec example JSON shape, gossip event to topic mapping)
  • cargo test -p ethlambda-p2p --lib (accepted attestation reaches the sink only on Accept and only when subscribed)
  • cargo test -p ethlambda-rpc --lib (an accepted API attestation reaches the bus, a refused one does not)
  • Live: curl -N 'localhost:5052/eth/v1/events?topics=single_attestation' on a beacon node.

…tions

ethPandaOps' contributoor subscribes to single_attestation and never to
attestation, and ethlambda accepted that topic without ever sending it, so
the lab showed no attestation data for our nodes.

Subnet attestations are validated in ethlambda-p2p and never reach the chain
actor, so p2p reports an accepted one through the GossipEventSink that #748
added, and the event bus maps it to a ChainEvent on Topic::SingleAttestation.
It is the highest-rate event the node has (every attestation on its backbone
subnets), so the attestation is cloned only when a client is subscribed, and
the payload is boxed to keep the broadcast ring sized for the smaller
variants. The payload is the existing electra SingleAttestation container, so
its JSON form is the specification's.
This is the specification's "(from P2P or API)" half of single_attestation:
POST /eth/v2/beacon/pool/attestations now reports each attestation that
passed validation and was handed to the network actor, the way the other
API handlers report what a validator client or builder submits.

It is a separate commit because emitting our own validators' attestations,
with near-zero propagation time, can link validator indices to this node,
which is why contributoor makes the topic opt-in. Dropping this commit leaves
the gossip-accepted events alone; docs/spec_deviations.md would then need a
line saying API submissions are not reported.
MegaRedHand added a commit that referenced this pull request Nov 2, 2026
feat(rpc): emit single_attestation for gossip-accepted subnet attestations

ethPandaOps' contributoor subscribes to single_attestation and never to
attestation, and ethlambda accepted that topic without ever sending it, so
the lab showed no attestation data for our nodes.

Subnet attestations are validated in ethlambda-p2p and never reach the chain
actor, so p2p reports an accepted one through the GossipEventSink that #748
added, and the event bus maps it to a ChainEvent on Topic::SingleAttestation.
It is the highest-rate event the node has (every attestation on its backbone
subnets), so the attestation is cloned only when a client is subscribed, and
the payload is boxed to keep the broadcast ring sized for the smaller
variants. The payload is the existing electra SingleAttestation container, so
its JSON form is the specification's.

Second commit: feat(rpc): emit single_attestation for API-submitted attestations

This is the specification's "(from P2P or API)" half of single_attestation:
POST /eth/v2/beacon/pool/attestations now reports each attestation that
passed validation and was handed to the network actor, the way the other
API handlers report what a validator client or builder submits.

It is a separate commit because emitting our own validators' attestations,
with near-zero propagation time, can link validator indices to this node,
which is why contributoor makes the topic opt-in. Dropping this commit leaves
the gossip-accepted events alone; docs/spec_deviations.md would then need a
line saying API submissions are not reported.

Cherry-picked from feat/beacon-single-attestation-event at 6a62106.
Adapted onto #749: events.rs keeps both the BeaconFastConfirmation and SingleAttestation variants and topic arms.

This branch has not been deployed

No deployments
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