You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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.
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 topic beacon.
shard-{number} for all integers number in [0, SHARD_SUBNET_COUNT): Messages for a given shard defined by shard_number are mapped to topic shard-{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/epoch from each peer are in separate chains, then the two peers cannot sync and should terminate connection.
If time between latest_finalized_root/epoch of 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 TBD
network_id: type/format TBD
latest_finalized_root: bytes32
latest_finalized_epoch: uint64
best_root: bytes32
best_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 serialized BeaconBlock in which BeaconBlock.body is the hash_tree_root of the associated BeaconBlockBody.
block_body: a serialied BeaconBlockBody.
block_root: the hash_tree_root of a BeaconBlock.
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 of block_headers to peer.
request_beacon_block_headers(block_root, slot, max_headers, skip_slots): Requests the block_headers starting 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_headers headers.
send_beacon_block_bodies(block_bodies): Sends list of block_bodies to peer.
request_beacon_block_bodies(block_roots): Requests the associated block_bodies for the given block_roots from peer.
Notes:
It is assumed that both the associated BeaconBlock and BeaconBlockBody can be looked up via block_root.
We need to model out the various uses of request_beacon_block_headers and 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 serialized Attestation with full serialized AttestationData for attestation.data.
API:
send_attestations(attestations): Sends list of attestations to peer.
Notes:
It is expected that an attestation is only broadcast to either beacon topic or shard-{attestation.data.shard} topic. Broadcasting to mismatched shard topics is considered bad form.
It is expected that only aggregate attestations are broadcast to the beacon topic. Repeated broadcasting of attestations with a single signer to the beacon topic is considered bad form.
There is a shard subnet design decision here. Due to the likelihood of attestation.data to be highly repeated across a committee during a given slot, it could be valuable to just send the attestation with a root in the attestation.data field. If the recipient does not already have an AttestationData for the received root, 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 the attestation.data but 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 a root. The attestations that a client cares about are (1) those that made it on-chain into a BeaconBlock and (2) the most recent set of attestations being actively broadcast on the wire. We might provide a request_attestations(slot) or request_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 serialized Exit.
API:
send_exits(exits): Sends a list of exits to 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
The text was updated successfully, but these errors were encountered:
Can we rename it to send_exits for consistency in plurality?
specify requesting and serving state via tree hash and state root
TODO: Specify handling requests of subsections of state given a block.state_root
Can you give an example where this would be used aside from light clients? Why not just define it as a SSZ encoded subsection of state, referred to by its state_root, and hash in the respective tree hash? With a send_substate(ssz encoded substate) and a request_substate(state_root, tree_hash of substate)?
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:
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 integersnumber
in[0, SHARD_SUBNET_COUNT)
: Messages for a given shard defined byshard_number
are mapped to topicshard-{shard_number % SHARD_SUBNET_COUNT}
.We use
discv5
to discover peers of select topics, and we usegossipsub
, 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 haveattestation.data.shard == 5
to a peer not subscribed toshard-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 higherlatest_finalized_epoch
or, if epochs are equal, the higherbest_slot
sends a list ofbeacon_block_roots
viasend_beacon_block_roots
. It is assumed that clients store and serve blocks at least as old as the network's current weak-subjectivity period.latest_finalized_root
/epoch
from each peer are in separate chains, then the two peers cannot sync and should terminate connection.latest_finalized_root
/epoch
of 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
: uint64From 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 thelatest_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 thelatest_finalized_root
/epoch
provided by the peer.Beacon Blocks
Supported pubsub topics:
beacon
The following definitions are used in the API:
block_header
: a serializedBeaconBlock
in whichBeaconBlock.body
is thehash_tree_root
of the associatedBeaconBlockBody
.block_body
: a serialiedBeaconBlockBody
.block_root
: thehash_tree_root
of 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_headers
to peer.request_beacon_block_headers(block_root, slot, max_headers, skip_slots)
: Requests theblock_headers
starting 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_headers
headers.send_beacon_block_bodies(block_bodies)
: Sends list ofblock_bodies
to peer.request_beacon_block_bodies(block_roots)
: Requests the associatedblock_bodies
for the givenblock_roots
from peer.Notes:
BeaconBlock
andBeaconBlockBody
can be looked up viablock_root
.request_beacon_block_headers
and 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
shard-{number}
topicsThe following definitions are used in the API:
attestation
: a serializedAttestation
with full serializedAttestationData
forattestation.data
.API:
send_attestations(attestations)
: Sends list ofattestations
to peer.Notes:
beacon
topic orshard-{attestation.data.shard}
topic. Broadcasting to mismatched shard topics is considered bad form.beacon
topic. Repeated broadcasting of attestations with a single signer to thebeacon
topic is considered bad form.attestation.data
to be highly repeated across a committee during a given slot, it could be valuable to just send theattestation
with aroot
in theattestation.data
field. If the recipient does not already have anAttestationData
for 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.data
but increases the rounds of communication when they haven't.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 aBeaconBlock
and (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 ofexits
to peer.Notes:
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
The text was updated successfully, but these errors were encountered: