-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Description
Minimal Phase 0 Wire API [WIP]
This is the minimal wire API required for Phase 0 of Eth2.0. Note that this is not the wire protocol but the interface right above. Once we settle on the API required, we can specify the underlying protocol.
All API methods are specified as the plural list version, assuming that if singular objects are sent or requested that the input will just be a list of length 1.
"Bad form" is any action that is not explicitly against the protocol but is not in the best interest of one's peers or the protocol in general. Messages/requests that are considered bad form may reduce the reputation of the sending node and may result in being dropped.
TODO:
- add tentative light client proposal Light client proposal #459 after merging in phase 1 PRs
- specify requesting and serving state via tree hash and state root
- vet sync proposal with 1.0 sync masters and vet alternatives
Dependencies
This document depends on:
Network topology
Ethereum 2.0 network topology consists of a pubsub mapping of peers to "topics". These topics along with peer mappings effectively form subnets.
The primary topics of core protocol consideration are:
beacon: All messages for the beacon chain are mapped to topicbeacon.shard-{number}for all integersnumberin[0, SHARD_SUBNET_COUNT): Messages for a given shard defined byshard_numberare mapped to topicshard-{shard_number % SHARD_SUBNET_COUNT}.
We use discv5 to discover peers of select topics, and we use gossipsub, a libp2p routing protocol, to route messages of a particular topic to the subnet in question.
Note: attempting to broadcast or request messages about a topic not subscribed to by the peer is considered bad form. For example, running send_attestations(attestations) where one or more of the attestations have attestation.data.shard == 5 to a peer not subscribed to shard-5 might result in that peer dropping the sending node.
Compression
Should conform on a compression standard early on. Libp2p does not ship with anything built in and recommends just adding compression over the libp2p stream.
API
EDIT: much of this API has not been specified noting the distinction between 1-on-1 RPC requests/responses between peers vs. pubsub broadcasts. Some methods below are implicitly doing both. This implicitness needs to be made explicit in the wire protocol.
Sync
The following is a basic sync protocol akin to eth1.0. This sync assumes that client has some latest_finalized_root/epoch acquired either from a previous sync or out-of-band. This data should be no older than the weak-subjectivity period of the network at that finalized checkpoint (dynamic based upon validator set size).
A status message is sent in the initial handshake between two peers. After handshake and status exchange, the peer with higher latest_finalized_epoch or, if epochs are equal, the higher best_slot sends a list of beacon_block_roots via send_beacon_block_roots. It is assumed that clients store and serve blocks at least as old as the network's current weak-subjectivity period.
- If
latest_finalized_root/epochfrom each peer are in separate chains, then the two peers cannot sync and should terminate connection. - If time between
latest_finalized_root/epochof each peer is greater than the weak-subjectivity period, then the peer behind cannot safely sync and should terminate connection.
Status handshake fields:
protocol_version: type/format TBDnetwork_id: type/format TBDlatest_finalized_root: bytes32latest_finalized_epoch: uint64best_root: bytes32best_slot: uint64
From state snapshot
If client has state up until latest_finalized_root/epoch (from a previous sync or from a snapshot acquired out-of-band), client can process the per-block state transitions from the latest_finalized_root to reach the head.
Fast sync state
If client does not have state at latest_finalized_root/epoch, then the client should perform a fast sync akin to eth1.0 fast synchronization to the latest_finalized_root/epoch provided by the peer.
Beacon Blocks
Supported pubsub topics:
beacon
The following definitions are used in the API:
block_header: a serializedBeaconBlockin whichBeaconBlock.bodyis thehash_tree_rootof the associatedBeaconBlockBody.block_body: a serialiedBeaconBlockBody.block_root: thehash_tree_rootof aBeaconBlock.
API:
send_beacon_block_roots(block_roots_and_slots): Sends list of(block_root, slot)to peer.send_beacon_block_headers(block_headers): Sends list ofblock_headersto peer.request_beacon_block_headers(block_root, slot, max_headers, skip_slots): Requests theblock_headersstarting at(block_root, slot)skip slots apart (if no block at the expected slot, return the next block at or above the expected slot) from peer. Reply must contain at mostmax_headersheaders.send_beacon_block_bodies(block_bodies): Sends list ofblock_bodiesto peer.request_beacon_block_bodies(block_roots): Requests the associatedblock_bodiesfor the givenblock_rootsfrom peer.
Notes:
- It is assumed that both the associated
BeaconBlockandBeaconBlockBodycan be looked up viablock_root. - We need to model out the various uses of
request_beacon_block_headersand make sure the skip mechanism suits our needs. (I'm not sure it's particularly useful without specifying requesting info about state).
Attestations
Supported pubsub topics:
beacon- all
shard-{number}topics
The following definitions are used in the API:
attestation: a serializedAttestationwith full serializedAttestationDataforattestation.data.
API:
send_attestations(attestations): Sends list ofattestationsto peer.
Notes:
- It is expected that an attestation is only broadcast to either
beacontopic orshard-{attestation.data.shard}topic. Broadcasting to mismatched shard topics is considered bad form. - It is expected that only aggregate attestations are broadcast to the
beacontopic. Repeated broadcasting of attestations with a single signer to thebeacontopic is considered bad form. - There is a shard subnet design decision here. Due to the likelihood of
attestation.datato be highly repeated across a committee during a given slot, it could be valuable to just send theattestationwith arootin theattestation.datafield. If the recipient does not already have anAttestationDatafor the receivedroot, then the recipient would explicitly request the root. This reduces the total data passed by 184 bytes in the case that the recipient has already received theattestation.databut increases the rounds of communication when they haven't. - We do not currently specify a getter method for an attestation by its
root. Due to the diverse ways attestations might both be aggregated and stored, it is not feasible to reliably lookup via aroot. The attestations that a client cares about are (1) those that made it on-chain into aBeaconBlockand (2) the most recent set of attestations being actively broadcast on the wire. We might provide arequest_attestations(slot)orrequest_attestations(epoch)but do not provide it in this minimal API specification.
Exits
Supported pubsub topics:
beacon
The following definitions are used in the API:
exit: a serializedExit.
API:
send_exits(exits): Sends a list ofexitsto peer.
Notes:
- We do not specify a getter for an exit by its
root. Standard usage is for a validator to broadcast when attempting to exit and for the exit to be soon added to a block.
State
TODO: Specify handling requests of subsections of state given a block.state_root