diff --git a/src/engine/specification.md b/src/engine/specification.md index ca355dda8..710427c96 100644 --- a/src/engine/specification.md +++ b/src/engine/specification.md @@ -9,7 +9,6 @@ This document specifies the Engine API methods that the Consensus Layer uses to - [Underlying protocol](#underlying-protocol) - [Versioning](#versioning) -- [Constants](#constants) - [Message ordering](#message-ordering) - [Load-balancing and advanced configurations](#load-balancing-and-advanced-configurations) - [Errors](#errors) @@ -17,8 +16,13 @@ This document specifies the Engine API methods that the Consensus Layer uses to - [ExecutionPayloadV1](#executionpayloadv1) - [ForkchoiceStateV1](#forkchoicestatev1) - [PayloadAttributesV1](#payloadattributesv1) + - [PayloadStatusV1](#payloadstatusv1) +- [Routines](#routines) + - [Payload validation](#payload-validation) + - [Sync](#sync) + - [Payload building](#payload-building) - [Core](#core) - - [engine_executePayloadV1](#engine_executepayloadv1) + - [engine_newPayloadV1](#engine_newpayloadv1) - [Request](#request) - [Response](#response) - [Specification](#specification) @@ -26,7 +30,6 @@ This document specifies the Engine API methods that the Consensus Layer uses to - [Request](#request-1) - [Response](#response-1) - [Specification](#specification-1) - - [Payload build process](#payload-build-process) - [engine_getPayloadV1](#engine_getpayloadv1) - [Request](#request-2) - [Response](#response-2) @@ -37,6 +40,7 @@ This document specifies the Engine API methods that the Consensus Layer uses to ## Underlying protocol This specification is based on [Ethereum JSON-RPC API](https://eth.wiki/json-rpc/API) and inherits the following properties of this standard: + * Supported communication protocols (HTTP and WebSocket) * Message format and encoding notation * [Error codes improvement proposal](https://eth.wiki/json-rpc/json-rpc-error-codes-improvement-proposal) @@ -51,6 +55,7 @@ the client **MUST** also expose the `eth` namespace. ## Versioning The versioning of the Engine API is defined as follows: + * The version of each method and structure is independent from versions of other methods and structures. * The `VX`, where the `X` is the number of the version, is suffixed to the name of each method and structure. * The version of a method or a structure **MUST** be incremented by one if any of the following is changed: @@ -58,7 +63,7 @@ The versioning of the Engine API is defined as follows: * a method response value * a method behavior * a set of structure fields -* The specification **MAY** reference a method or a structure without the version suffix e.g. `engine_executePayload`. These statements should be read as related to all versions of the referenced method or structure. +* The specification **MAY** reference a method or a structure without the version suffix e.g. `engine_newPayload`. These statements should be read as related to all versions of the referenced method or structure. ## Message ordering @@ -76,7 +81,7 @@ Intuitively this is because the Consensus Layer drives the Execution Layer and t On the other hand, generic many-to-one Consensus Layer to Execution Layer configurations are not supported out-of-the-box. The Execution Layer, by default, only supports one chain head at a time and thus has undefined behavior when multiple Consensus Layers simultaneously control the head. The Engine API does work properly, if in such a many-to-one configuration, only one Consensus Layer instantiation is able to *write* to the Execution Layer's chain head and initiate the payload build process (i.e. call `engine_forkchoiceUpdated` ), -while other Consensus Layers can only safely insert payloads (i.e. `engine_executePayload`) and read from the Execution Layer. +while other Consensus Layers can only safely insert payloads (i.e. `engine_newPayload`) and read from the Execution Layer. ## Errors @@ -124,6 +129,7 @@ Fields having `DATA` and `QUANTITY` types **MUST** be encoded according to the [ ### ExecutionPayloadV1 This structure maps on the [`ExecutionPayload`](https://github.com/ethereum/consensus-specs/blob/dev/specs/bellatrix/beacon-chain.md#ExecutionPayload) structure of the beacon chain spec. The fields are encoded as follows: + - `parentHash`: `DATA`, 32 Bytes - `feeRecipient`: `DATA`, 20 Bytes - `stateRoot`: `DATA`, 32 Bytes @@ -142,6 +148,7 @@ This structure maps on the [`ExecutionPayload`](https://github.com/ethereum/cons ### ForkchoiceStateV1 This structure encapsulates the fork choice state. The fields are encoded as follows: + - `headBlockHash`: `DATA`, 32 Bytes - block hash of the head of the canonical chain - `safeBlockHash`: `DATA`, 32 Bytes - the "safe" block hash of the canonical chain under certain synchrony and honesty assumptions. This value **MUST** be either equal to or an ancestor of `headBlockHash` - `finalizedBlockHash`: `DATA`, 32 Bytes - block hash of the most recent finalized block @@ -149,41 +156,95 @@ This structure encapsulates the fork choice state. The fields are encoded as fol ### PayloadAttributesV1 This structure contains the attributes required to initiate a payload build process in the context of an `engine_forkchoiceUpdated` call. The fields are encoded as follows: + - `timestamp`: `QUANTITY`, 64 Bits - value for the `timestamp` field of the new payload - `random`: `DATA`, 32 Bytes - value for the `random` field of the new payload - `suggestedFeeRecipient`: `DATA`, 20 Bytes - suggested value for the `feeRecipient` field of the new payload +### PayloadStatusV1 + +This structure contains the result of processing a payload. The fields are encoded as follows: + +- `status`: `enum` - `"VALID" | "INVALID" | "SYNCING" | "ACCEPTED" | "INVALID_BLOCK_HASH"` +- `latestValidHash`: `DATA|null`, 32 Bytes - the hash of the most recent *valid* block in the branch defined by payload and its ancestors +- `validationError`: `String|null` - a message providing additional details on the validation error if the payload is deemed `INVALID` + +## Routines + +### Payload validation + +Payload validation process consists of validating a payload with respect to the block header and execution environment rule sets. The process is specified as follows: + +1. Client software **MAY** obtain a parent state by executing ancestors of a payload as a part of the validation process. In this case each ancestor **MUST** also pass payload validation process. + +1. Client software **MUST** validate a payload according to the block header and execution environment rule set with modifications to these rule sets 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): + * If validation succeeds, the response **MUST** contain `{status: VALID, latestValidHash: payload.blockHash}` + * If validation fails, the response **MUST** contain `{status: INVALID, latestValidHash: validHash}` where `validHash` is the block hash of the most recent *valid* ancestor of the invalid payload. That is, the valid ancestor of the payload with the highest `blockNumber`. Note that `validHash` may reference a PoW block + * Client software **MUST NOT** surface an `INVALID` payload over any API endpoint and p2p interface. + +1. Client software **MUST** return `-32002: Invalid terminal block` error if the most recent PoW block in the chain of a payload ancestors, that is a PoW block with the highest `blockNumber`, doesn't satisfy terminal block conditions according to [EIP-3675](https://eips.ethereum.org/EIPS/eip-3675#transition-block-validity). This check maps on the Transition block validity section of the EIP. + +1. Client software **MAY** provide additional details on the validation error if a payload is deemed `INVALID` by assigning the corresponding message to the `validationError` field. + +1. The process of validating a payload on the canonical chain **MUST NOT** be affected by an active sync process on a side branch of the block tree. For example, if side branch `B` is `SYNCING` but the requisite data for validating a payload from canonical branch `A` is available, client software **MUST** run full validation of the payload and respond accordingly. + +### Sync + +In the context of this specification, the sync is understood as the process of obtaining data required to validate a payload. The sync process may consist of the following stages: + +1. Pulling data from remote peers in the network. +1. Passing ancestors of a payload through the [Payload validation](#payload-validation) and obtaining a parent state. + +*Note:* Each of these stages is optional. Exact behavior of client software during the sync process is implementation dependent. + +### Payload building + +The payload build process is specified as follows: + +1. Client software **MUST** set the payload field values according to the set of parameters passed into this method with exception of the `suggestedFeeRecipient`. The built `ExecutionPayload` **MAY** deviate the `feeRecipient` field value from what is specified by the `suggestedFeeRecipient` parameter. + +1. Client software **SHOULD** build the initial version of the payload which has an empty transaction set. + +1. Client software **SHOULD** start the process of updating the payload. The strategy of this process is implementation dependent. The default strategy is to keep the transaction set up-to-date with the state of local mempool. + +1. Client software **SHOULD** stop the updating process when either a call to `engine_getPayload` with the build process's `payloadId` is made or [`SECONDS_PER_SLOT`](https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#time-parameters-1) (12s in the Mainnet configuration) have passed since the point in time identified by the `timestamp` parameter. + ## Core -### engine_executePayloadV1 +### engine_newPayloadV1 #### Request -* method: `engine_executePayloadV1` +* method: `engine_newPayloadV1` * params: 1. [`ExecutionPayloadV1`](#ExecutionPayloadV1) #### Response -* result: `object` - - `status`: `enum` - `"VALID" | "INVALID" | "SYNCING"` - - `latestValidHash`: `DATA|null`, 32 Bytes - the hash of the most recent *valid* block in the branch defined by payload and its ancestors - - `validationError`: `String|null` - a message providing additional details on the validation error if the payload is deemed `INVALID` -* error: code and message set in case an exception happens while executing the payload. +* result: [`PayloadStatusV1`](#PayloadStatusV1) +* error: code and message set in case an exception happens while processing the payload. #### Specification -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 return the validation result. - * If validation succeeds, return `{status: VALID, latestValidHash: payload.blockHash}` - * If validation fails, return `{status: INVALID, latestValidHash: validHash}` where `validHash` is the block hash of the most recent *valid* ancestor of the invalid payload. That is, the valid ancestor of the payload with the highest `blockNumber`. +1. Client software **MUST** validate `blockHash` value as being equivalent to `Keccak256(RLP(ExecutionBlockHeader))`, where `ExecutionBlockHeader` is the execution layer block header (the former PoW block header structure). Fields of this object are set to the corresponding payload values and constant values according to the Block structure section of [EIP-3675](https://eips.ethereum.org/EIPS/eip-3675#block-structure), extended with the corresponding section of [EIP-4399](https://eips.ethereum.org/EIPS/eip-4399#block-structure). Client software **MUST** run this validation in all cases even if this branch or any other branches of the block tree are in an active sync process. + +1. Client software **MAY** initiate a sync process if requisite data for payload validation is missing. Sync process is specified in the [Sync](#sync) section. -2. Client software **MUST** discard the payload if it's deemed invalid. +1. Client software **MUST** validate the payload if it extends the canonical chain and requisite data for the validation is locally available. The validation process is specified in the [Payload validation](#payload-validation) section. -3. Client software **MUST** return `{status: SYNCING, latestValidHash: null}` if the sync process is already in progress or if requisite data for payload validation is missing. In the event that requisite data to validate the payload is missing (e.g. does not have payload identified by `parentHash`), the client software **SHOULD** initiate the sync process. +1. Client software **MAY NOT** validate the payload if the payload doesn't belong to the canonical chain. -4. Client software **MAY** provide additional details on the validation error if the payload is deemed `INVALID` by assigning the corresponding message to the `validationError` field. +1. Client software **MUST** respond to this method call in the following way: + * `{status: INVALID_BLOCK_HASH, latestValidHash: null, validationError: null}` if the `blockHash` validation has failed + * `{status: SYNCING, latestValidHash: null, validationError: null}` if the payload extends the canonical chain and requisite data for its validation is missing + * with the payload status obtained from the [Payload validation](#payload-validation) process if the payload has been fully validated while processing the call + * `{status: ACCEPTED, latestValidHash: null, validationError: null}` if the following conditions are met: + - the `blockHash` of the payload is valid + - the payload doesn't extend the canonical chain + - the payload hasn't been fully validated + * with `-32002: Invalid terminal block` error if terminal block conditions aren't met. -5. Client software **MUST** return `-32002: Invalid terminal block` error if the parent block is a PoW block that doesn't satisfy terminal block conditions according to [EIP-3675](https://eips.ethereum.org/EIPS/eip-3675#definitions). This check maps on the Transition block validity section of [EIP-3675](https://eips.ethereum.org/EIPS/eip-3675#transition-block-validity). +1. If any of the above fails due to errors unrelated to the normal processing flow of the method, client software **MUST** respond with an error object. ### engine_forkchoiceUpdatedV1 @@ -197,32 +258,37 @@ This structure contains the attributes required to initiate a payload build proc #### Response * result: `object` - - `status`: `enum` - `"SUCCESS" | "SYNCING"` - - `payloadId`: `DATA|null`, 8 Bytes - identifier of the payload build process or `null` -* error: code and message set in case an exception happens while updating the forkchoice or initiating the payload build process. + - `payloadStatus`: [`PayloadStatusV1`](#PayloadStatusV1); values of the `status` field in the context of this method are restricted to the following subset: + * `"VALID"` + * `"INVALID"` + * `"SYNCING"` + - `payloadId`: `DATA|null`, 8 Bytes - identifier of the payload build process or `null` +* error: code and message set in case an exception happens while the validating payload, updating the forkchoice or initiating the payload build process. #### Specification -1. The values `(forkchoiceState.headBlockHash, forkchoiceState.finalizedBlockHash)` of this method call map 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. +1. Client software **MAY** initiate a sync process if `forkchoiceState.headBlockHash` references an unknown payload or a payload that can't be validated because data that are requisite for the validation is missing. The sync process is specified in the [Sync](#sync) section. -2. All updates to the forkchoice state resulting from this call **MUST** be made atomically. +1. Client software **MAY** skip an update of the forkchoice state and **MUST NOT** begin a payload build process if `forkchoiceState.headBlockHash` doesn't reference a leaf of the block tree. That is, the block referenced by `forkchoiceState.headBlockHash` is neither the head of the canonical chain nor a block at the tip of any other chain. -3. Client software **MUST** return `{status: SUCCESS, payloadId: null}` if `payloadAttributes` is `null` and the client is not `SYNCING`. +1. Client software **MUST** return `-32002: Invalid terminal block` error if `forkchoiceState.headBlockHash` references a PoW block that doesn't satisfy terminal block conditions according to [EIP-3675](https://eips.ethereum.org/EIPS/eip-3675#definitions). This check maps to the transition block validity section of the EIP. -4. Client software **MUST** return `{status: SYNCING, payloadId: null}` if the payload identified by either the `forkchoiceState.headBlockHash` or the `forkchoiceState.finalizedBlockHash` is unknown or if the sync process is in progress. In the event that either the `forkchoiceState.headBlockHash` or the `forkchoiceState.finalizedBlockHash` is unknown, the client software **SHOULD** initiate the sync process. +1. Before updating the forkchoice state, client software **MUST** ensure the validity of the payload referenced by `forkchoiceState.headBlockHash`, and **MAY** validate the payload while processing the call. The validation process is specified in the [Payload validation](#payload-validation) section. -5. Client software **MUST** return `{status: SUCCESS, payloadId: buildProcessId}` if `payloadAttributes` is not `null` and the client is not `SYNCING`, and **MUST** begin a payload build process building on top of `forkchoiceState.headBlockHash` and identified via `buildProcessId` value. The build process is specified in the [Payload build process](#payload-build-process) section. +1. Client software **MUST** update its forkchoice state if payloads referenced by `forkchoiceState.headBlockHash` and `forkchoiceState.finalizedBlockHash` are `VALID`. The update is specified as follows: + * The values `(forkchoiceState.headBlockHash, forkchoiceState.finalizedBlockHash)` of this method call map on the `POS_FORKCHOICE_UPDATED` event of [EIP-3675](https://eips.ethereum.org/EIPS/eip-3675#block-validity) and **MUST** be processed according to the specification defined in the EIP + * All updates to the forkchoice state resulting from this call **MUST** be made atomically. -6. Client software **MUST** return `-32002: Invalid terminal block` error if a block referenced by `forkchoiceState.headBlockHash` is a PoW block that doesn't satisfy terminal block conditions according to [EIP-3675](https://eips.ethereum.org/EIPS/eip-3675#definitions). +1. Client software **MUST** begin a payload build process building on top of `forkchoiceState.headBlockHash` and identified via `buildProcessId` value if `payloadAttributes` is not `null` and the forkchoice state has been updated successfully. The build process is specified in the [Payload building](#payload-building) section. -7. If any of the above fails due to errors unrelated to the client software's normal `SYNCING` status, the client software **MUST** return an error. +1. Client software **MUST** respond to this method call in the following way: + * `{payloadStatus: {status: SYNCING, latestValidHash: null, validationError: null}, payloadId: null}` if `forkchoiceState.headBlockHash` references an unknown payload or a payload that can't be validated because requisite data for the validation is missing + * `{payloadStatus: {status: INVALID, latestValidHash: null, validationError: errorMessage | null}, payloadId: null}` obtained from the [Payload validation](#payload-validation) process if the payload is deemed `INVALID` + * `{payloadStatus: {status: VALID, latestValidHash: forkchoiceState.headBlockHash, validationError: null}, payloadId: null}` if the payload is deemed `VALID` and a build process hasn't been started + * `{payloadStatus: {status: VALID, latestValidHash: forkchoiceState.headBlockHash, validationError: null}, payloadId: buildProcessId}` if the payload is deemed `VALID` and the build process has begun + * with `-32002: Invalid terminal block` error if terminal block conditions aren't met -##### Payload build process -The payload build process is specified as follows: -* Client software **MUST** set the payload field values according to the set of parameters passed into this method with exception of the `suggestedFeeRecipient`. The built `ExecutionPayload` **MAY** deviate the `feeRecipient` field value from what is specified by the `suggestedFeeRecipient` parameter. -* Client software **SHOULD** build the initial version of the payload which has an empty transaction set. -* Client software **SHOULD** start the process of updating the payload. The strategy of this process is implementation dependent. The default strategy is to keep the transaction set up-to-date with the state of local mempool. -* Client software **SHOULD** stop the updating process when either a call to `engine_getPayload` with the build process's `payloadId` is made or [`SECONDS_PER_SLOT`](https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#time-parameters-1) (12s in the Mainnet configuration) have passed since the point in time identified by the `timestamp` parameter. +1. If any of the above fails due to errors unrelated to the normal processing flow of the method, client software **MUST** respond with an error object. ### engine_getPayloadV1 @@ -241,6 +307,6 @@ The payload build process is specified as follows: 1. Given the `payloadId` client software **MUST** return the most recent version of the payload that is available in the corresponding build process at the time of receiving the call. -2. The call **MUST** return `-32001: Unknown payload` error if the build process identified by the `payloadId` does not exist. +1. The call **MUST** return `-32001: Unknown payload` error if the build process identified by the `payloadId` does not exist. -3. Client software **MAY** stop the corresponding build process after serving this call. +1. Client software **MAY** stop the corresponding build process after serving this call. diff --git a/wordlist.txt b/wordlist.txt index d372d3132..abe57d601 100644 --- a/wordlist.txt +++ b/wordlist.txt @@ -21,6 +21,7 @@ rpc schemas secp statev +statusv sha uint updatedv