This document specifies the Engine API methods that the Consensus Layer uses to interact with the Execution Layer.
- Underlying protocol
- Versioning
- Message ordering
- Load-balancing and advanced configurations
- Errors
- Structures
- Routines
- Core
This specification is based on Ethereum 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
Client software MUST expose Engine API at a port independent from JSON-RPC API.
The default port for the Engine API is 8550.
The Engine API is exposed under the engine
namespace.
To facilitate an Engine API consumer to access state and logs (e.g. proof-of-stake deposits) through the same connection,
the client MUST also expose the eth
namespace.
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 theX
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:
- a set of method parameters
- 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_newPayload
. These statements should be read as related to all versions of the referenced method or structure.
Consensus Layer client software MUST respect the order of the corresponding fork choice update events
when making calls to the engine_forkchoiceUpdated
method.
Execution Layer client software MUST process engine_forkchoiceUpdated
method calls
in the same order as they have been received.
The Engine API supports a one-to-many Consensus Layer to Execution Layer configuration. Intuitively this is because the Consensus Layer drives the Execution Layer and thus can drive many of them independently.
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_newPayload
) and read from the Execution Layer.
The list of error codes introduced by this specification can be found below.
Code | Message | Meaning |
---|---|---|
-32700 | Parse error | Invalid JSON was received by the server. |
-32600 | Invalid Request | The JSON sent is not a valid Request object. |
-32601 | Method not found | The method does not exist / is not available. |
-32602 | Invalid params | Invalid method parameter(s). |
-32603 | Internal error | Internal JSON-RPC error. |
-32000 | Server error | Generic client error while processing request. |
-32001 | Unknown payload | Payload does not exist / is not available. |
Each error returns a null
data
value, except -32000
which returns the data
object with a err
member that explains the error encountered.
For example:
$ curl https://localhost:8550 \
-X POST \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"engine_getPayloadV1","params": ["0x1"],"id":1}'
{
"jsonrpc": "2.0",
"id": 1,
"error": {
"code": -32000,
"message": "Server error",
"data": {
"err": "Database corrupted"
}
}
}
Fields having DATA
and QUANTITY
types MUST be encoded according to the HEX value encoding section of Ethereum JSON-RPC API.
Note: Byte order of encoded value having QUANTITY
type is big-endian.
This structure maps on the ExecutionPayload
structure of the beacon chain spec. The fields are encoded as follows:
parentHash
:DATA
, 32 BytesfeeRecipient
:DATA
, 20 BytesstateRoot
:DATA
, 32 BytesreceiptsRoot
:DATA
, 32 ByteslogsBloom
:DATA
, 256 BytesprevRandao
:DATA
, 32 BytesblockNumber
:QUANTITY
, 64 BitsgasLimit
:QUANTITY
, 64 BitsgasUsed
:QUANTITY
, 64 Bitstimestamp
:QUANTITY
, 64 BitsextraData
:DATA
, 0 to 32 BytesbaseFeePerGas
:QUANTITY
, 256 BitsblockHash
:DATA
, 32 Bytestransactions
:Array of DATA
- Array of transaction objects, each object is a byte list (DATA
) representingTransactionType || TransactionPayload
orLegacyTransaction
as defined in EIP-2718
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 chainsafeBlockHash
: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 ofheadBlockHash
finalizedBlockHash
:DATA
, 32 Bytes - block hash of the most recent finalized block
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 thetimestamp
field of the new payloadprevRandao
:DATA
, 32 Bytes - value for theprevRandao
field of the new payloadsuggestedFeeRecipient
:DATA
, 20 Bytes - suggested value for thefeeRecipient
field of the new payload
This structure contains the result of processing a payload. The fields are encoded as follows:
status
:enum
-"VALID" | "INVALID" | "SYNCING" | "ACCEPTED" | "INVALID_BLOCK_HASH" | "INVALID_TERMINAL_BLOCK"
latestValidHash
:DATA|null
, 32 Bytes - the hash of the most recent valid block in the branch defined by payload and its ancestorsvalidationError
:String|null
- a message providing additional details on the validation error if the payload is classified asINVALID
,INVALID_BLOCK_HASH
orINVALID_TERMINAL_BLOCK.
This structure contains configurable settings of the transition process. The fields are encoded as follows:
terminalTotalDifficulty
:QUANTITY
, 256 Bits - maps on theTERMINAL_TOTAL_DIFFICULTY
parameter of EIP-3675terminalBlockHash
:DATA
, 32 Bytes - maps onTERMINAL_BLOCK_HASH
parameter of EIP-3675terminalBlockNumber
:QUANTITY
, 64 Bits - maps onTERMINAL_BLOCK_NUMBER
parameter of EIP-3675
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:
-
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.
-
Client software MUST validate that the most recent PoW block in the chain of a payload ancestors satisfies terminal block conditions according to EIP-3675. This check maps to the transition block validity section of the EIP. If this validation fails, the response MUST contain
{status: INVALID_TERMINAL_BLOCK, latestValidHash: null}
. Additionally, each block in a tree of descendants of an invalid terminal block MUST be deemedINVALID
. -
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 section of EIP-3675:
- If validation succeeds, the response MUST contain
{status: VALID, latestValidHash: payload.blockHash}
- If validation fails, the response MUST contain
{status: INVALID, latestValidHash: validHash}
wherevalidHash
is the block hash of the most recent valid ancestor of the invalid payload. That is, the valid ancestor of the payload with the highestblockNumber
- Client software MUST NOT surface an
INVALID
payload over any API endpoint and p2p interface.
-
Client software MAY provide additional details on the validation error if a payload is deemed
INVALID
by assigning the corresponding message to thevalidationError
field. -
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
isSYNCING
but the requisite data for validating a payload from canonical branchA
is available, client software MUST run full validation of the payload and respond accordingly.
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:
- Pulling data from remote peers in the network.
- Passing ancestors of a payload through the 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.
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 builtExecutionPayload
MAY deviate thefeeRecipient
field value from what is specified by thesuggestedFeeRecipient
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'spayloadId
is made orSECONDS_PER_SLOT
(12s in the Mainnet configuration) have passed since the point in time identified by thetimestamp
parameter.
- method:
engine_newPayloadV1
- params:
- result:
PayloadStatusV1
- error: code and message set in case an exception happens while processing the payload.
-
Client software MUST validate
blockHash
value as being equivalent toKeccak256(RLP(ExecutionBlockHeader))
, whereExecutionBlockHeader
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, extended with the corresponding section of EIP-4399. 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. -
Client software MAY initiate a sync process if requisite data for payload validation is missing. Sync process is specified in the Sync section.
-
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 section.
-
Client software MAY NOT validate the payload if the payload doesn't belong to the canonical chain.
-
Client software MUST respond to this method call in the following way:
{status: INVALID_BLOCK_HASH, latestValidHash: null, validationError: errorMessage | null}
if theblockHash
validation has failed{status: INVALID_TERMINAL_BLOCK, latestValidHash: null, validationError: errorMessage | null}
if terminal block conditions are not satisfied{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 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.
- the
- 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.
- method: "engine_forkchoiceUpdatedV1"
- params:
forkchoiceState
:Object
- instance ofForkchoiceStateV1
payloadAttributes
:Object|null
- instance ofPayloadAttributesV1
ornull
- result:
object
payloadStatus
:PayloadStatusV1
; values of thestatus
field in the context of this method are restricted to the following subset:"VALID"
"INVALID"
"SYNCING"
"INVALID_TERMINAL_BLOCK"
payloadId
:DATA|null
, 8 Bytes - identifier of the payload build process ornull
- error: code and message set in case an exception happens while the validating payload, updating the forkchoice or initiating the payload build process.
-
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 section. -
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 byforkchoiceState.headBlockHash
is neither the head of the canonical chain nor a block at the tip of any other chain. -
If
forkchoiceState.headBlockHash
references a PoW block, client software MUST validate this block with respect to terminal block conditions according to EIP-3675. This check maps to the transition block validity section of the EIP. Additionally, if this validation fails, client software MUST NOT update the forkchoice state and MUST NOT begin a payload build process. -
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 section. -
Client software MUST update its forkchoice state if payloads referenced by
forkchoiceState.headBlockHash
andforkchoiceState.finalizedBlockHash
areVALID
. The update is specified as follows:
- The values
(forkchoiceState.headBlockHash, forkchoiceState.finalizedBlockHash)
of this method call map on thePOS_FORKCHOICE_UPDATED
event of EIP-3675 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.
-
Client software MUST begin a payload build process building on top of
forkchoiceState.headBlockHash
and identified viabuildProcessId
value ifpayloadAttributes
is notnull
and the forkchoice state has been updated successfully. The build process is specified in the Payload building section. -
Client software MUST respond to this method call in the following way:
{payloadStatus: {status: SYNCING, latestValidHash: null, validationError: null}, payloadId: null}
ifforkchoiceState.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: validHash, validationError: errorMessage | null}, payloadId: null}
obtained from the Payload validation process if the payload is deemedINVALID
{payloadStatus: {status: INVALID_TERMINAL_BLOCK, latestValidHash: null, validationError: errorMessage | null}, payloadId: null}
obtained either from the Payload validation process or as a result of validating a PoW block referenced byforkchoiceState.headBlockHash
{payloadStatus: {status: VALID, latestValidHash: forkchoiceState.headBlockHash, validationError: null}, payloadId: null}
if the payload is deemedVALID
and a build process hasn't been started{payloadStatus: {status: VALID, latestValidHash: forkchoiceState.headBlockHash, validationError: null}, payloadId: buildProcessId}
if the payload is deemedVALID
and the build process has begun.
- 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.
- method:
engine_getPayloadV1
- params:
payloadId
:DATA
, 8 Bytes - Identifier of the payload build process
- result:
ExecutionPayloadV1
- error: code and message set in case an exception happens while getting the payload.
-
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. -
The call MUST return
-32001: Unknown payload
error if the build process identified by thepayloadId
does not exist. -
Client software MAY stop the corresponding build process after serving this call.
- method:
engine_exchangeTransitionConfigurationV1
- params:
transitionConfiguration
:Object
- instance ofTransitionConfigurationV1
;terminalBlockNumber
MUST be set to0
- result:
TransitionConfigurationV1
- error: code and message set in case an exception happens while getting a transition configuration.
-
Execution Layer client software MUST respond with configurable setting values that are set according to the Client software configuration section of EIP-3675.
-
Execution Layer client software SHOULD surface an error to the user if local configuration settings mismatch corresponding values received in the call of this method, with exception for
terminalBlockNumber
value. -
Consensus Layer client software SHOULD surface an error to the user if local configuration settings mismatch corresponding values obtained from the response to the call of this method.