|
| 1 | +# Engine API. Interop edition |
| 2 | + |
| 3 | +This document specifies a subset of the Engine API methods that are required to be implemented for the Merge interop. |
| 4 | + |
| 5 | +*Note*: Sync API design is yet a draft and considered optional for the interop. |
| 6 | + |
| 7 | +## Underlying protocol |
| 8 | + |
| 9 | +This specification is based on [Ethereum JSON-RPC API](https://eth.wiki/json-rpc/API) and inherits the following properties of this standard: |
| 10 | +* Supported communication protocols (HTTP and WebSocket) |
| 11 | +* Message format and encoding notation |
| 12 | +* [Error codes improvement proposal](https://eth.wiki/json-rpc/json-rpc-error-codes-improvement-proposal) |
| 13 | + |
| 14 | +Client software **MUST** expose Engine API at a port independent from JSON-RPC API. The default port for the Engine API is 8550 for HTTP and 8551 for WebSocket. |
| 15 | + |
| 16 | +## Error codes |
| 17 | + |
| 18 | +The list of error codes introduced by this specification can be found below. |
| 19 | + |
| 20 | +| Code | Possible Return message | Description | |
| 21 | +| - | - | - | |
| 22 | +| 4 | Unknown header | Should be used when a call refers to the unknown header | |
| 23 | +| 5 | Unknown payload | Should be used when the `payloadId` parameter of `engine_getPayload` call refers to a payload building process that is unavailable | |
| 24 | + |
| 25 | +## Structures |
| 26 | + |
| 27 | +Fields having `DATA` and `QUANTITY` types **MUST** be encoded according to the [HEX value encoding](https://eth.wiki/json-rpc/API#hex-value-encoding) section of Ethereum JSON-RPC API. |
| 28 | + |
| 29 | +*Note:* Byte order of encoded value having `QUANTITY` type is big-endian. |
| 30 | + |
| 31 | +### ExecutionPayload |
| 32 | + |
| 33 | +This structure maps on the [`ExecutionPayload`](https://github.com/ethereum/consensus-specs/blob/dev/specs/merge/beacon-chain.md#ExecutionPayload) structure of the beacon chain spec. The fields are encoded as follows: |
| 34 | +- `parentHash`: `DATA`, 32 Bytes |
| 35 | +- `coinbase`: `DATA`, 20 Bytes |
| 36 | +- `stateRoot`: `DATA`, 32 Bytes |
| 37 | +- `receiptRoot`: `DATA`, 32 Bytes |
| 38 | +- `logsBloom`: `DATA`, 256 Bytes |
| 39 | +- `random`: `DATA`, 32 Bytes |
| 40 | +- `blockNumber`: `QUANTITY`, 64 Bits |
| 41 | +- `gasLimit`: `QUANTITY`, 64 Bits |
| 42 | +- `gasUsed`: `QUANTITY`, 64 Bits |
| 43 | +- `timestamp`: `QUANTITY`, 64 Bits |
| 44 | +- `extraData`: `DATA`, 0 to 32 Bytes |
| 45 | +- `baseFeePerGas`: `QUANTITY`, 256 Bits |
| 46 | +- `blockHash`: `DATA`, 32 Bytes |
| 47 | +- `transactions`: `Array of DATA` - Array of transaction objects, each object is a byte list (`DATA`) representing `TransactionType || TransactionPayload` or `LegacyTransaction` as defined in [EIP-2718](https://eips.ethereum.org/EIPS/eip-2718) |
| 48 | + |
| 49 | +## Core |
| 50 | + |
| 51 | +### engine_preparePayload |
| 52 | + |
| 53 | +#### Parameters |
| 54 | +1. `Object` - The payload attributes: |
| 55 | +- `parentHash`: `DATA`, 32 Bytes - hash of the parent block |
| 56 | +- `timestamp`: `QUANTITY`, 64 Bits - value for the `timestamp` field of the new payload |
| 57 | +- `random`: `DATA`, 32 Bytes - value for the `random` field of the new payload |
| 58 | +- `feeRecipient`: `DATA`, 20 Bytes - suggested value for the `coinbase` field of the new payload |
| 59 | + |
| 60 | +#### Returns |
| 61 | +1. `payloadId|Error`: `QUANTITY`, 64 Bits - Identifier of the payload building process |
| 62 | + |
| 63 | +#### Specification |
| 64 | + |
| 65 | +1. Given provided field value set client software **SHOULD** build the initial version of the payload which has an empty transaction set. |
| 66 | + |
| 67 | +2. Client software **SHOULD** start the process of updating the payload. The strategy of this process is implementation dependent. The default strategy would be to keep the transaction set up-to-date with the state of local mempool. |
| 68 | + |
| 69 | +3. Client software **SHOULD** stop the updating process either by finishing to serve the [**`engine_getPayload`**](#engine_getPayload) call with the same `payloadId` value or when [`SECONDS_PER_SLOT`](https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#time-parameters-1) (currently set to 12 in the Mainnet configuration) seconds have passed since the point in time identified by the `timestamp` parameter. |
| 70 | + |
| 71 | +4. Client software **MUST** set the payload field values according to the set of parameters passed in the call to this method with exception for the `feeRecipient`. The `coinbase` field value **MAY** deviate from what is specified by the `feeRecipient` parameter. |
| 72 | + |
| 73 | +5. Client software **SHOULD** respond with `2: Action not allowed` error if the sync process is in progress. |
| 74 | + |
| 75 | +6. Client software **SHOULD** respond with `4: Unknown block` error if the parent block is unknown. |
| 76 | + |
| 77 | +### engine_getPayload |
| 78 | + |
| 79 | +#### Parameters |
| 80 | +1. `payloadId`: `QUANTITY`, 64 Bits - Identifier of the payload building process |
| 81 | + |
| 82 | +#### Returns |
| 83 | +`Object|Error` - Either instance of [`ExecutionPayload`](#ExecutionPayload) or an error |
| 84 | + |
| 85 | +#### Specification |
| 86 | + |
| 87 | +1. Given the `payloadId` client software **MUST** respond with the most recent version of the payload that is available in the corresponding building process at the time of receiving the call. |
| 88 | + |
| 89 | +2. The call **MUST** be responded with `5: Unavailable payload` error if the building process identified by the `payloadId` doesn't exist. |
| 90 | + |
| 91 | +3. Client software **MAY** stop the corresponding building process after serving this call. |
| 92 | + |
| 93 | +### engine_executePayload |
| 94 | + |
| 95 | +#### Parameters |
| 96 | +1. `Object` - Instance of [`ExecutionPayload`](#ExecutionPayload) |
| 97 | + |
| 98 | +#### Returns |
| 99 | +`Object` - Response object: |
| 100 | +1. `status`: `String` - the result of the payload execution: |
| 101 | + - `VALID` - given payload is valid |
| 102 | + - `INVALID` - given payload is invalid |
| 103 | + - `SYNCING` - sync process is in progress |
| 104 | + |
| 105 | +#### Specification |
| 106 | + |
| 107 | +1. Client software **MUST** validate the payload according to the execution environment rule set with modifications to this rule set defined in the [Block Validity](https://eips.ethereum.org/EIPS/eip-3675#block-validity) section of [EIP-3675](https://eips.ethereum.org/EIPS/eip-3675#specification) and respond with the validation result. |
| 108 | + |
| 109 | +2. Client software **MUST** defer persisting a valid payload until the corresponding [**`engine_consensusValidated`**](#engine_consensusValidated) message deems the payload valid with respect to the proof-of-stake consensus rules. |
| 110 | + |
| 111 | +3. Client software **MUST** discard the payload if it's deemed invalid. |
| 112 | + |
| 113 | +4. The call **MUST** be responded with `SYNCING` status while the sync process is in progress and thus the execution cannot yet be validated. |
| 114 | + |
| 115 | +5. In the case when the parent block is unknown, client software **MUST** pull the block from the network and take one of the following actions depending on the parent block properties: |
| 116 | + - If the parent block is a PoW block as per [EIP-3675](https://eips.ethereum.org/EIPS/eip-3675#specification) definition, then all missing dependencies of the payload **MUST** be pulled from the network and validated accordingly. The call **MUST** be responded according to the validity of the payload and the chain of its ancestors. |
| 117 | + - If the parent block is a PoS block as per [EIP-3675](https://eips.ethereum.org/EIPS/eip-3675#specification) definition, then the call **MAY** be responded with `SYNCING` status and sync process **SHOULD** be initiated accordingly. |
| 118 | + |
| 119 | +### engine_consensusValidated |
| 120 | + |
| 121 | +#### Parameters |
| 122 | +1. `Object` - Payload validity status with respect to the consensus rules: |
| 123 | +- `blockHash`: `DATA`, 32 Bytes - block hash value of the payload |
| 124 | +- `status`: `String: VALID|INVALID` - result of the payload validation with respect to the proof-of-stake consensus rules |
| 125 | + |
| 126 | +#### Returns |
| 127 | +None or an error |
| 128 | + |
| 129 | +#### Specification |
| 130 | + |
| 131 | +1. The call of this method with `VALID` status maps on the `POS_CONSENSUS_VALIDATED` event of [EIP-3675](https://eips.ethereum.org/EIPS/eip-3675#specification) and **MUST** be processed according to the specification defined in the EIP. |
| 132 | + |
| 133 | +2. If the status in this call is `INVALID` the payload **MUST** be discarded disregarding its validity with respect to the execution environment rules. |
| 134 | + |
| 135 | +3. Client software **MUST** respond with `4: Unknown block` error if the payload identified by the `blockHash` is unknown. |
| 136 | + |
| 137 | +### engine_forkchoiceUpdated |
| 138 | + |
| 139 | +#### Parameters |
| 140 | +1. `Object` - The state of the fork choice: |
| 141 | +- `headBlockHash`: `DATA`, 32 Bytes - block hash of the head of the canonical chain |
| 142 | +- `finalizedBlockHash`: `DATA`, 32 Bytes - block hash of the most recent finalized block |
| 143 | + |
| 144 | +#### Returns |
| 145 | +None or an error |
| 146 | + |
| 147 | +#### Specification |
| 148 | + |
| 149 | +1. This method call maps on the `POS_FORKCHOICE_UPDATED` event of [EIP-3675](https://eips.ethereum.org/EIPS/eip-3675#specification) and **MUST** be processed according to the specification defined in the EIP. |
| 150 | + |
| 151 | +2. Client software **MUST** respond with `4: Unknown block` error if the payload identified by either the `headBlockHash` or the `finalizedBlockHash` is unknown. |
0 commit comments