Module that facilitates communication between consensus and execution layers
This document specifies the internal x/evmengine
module of the Story blockchain.
As Story Network separates the consensus and execution client, like Ethereum, the consensus client (CL) and execution client (EL) needs to communicate to sync to the network, propose proper EVM blocks, and execute EVM-triggered EL actions in CL.
The module exists to facilitate all communications between CL and EL using the Engine API, from staking and upgrades to driving block production and consensus in CL and EL.
Type: time.Duration
Build delay determines the wait duration from the start of PrepareProposal
ABCI2 call before fetching the next EVM block data to propose from EL via the Engine API. Applicable to the current proposer only. If the node has a block optimistically built beforehand, the build delay is not used.
Type: bool
Enable optimistic building of a block if true. A node will deterministically build the next block if it finds itself as the next proposer in the current block. Optimistic building starts with requesting the next EVM block data (for the next CL block) immediately after the FinalizeBlock
of ABCI2.
Type: ExecutionHeadTable
Head table stores the latest execution head data to be used for partial validation of EVM blocks received from other validators. When the chain initializes, the execution head is populated with the genesis execution hash loaded from genesis.json
.
The following execution head is stored in the table.
Type: *bindings.UpgradeEntrypoint
Upgrade contract is used to filter and parse upgrade-related events from EL.
Type: *bindings.UBIPool
UBI contract is used to filter and parse UBI-related events from EL.
Type: struct
Mutable payload stores the optimistic block built, if optimistic building is enabled.
The module’s GenesisState
defines the state necessary for initializing the chain from a previously exported height.
At each block, if the node is the proposer, ABCI2 triggers PrepareProposal
which
MsgExecutionPayload
with the built EVM block and previous EVM logs.MsgExecutionPayload
data.This CL block is then propagated to all other validators.
At each block, if the node is not a proposer but a validator, ABCI2 triggers ProcessProposal
with received commits (which should be a transaction of MsgExecutionPayload
data in the honest case).
The node first validates that the received commit has only one transaction with at least 2/3 of votes committed. Then, the node validates that the one transaction only contains one unmarshalled MsgExecutionPayload
data. Finally, the node processes the received data and broadcasts its acceptance of the proposal to the network. If any of the validation or processing fails, the node rejects the proposal.
More specifically, the node processes the received MsgExecutionPayload
data in the following manner:
MsgExecutionPayload
(outlined in Messages).If optimistic building is enabled, PostFinalize
is triggered immediately after FinalizeBlock
set through custom ABCI callback. During this process, the node peeks the staking and reward queues from the evmstaking module, and builds a new execution payload on top of the current execution head. It sets the optimistic block to be used in the next block’s PrepareProposal
phase and returns the response from the forkchoice update.
In this section we describe the processing of the evmengine messages and the corresponding updates to the state. All created/modified state objects specified by each message are defined within the state section.
This message is expected to fail if:
Withdrawals
, BlobGasUsed
, and ExcessBlobGas
fields are nilWithdrawals
count does not match local node’s sum of dequeued stake & reward withdrawalsThe message must contain previous block’s events, which gets processed at the current CL block (in other words, execution events from EL block n-1 are processed at CL block n). In the future, the message will remove prev_payload_events
and rely on Engine API to get the current finalized EL block’s events.
Also note that EVM events are processed in CL in the order they are generated in EL.
All UBI-related changes must be triggered from the canonical UBI contract in the EVM execution layer. This module handles the execution handling of those triggers in CL. Read more about UBI for validators
The UBIPool
contract emits the UBI distribution set event, which is parsed by the module to set the UBI percentage in the distribution module.
All chain upgrade-related logics must be triggered from the canonical upgrade contract in the EVM execution layer. This module handles the execution handling of those triggers in CL.
The UpgradeEntrypoint
contract emits the software upgrade event, which is parsed by the module to schedule an upgrade at a given height for a given binary name. Currently, all upgrades must either be set via forks or by the software upgrade events; the latter process is a multisig-controlled process, which will transition into a voting-based process in the future.
Similar to the software upgrade, the module processes the cancel upgrade event from EVM logs of the previous block, and clears an existing upgrade plan.
Module that facilitates communication between consensus and execution layers
This document specifies the internal x/evmengine
module of the Story blockchain.
As Story Network separates the consensus and execution client, like Ethereum, the consensus client (CL) and execution client (EL) needs to communicate to sync to the network, propose proper EVM blocks, and execute EVM-triggered EL actions in CL.
The module exists to facilitate all communications between CL and EL using the Engine API, from staking and upgrades to driving block production and consensus in CL and EL.
Type: time.Duration
Build delay determines the wait duration from the start of PrepareProposal
ABCI2 call before fetching the next EVM block data to propose from EL via the Engine API. Applicable to the current proposer only. If the node has a block optimistically built beforehand, the build delay is not used.
Type: bool
Enable optimistic building of a block if true. A node will deterministically build the next block if it finds itself as the next proposer in the current block. Optimistic building starts with requesting the next EVM block data (for the next CL block) immediately after the FinalizeBlock
of ABCI2.
Type: ExecutionHeadTable
Head table stores the latest execution head data to be used for partial validation of EVM blocks received from other validators. When the chain initializes, the execution head is populated with the genesis execution hash loaded from genesis.json
.
The following execution head is stored in the table.
Type: *bindings.UpgradeEntrypoint
Upgrade contract is used to filter and parse upgrade-related events from EL.
Type: *bindings.UBIPool
UBI contract is used to filter and parse UBI-related events from EL.
Type: struct
Mutable payload stores the optimistic block built, if optimistic building is enabled.
The module’s GenesisState
defines the state necessary for initializing the chain from a previously exported height.
At each block, if the node is the proposer, ABCI2 triggers PrepareProposal
which
MsgExecutionPayload
with the built EVM block and previous EVM logs.MsgExecutionPayload
data.This CL block is then propagated to all other validators.
At each block, if the node is not a proposer but a validator, ABCI2 triggers ProcessProposal
with received commits (which should be a transaction of MsgExecutionPayload
data in the honest case).
The node first validates that the received commit has only one transaction with at least 2/3 of votes committed. Then, the node validates that the one transaction only contains one unmarshalled MsgExecutionPayload
data. Finally, the node processes the received data and broadcasts its acceptance of the proposal to the network. If any of the validation or processing fails, the node rejects the proposal.
More specifically, the node processes the received MsgExecutionPayload
data in the following manner:
MsgExecutionPayload
(outlined in Messages).If optimistic building is enabled, PostFinalize
is triggered immediately after FinalizeBlock
set through custom ABCI callback. During this process, the node peeks the staking and reward queues from the evmstaking module, and builds a new execution payload on top of the current execution head. It sets the optimistic block to be used in the next block’s PrepareProposal
phase and returns the response from the forkchoice update.
In this section we describe the processing of the evmengine messages and the corresponding updates to the state. All created/modified state objects specified by each message are defined within the state section.
This message is expected to fail if:
Withdrawals
, BlobGasUsed
, and ExcessBlobGas
fields are nilWithdrawals
count does not match local node’s sum of dequeued stake & reward withdrawalsThe message must contain previous block’s events, which gets processed at the current CL block (in other words, execution events from EL block n-1 are processed at CL block n). In the future, the message will remove prev_payload_events
and rely on Engine API to get the current finalized EL block’s events.
Also note that EVM events are processed in CL in the order they are generated in EL.
All UBI-related changes must be triggered from the canonical UBI contract in the EVM execution layer. This module handles the execution handling of those triggers in CL. Read more about UBI for validators
The UBIPool
contract emits the UBI distribution set event, which is parsed by the module to set the UBI percentage in the distribution module.
All chain upgrade-related logics must be triggered from the canonical upgrade contract in the EVM execution layer. This module handles the execution handling of those triggers in CL.
The UpgradeEntrypoint
contract emits the software upgrade event, which is parsed by the module to schedule an upgrade at a given height for a given binary name. Currently, all upgrades must either be set via forks or by the software upgrade events; the latter process is a multisig-controlled process, which will transition into a voting-based process in the future.
Similar to the software upgrade, the module processes the cancel upgrade event from EVM logs of the previous block, and clears an existing upgrade plan.