diff --git a/apis/eventstream/eventstream.v2.yaml b/apis/eventstream/eventstream.v2.yaml new file mode 100644 index 00000000..7abf0145 --- /dev/null +++ b/apis/eventstream/eventstream.v2.yaml @@ -0,0 +1,160 @@ +get: + operationId: "eventstreamV2" + summary: Subscribe to beacon node events + tags: + - Events + - ValidatorRequiredApi + description: | + Provides endpoint to subscribe to beacon node Server-Sent-Events stream. + Consumers should use [eventsource](https://html.spec.whatwg.org/multipage/server-sent-events.html#the-eventsource-interface) + implementation to listen on those events. + + Servers _may_ send SSE comments beginning with `:` for any purpose, including to keep the + event stream connection alive in the presence of proxy servers. + parameters: + - name: topics + in: query + required: true + description: Event types to subscribe to + schema: + type: array + uniqueItems: true + items: + type: string + enum: + - head + - block + - block_gossip + - attestation + - voluntary_exit + - bls_to_execution_change + - proposer_slashing + - attester_slashing + - finalized_checkpoint + - chain_reorg + - contribution_and_proof + - light_client_finality_update + - light_client_optimistic_update + - payload_attributes + - blob_sidecar + responses: + "200": + description: Opened SSE stream. + content: + text/event-stream: + schema: + type: string + description: https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events#Event_stream_format + examples: + head: + description: The node has finished processing, resulting in a new head. previous_duty_dependent_root is `get_block_root_at_slot(state, compute_start_slot_at_epoch(epoch - 1) - 1)` and current_duty_dependent_root is `get_block_root_at_slot(state, compute_start_slot_at_epoch(epoch) - 1)`. Both dependent roots use the genesis block root in the case of underflow. + value: | + event: head + data: {"slot":"10", "block":"0x9a2fefd2fdb57f74993c7780ea5b9030d2897b615b89f808011ca5aebed54eaf", "state":"0x600e852a08c1200654ddf11025f1ceacb3c2e74bdd5c630cde0838b2591b69f9", "epoch_transition":false, "previous_duty_dependent_root":"0x5e0043f107cb57913498fbf2f99ff55e730bf1e151f02f221e977c91a90a0e91", "current_duty_dependent_root":"0x5e0043f107cb57913498fbf2f99ff55e730bf1e151f02f221e977c91a90a0e91", "execution_optimistic": false} + block: + description: The node has received a block (from P2P or API) that is successfully imported on the fork-choice `on_block` handler + value: | + event: block + data: {"slot":"10", "block":"0x9a2fefd2fdb57f74993c7780ea5b9030d2897b615b89f808011ca5aebed54eaf", "execution_optimistic": false} + block_gossip: + description: The node has received a block (from P2P or API) that passes validation rules of the `beacon_block` topic + value: | + event: block_gossip + data: {"slot":"10", "block":"0x9a2fefd2fdb57f74993c7780ea5b9030d2897b615b89f808011ca5aebed54eaf"} + attestation: + description: The node has received an Attestation (from P2P or API) that passes validation rules of the `beacon_attestation_{subnet_id}` topic + value: | + event: attestation + data: {"version":"altair", "data": {"aggregation_bits":"0x01", "signature":"0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505", "data":{"slot":"1", "index":"1", "beacon_block_root":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", "source":{"epoch":"1", "root":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"}, "target":{"epoch":"1", "root":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"}}}} + voluntary_exit: + description: The node has received a SignedVoluntaryExit (from P2P or API) that passes validation rules of `voluntary_exit` topic + value: | + event: voluntary_exit + data: {"message":{"epoch":"1", "validator_index":"1"}, "signature":"0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505"} + proposer_slashing: + description: The node has received a ProposerSlashing (from P2P or API) that passes validation rules of the `proposer_slashing` topic + value: | + event: proposer_slashing + data: {"signed_header_1":{"message":{"slot":"0","proposer_index":"0","parent_root":"0x0000000000000000000000000000000000000000000000000000000000000000","state_root":"0x0000000000000000000000000000000000000000000000000000000000000000","body_root":"0x0000000000000000000000000000000000000000000000000000000000000000"},"signature":"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"},"signed_header_2":{"message":{"slot":"0","proposer_index":"0","parent_root":"0x0000000000000000000000000000000000000000000000000000000000000000","state_root":"0x0000000000000000000000000000000000000000000000000000000000000000","body_root":"0x0000000000000000000000000000000000000000000000000000000000000000"},"signature":"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"}} + attester_slashing: + description: The node has received an AttesterSlashing (from P2P or API) that passes validation rules of the `attester_slashing` topic + value: | + event: attester_slashing + data: {"version":"altair", "data": {"attestation_1":{"attesting_indices":["0", "1"],"data":{"slot":"0","index":"0","beacon_block_root":"0x0000000000000000000000000000000000000000000000000000000000000000","source":{"epoch":"0","root":"0x0000000000000000000000000000000000000000000000000000000000000000"},"target":{"epoch":"0","root":"0x0000000000000000000000000000000000000000000000000000000000000000"}},"signature":"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"},"attestation_2":{"attesting_indices":["0", "1"],"data":{"slot":"0","index":"0","beacon_block_root":"0x0000000000000000000000000000000000000000000000000000000000000000","source":{"epoch":"0","root":"0x0000000000000000000000000000000000000000000000000000000000000000"},"target":{"epoch":"0","root":"0x0000000000000000000000000000000000000000000000000000000000000000"}},"signature":"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"}}} + bls_to_execution_change: + description: The node has received a SignedBLSToExecutionChange (from P2P or API) that passes validation rules of the `bls_to_execution_change` topic + value: | + event: bls_to_execution_change + data: {"message":{"validator_index":"1", "from_bls_pubkey":"0x933ad9491b62059dd065b560d256d8957a8c402cc6e8d8ee7290ae11e8f7329267a8811c397529dac52ae1342ba58c95", "to_execution_address":"0x9Be8d619c56699667c1feDCD15f6b14D8B067F72"}, "signature":"0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505"} + finalized_checkpoint: + description: Finalized checkpoint has been updated + value: | + event: finalized_checkpoint + data: {"block":"0x9a2fefd2fdb57f74993c7780ea5b9030d2897b615b89f808011ca5aebed54eaf", "state":"0x600e852a08c1200654ddf11025f1ceacb3c2e74bdd5c630cde0838b2591b69f9", "epoch":"2", "execution_optimistic": false } + chain_reorg: + description: The node has reorganized its chain + value: | + event: chain_reorg + data: {"slot":"200", "depth":"50", "old_head_block":"0x9a2fefd2fdb57f74993c7780ea5b9030d2897b615b89f808011ca5aebed54eaf", "new_head_block":"0x76262e91970d375a19bfe8a867288d7b9cde43c8635f598d93d39d041706fc76", "old_head_state":"0x9a2fefd2fdb57f74993c7780ea5b9030d2897b615b89f808011ca5aebed54eaf", "new_head_state":"0x600e852a08c1200654ddf11025f1ceacb3c2e74bdd5c630cde0838b2591b69f9", "epoch":"2", "execution_optimistic": false} + contribution_and_proof: + description: The node has received a SignedContributionAndProof (from P2P or API) that passes validation rules of the `sync_committee_contribution_and_proof` topic + value: | + event: contribution_and_proof + data: {"message": {"aggregator_index": "997", "contribution": {"slot": "168097", "beacon_block_root": "0x56f1fd4262c08fa81e27621c370e187e621a67fc80fe42340b07519f84b42ea1", "subcommittee_index": "0", "aggregation_bits": "0xffffffffffffffffffffffffffffffff", "signature": "0x85ab9018e14963026476fdf784cc674da144b3dbdb47516185438768774f077d882087b90ad642469902e782a8b43eed0cfc1b862aa9a473b54c98d860424a702297b4b648f3f30bdaae8a8b7627d10d04cb96a2cc8376af3e54a9aa0c8145e3"}, "selection_proof": "0x87c305f04bfe5db27c2b19fc23e00d7ac496ec7d3e759cbfdd1035cb8cf6caaa17a36a95a08ba78c282725e7b66a76820ca4eb333822bd399ceeb9807a0f2926c67ce67cfe06a0b0006838203b493505a8457eb79913ce1a3bcd1cc8e4ef30ed"}, "signature": "0xac118511474a94f857300b315c50585c32a713e4452e26a6bb98cdb619936370f126ed3b6bb64469259ee92e69791d9e12d324ce6fd90081680ce72f39d85d50b0ff977260a8667465e613362c6d6e6e745e1f9323ec1d6f16041c4e358839ac"} + light_client_finality_update: + description: The node's latest known `LightClientFinalityUpdate` has been updated + value: | + event: light_client_finality_update + data: {"version":"altair", "data": {"attested_header": {"beacon": {"slot":"1", "proposer_index":"1", "parent_root":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", "state_root":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", "body_root":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"}}, "finalized_header": {"beacon": {"slot":"1", "proposer_index":"1", "parent_root":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", "state_root":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", "body_root":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"}}, "finality_branch": ["0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"], "sync_aggregate": {"sync_committee_bits":"0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffffffffffffffffffffffbffffffffffffffffffffbffffffffffffff", "sync_committee_signature":"0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505"}, "signature_slot":"1"}} + light_client_optimistic_update: + description: The node's latest known `LightClientOptimisticUpdate` has been updated + value: | + event: light_client_optimistic_update + data: {"version":"altair", "data": {"attested_header": {"beacon": {"slot":"1", "proposer_index":"1", "parent_root":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", "state_root":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", "body_root":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"}}, "sync_aggregate": {"sync_committee_bits":"0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffffffffffffffffffffffbffffffffffffffffffffbffffffffffffff", "sync_committee_signature":"0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505"}, "signature_slot":"1"}} + payload_attributes: + description: | + The node has computed new payload attributes for execution payload building. + + This event gives block builders and relays sufficient information to construct or + verify a block at `proposal_slot`. The meanings of the fields are: + + - `version`: the identifier of the beacon hard fork at `proposal_slot`, e.g. + `"bellatrix"`, `"capella"`. + - `proposal_slot`: the slot at which a block using these payload attributes may be + built. + - `parent_block_root`: the beacon block root of the parent block to be built upon. + - `parent_block_number`: the execution block number of the parent block. + - `parent_block_hash`: the execution block hash of the parent block. + - `proposer_index`: the validator index of the proposer at `proposal_slot` on + the chain identified by `parent_block_root`. + - `payload_attributes`: beacon API encoding of `PayloadAttributesV` as + defined by the `execution-apis` specification. The version `N` must match the + payload attributes for the hard fork matching `version`. + The beacon API encoded object must have equivalent fields to its counterpart in + `execution-apis` with two differences: 1) `snake_case` identifiers must be used + rather than `camelCase`; 2) integers must be encoded as quoted decimals rather + than big-endian hex. + + The frequency at which this event is sent may depend on beacon node configuration. + The fee recipient may also be set via beacon node config, but should likely be + ignored by block builders and most other API consumers. + value: | + event: payload_attributes + data: {"version": "capella", "data": {"proposer_index": "123", "proposal_slot": "10", "parent_block_number": "9", "parent_block_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", "parent_block_hash": "0x9a2fefd2fdb57f74993c7780ea5b9030d2897b615b89f808011ca5aebed54eaf", "payload_attributes": {"timestamp": "123456", "prev_randao": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", "suggested_fee_recipient": "0x0000000000000000000000000000000000000000", "withdrawals": [{"index": "5", "validator_index": "10", "address": "0x0000000000000000000000000000000000000000", "amount": "15640"}]}}} + blob_sidecar: + description: The node has received a BlobSidecar (from P2P or API) that passes all gossip validations on the blob_sidecar_{subnet_id} topic + value: | + event: blob_sidecar + data: {"block_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", "index": "1", "slot": "1", "kzg_commitment": "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505", "versioned_hash": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"} + "400": + description: "The topics supplied could not be parsed" + content: + application/json: + schema: + $ref: "../../beacon-node-oapi.yaml#/components/schemas/ErrorMessage" + example: + code: 400 + message: "Invalid topic: weather_forecast" + "500": + $ref: '../../beacon-node-oapi.yaml#/components/responses/InternalError' + diff --git a/apis/eventstream/index.yaml b/apis/eventstream/eventstream.yaml similarity index 100% rename from apis/eventstream/index.yaml rename to apis/eventstream/eventstream.yaml diff --git a/beacon-node-oapi.yaml b/beacon-node-oapi.yaml index 31a60561..f2f33929 100644 --- a/beacon-node-oapi.yaml +++ b/beacon-node-oapi.yaml @@ -220,8 +220,9 @@ paths: $ref: "./apis/validator/liveness.yaml" /eth/v1/events: - $ref: "./apis/eventstream/index.yaml" - + $ref: "./apis/eventstream/eventstream.yaml" + /eth/v2/events: + $ref: "./apis/eventstream/eventstream.v2.yaml" components: schemas: