rpc-interface.md
1 ETH 2.0 Networking Spec - RPC Interface 2 === 3 4 # Abstract 5 6 The Ethereum 2.0 networking stack uses two modes of communication: a broadcast protocol that gossips information to interested parties via GossipSub, and an RPC protocol that retrieves information from specific clients. This specification defines the RPC protocol. 7 8 The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL", NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119. 9 10 # Dependencies 11 12 This specification assumes familiarity with the [Messaging](./messaging.md), [Node Identification](./node-identification.md), and [Beacon Chain](../core/0_beacon-chain.md) specifications. 13 14 # Specification 15 16 ## Message Schemas 17 18 Message body schemas are notated like this: 19 20 ``` 21 ( 22 field_name_1: type 23 field_name_2: type 24 ) 25 ``` 26 27 Embedded types are serialized as SSZ Containers unless otherwise noted. 28 29 All referenced data structures can be found in the [0-beacon-chain](../core/0_beacon-chain.md#data-structures) specification. 30 31 ## `libp2p` Protocol Names 32 33 A "Protocol ID" in `libp2p` parlance refers to a human-readable identifier `libp2p` uses in order to identify sub-protocols and stream messages of different types over the same connection. Peers exchange supported protocol IDs via the `Identify` protocol upon connection. When opening a new stream, peers pin a particular protocol ID to it, and the stream remains contextualised thereafter. Since messages are sent inside a stream, they do not need to bear the protocol ID. 34 35 ## RPC-Over-`libp2p` 36 37 To facilitate RPC-over-`libp2p`, a single protocol name is used: `/eth/serenity/beacon/rpc/1`. The version number in the protocol name is neither backwards or forwards compatible, and will be incremented whenever changes to the below structures are required. 38 39 Remote method calls are wrapped in a "request" structure: 40 41 ``` 42 ( 43 id: uint64 44 method_id: uint16 45 body: Request 46 ) 47 ``` 48 49 and their corresponding responses are wrapped in a "response" structure: 50 51 ``` 52 ( 53 id: uint64 54 response_code: uint16 55 result: bytes 56 ) 57 ``` 58 59 If an error occurs, a variant of the response structure is returned: 60 61 ``` 62 ( 63 id: uint64 64 response_code: uint16 65 result: bytes 66 ) 67 ``` 68 69 The details of the RPC-Over-`libp2p` protocol are similar to [JSON-RPC 2.0](https://www.jsonrpc.org/specification). Specifically: 70 71 1. The `id` member is REQUIRED. 72 2. The `id` member in the response MUST be the same as the value of the `id` in the request. 73 3. The `id` member MUST be unique within the context of a single connection. Monotonically increasing `id`s are RECOMMENDED. 74 4. The `method_id` member is REQUIRED. 75 5. The `result` member is REQUIRED on success. 76 6. The `result` member is OPTIONAL on errors, and MAY contain additional information about the error. 77 7. `response_code` MUST be `0` on success. 78 79 Structuring RPC requests in this manner allows multiple calls and responses to be multiplexed over the same stream without switching. Note that this implies that responses MAY arrive in a different order than requests. 80 81 The "method ID" fields in the below messages refer to the `method` field in the request structure above. 82 83 The first 1,000 values in `response_code` are reserved for system use. The following response codes are predefined: 84 85 1. `0`: No error. 86 2. `10`: Parse error. 87 2. `20`: Invalid request. 88 3. `30`: Method not found. 89 4. `40`: Server error. 90 91 ### Alternative for Non-`libp2p` Clients 92 93 Since some clients are waiting for `libp2p` implementations in their respective languages. As such, they MAY listen for raw TCP messages on port `9000`. To distinguish RPC messages from other messages on that port, a byte prefix of `ETH` (`0x455448`) MUST be prepended to all messages. This option will be removed once `libp2p` is ready in all supported languages. 94 95 ## Messages 96 97 ### Hello 98 99 **Method ID:** `0` 100 101 **Body**: 102 103 ``` 104 ( 105 network_id: uint8 106 chain_id: uint64 107 latest_finalized_root: bytes32 108 latest_finalized_epoch: uint64 109 best_root: bytes32 110 best_slot: uint64 111 ) 112 ``` 113 114 Clients exchange `hello` messages upon connection, forming a two-phase handshake. The first message the initiating client sends MUST be the `hello` message. In response, the receiving client MUST respond with its own `hello` message. 115 116 Clients SHOULD immediately disconnect from one another following the handshake above under the following conditions: 117 118 1. If `network_id` belongs to a different chain, since the client definitionally cannot sync with this client. 119 2. If the `latest_finalized_root` shared by the peer is not in the client's chain at the expected epoch. For example, if Peer 1 in the diagram below has `(root, epoch)` of `(A, 5)` and Peer 2 has `(B, 3)`, Peer 1 would disconnect because it knows that `B` is not the root in their chain at epoch 3: 120 121 ``` 122 Root A 123 124 +---+ 125 |xxx| +----+ Epoch 5 126 +-+-+ 127 ^ 128 | 129 +-+-+ 130 | | +----+ Epoch 4 131 +-+-+ 132 Root B ^ 133 | 134 +---+ +-+-+ 135 |xxx+<---+--->+ | +----+ Epoch 3 136 +---+ | +---+ 137 | 138 +-+-+ 139 | | +-----------+ Epoch 2 140 +-+-+ 141 ^ 142 | 143 +-+-+ 144 | | +-----------+ Epoch 1 145 +---+ 146 ``` 147 148 Once the handshake completes, the client with the higher `latest_finalized_epoch` or `best_slot` (if the clients have equal `latest_finalized_epoch`s) SHOULD request beacon block roots from its counterparty via `beacon_block_roots` (i.e., RPC method `10`). 149 150 ### Goodbye 151 152 **Method ID:** `1` 153 154 **Body:** 155 156 ``` 157 ( 158 reason: uint64 159 ) 160 ``` 161 162 Client MAY send `goodbye` messages upon disconnection. The reason field MAY be one of the following values: 163 164 - `1`: Client shut down. 165 - `2`: Irrelevant network. 166 - `3`: Fault/error. 167 168 Clients MAY define custom goodbye reasons as long as the value is larger than `1000`. 169 170 ### Get Status 171 172 **Method ID:** `2` 173 174 **Request Body:** 175 176 ``` 177 ( 178 sha: bytes32 179 user_agent: bytes 180 timestamp: uint64 181 ) 182 ``` 183 184 **Response Body:** 185 186 ``` 187 ( 188 sha: bytes32 189 user_agent: bytes 190 timestamp: uint64 191 ) 192 ``` 193 194 Returns metadata about the remote node. 195 196 ### Request Beacon Block Roots 197 198 **Method ID:** `10` 199 200 **Request Body** 201 202 ``` 203 ( 204 start_slot: uint64 205 count: uint64 206 ) 207 ``` 208 209 **Response Body:** 210 211 ``` 212 # BlockRootSlot 213 ( 214 block_root: bytes32 215 slot: uint64 216 ) 217 218 ( 219 roots: []BlockRootSlot 220 ) 221 ``` 222 223 Requests a list of block roots and slots from the peer. The `count` parameter MUST be less than or equal to `32768`. The slots MUST be returned in ascending slot order. 224 225 ### Beacon Block Headers 226 227 **Method ID:** `11` 228 229 **Request Body** 230 231 ``` 232 ( 233 start_root: HashTreeRoot 234 start_slot: uint64 235 max_headers: uint64 236 skip_slots: uint64 237 ) 238 ``` 239 240 **Response Body:** 241 242 ``` 243 ( 244 headers: []BeaconBlockHeader 245 ) 246 ``` 247 248 Requests beacon block headers from the peer starting from `(start_root, start_slot)`. The response MUST contain no more than `max_headers` headers. `skip_slots` defines the maximum number of slots to skip between blocks. For example, requesting blocks starting at slots `2` a `skip_slots` value of `1` would return the blocks at `[2, 4, 6, 8, 10]`. In cases where a slot is empty for a given slot number, the closest previous block MUST be returned. For example, if slot `4` were empty in the previous example, the returned array would contain `[2, 3, 6, 8, 10]`. If slot three were further empty, the array would contain `[2, 6, 8, 10]` - i.e., duplicate blocks MUST be collapsed. A `skip_slots` value of `0` returns all blocks. 249 250 The function of the `skip_slots` parameter helps facilitate light client sync - for example, in [#459](https://github.com/ethereum/eth2.0-specs/issues/459) - and allows clients to balance the peers from whom they request headers. Clients could, for instance, request every 10th block from a set of peers where each peer has a different starting block in order to populate block data. 251 252 ### Beacon Block Bodies 253 254 **Method ID:** `12` 255 256 **Request Body:** 257 258 ``` 259 ( 260 block_roots: []HashTreeRoot 261 ) 262 ``` 263 264 **Response Body:** 265 266 ``` 267 ( 268 block_bodies: []BeaconBlockBody 269 ) 270 ``` 271 272 Requests the `block_bodies` associated with the provided `block_roots` from the peer. Responses MUST return `block_roots` in the order provided in the request. If the receiver does not have a particular `block_root`, it must return a zero-value `block_body` (i.e., a `block_body` container with all zero fields). 273 274 ### Beacon Chain State 275 276 **Note:** This section is preliminary, pending the definition of the data structures to be transferred over the wire during fast sync operations. 277 278 **Method ID:** `13` 279 280 **Request Body:** 281 282 ``` 283 ( 284 hashes: []HashTreeRoot 285 ) 286 ``` 287 288 **Response Body:** TBD 289 290 Requests contain the hashes of Merkle tree nodes that when merkleized yield the block's `state_root`. 291 292 The response will contain the values that, when hashed, yield the hashes inside the request body.