Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Minimal Phase 0 Wire API #593

Closed
djrtwo opened this issue Feb 8, 2019 · 2 comments
Closed

Minimal Phase 0 Wire API #593

djrtwo opened this issue Feb 8, 2019 · 2 comments
Labels
general:RFC Request for Comments scope:v-guide Validator guide

Comments

@djrtwo
Copy link
Contributor

djrtwo commented Feb 8, 2019

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 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 most max_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

@djrtwo djrtwo added the general:RFC Request for Comments label Feb 8, 2019
@protolambda
Copy link
Collaborator

protolambda commented Feb 9, 2019

`send_exit(exits)`
`send_attestations(attestations)`

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)?

@djrtwo
Copy link
Contributor Author

djrtwo commented Feb 26, 2019

closing in favor of #692

@djrtwo djrtwo closed this as completed Feb 26, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
general:RFC Request for Comments scope:v-guide Validator guide
Projects
None yet
Development

No branches or pull requests

4 participants
@JustinDrake @djrtwo @protolambda and others