Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: wire SystemCaller #11321

Merged
merged 9 commits into from
Sep 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 4 additions & 20 deletions crates/engine/invalid-block-hooks/src/witness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,7 @@ use eyre::OptionExt;
use pretty_assertions::Comparison;
use reth_chainspec::{EthChainSpec, EthereumHardforks};
use reth_engine_primitives::InvalidBlockHook;
use reth_evm::{
system_calls::{apply_beacon_root_contract_call, apply_blockhashes_contract_call},
ConfigureEvm,
};
use reth_evm::{system_calls::SystemCaller, ConfigureEvm};
use reth_primitives::{Header, Receipt, SealedBlockWithSenders, SealedHeader};
use reth_provider::{BlockExecutionOutput, ChainSpecProvider, StateProviderFactory};
use reth_revm::{
Expand Down Expand Up @@ -87,23 +84,10 @@ where
EnvWithHandlerCfg::new_with_cfg_env(cfg, block_env, Default::default()),
);

let mut system_caller = SystemCaller::new(&self.evm_config, self.provider.chain_spec());

// Apply pre-block system contract calls.
apply_beacon_root_contract_call(
&self.evm_config,
self.provider.chain_spec().as_ref(),
block.timestamp,
block.number,
block.parent_beacon_block_root,
&mut evm,
)?;
apply_blockhashes_contract_call(
&self.evm_config,
&self.provider.chain_spec(),
block.timestamp,
block.number,
block.parent_hash,
&mut evm,
)?;
system_caller.apply_pre_execution_changes(&block.clone().unseal(), &mut evm)?;

// Re-execute all of the transactions in the block to load all touched accounts into
// the cache DB.
Expand Down
8 changes: 4 additions & 4 deletions crates/engine/util/src/reorg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use reth_beacon_consensus::{BeaconEngineMessage, BeaconOnNewPayloadError, OnFork
use reth_engine_primitives::EngineTypes;
use reth_errors::{BlockExecutionError, BlockValidationError, RethError, RethResult};
use reth_ethereum_forks::EthereumHardforks;
use reth_evm::{system_calls::apply_beacon_root_contract_call, ConfigureEvm};
use reth_evm::{system_calls::SystemCaller, ConfigureEvm};
use reth_payload_validator::ExecutionPayloadValidator;
use reth_primitives::{proofs, Block, BlockBody, Header, Receipt, Receipts};
use reth_provider::{BlockReader, ExecutionOutcome, ProviderError, StateProviderFactory};
Expand Down Expand Up @@ -286,9 +286,9 @@ where
let mut evm = evm_config.evm_with_env(&mut state, env);

// apply eip-4788 pre block contract call
apply_beacon_root_contract_call(
evm_config,
chain_spec,
let mut system_caller = SystemCaller::new(evm_config, chain_spec);

system_caller.apply_beacon_root_contract_call(
reorg_target.timestamp,
reorg_target.number,
reorg_target.parent_beacon_block_root,
Expand Down
35 changes: 6 additions & 29 deletions crates/ethereum/evm/src/execute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,7 @@ use reth_evm::{
BatchExecutor, BlockExecutionError, BlockExecutionInput, BlockExecutionOutput,
BlockExecutorProvider, BlockValidationError, Executor, ProviderError,
},
system_calls::{
apply_beacon_root_contract_call, apply_blockhashes_contract_call,
apply_consolidation_requests_contract_call, apply_withdrawal_requests_contract_call,
},
system_calls::SystemCaller,
ConfigureEvm,
};
use reth_execution_types::ExecutionOutcome;
Expand Down Expand Up @@ -142,23 +139,9 @@ where
DB: Database,
DB::Error: Into<ProviderError> + Display,
{
// apply pre execution changes
apply_beacon_root_contract_call(
&self.evm_config,
&self.chain_spec,
block.timestamp,
block.number,
block.parent_beacon_block_root,
&mut evm,
)?;
apply_blockhashes_contract_call(
&self.evm_config,
&self.chain_spec,
block.timestamp,
block.number,
block.parent_hash,
&mut evm,
)?;
let mut system_caller = SystemCaller::new(&self.evm_config, &self.chain_spec);

system_caller.apply_pre_execution_changes(block, &mut evm)?;

// execute transactions
let mut cumulative_gas_used = 0;
Expand Down Expand Up @@ -212,15 +195,9 @@ where
let deposit_requests =
crate::eip6110::parse_deposits_from_receipts(&self.chain_spec, &receipts)?;

// Collect all EIP-7685 requests
let withdrawal_requests =
apply_withdrawal_requests_contract_call(&self.evm_config, &mut evm)?;

// Collect all EIP-7251 requests
let consolidation_requests =
apply_consolidation_requests_contract_call(&self.evm_config, &mut evm)?;
let post_execution_requests = system_caller.apply_post_execution_changes(&mut evm)?;

[deposit_requests, withdrawal_requests, consolidation_requests].concat()
[deposit_requests, post_execution_requests].concat()
} else {
vec![]
};
Expand Down
74 changes: 33 additions & 41 deletions crates/ethereum/payload/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,7 @@ use reth_basic_payload_builder::{
use reth_chain_state::ExecutedBlock;
use reth_chainspec::ChainSpec;
use reth_errors::RethError;
use reth_evm::{
system_calls::{
post_block_consolidation_requests_contract_call,
post_block_withdrawal_requests_contract_call, pre_block_beacon_root_contract_call,
pre_block_blockhashes_contract_call,
},
ConfigureEvm, NextBlockEnvAttributes,
};
use reth_evm::{system_calls::SystemCaller, ConfigureEvm, NextBlockEnvAttributes};
use reth_evm_ethereum::{eip6110::parse_deposits_from_receipts, EthEvmConfig};
use reth_execution_types::ExecutionOutcome;
use reth_payload_builder::{EthBuiltPayload, EthPayloadBuilderAttributes};
Expand Down Expand Up @@ -167,29 +160,28 @@ where

let block_number = initialized_block_env.number.to::<u64>();

let mut system_caller = SystemCaller::new(&evm_config, chain_spec.clone());

// apply eip-4788 pre block contract call
pre_block_beacon_root_contract_call(
&mut db,
&evm_config,
&chain_spec,
&initialized_cfg,
&initialized_block_env,
attributes.parent_beacon_block_root,
)
.map_err(|err| {
warn!(target: "payload_builder",
parent_hash=%parent_block.hash(),
%err,
"failed to apply beacon root contract call for payload"
);
PayloadBuilderError::Internal(err.into())
})?;
system_caller
.pre_block_beacon_root_contract_call(
&mut db,
&initialized_cfg,
&initialized_block_env,
attributes.parent_beacon_block_root,
)
.map_err(|err| {
warn!(target: "payload_builder",
parent_hash=%parent_block.hash(),
%err,
"failed to apply beacon root contract call for payload"
);
PayloadBuilderError::Internal(err.into())
})?;

// apply eip-2935 blockhashes update
pre_block_blockhashes_contract_call(
system_caller.pre_block_blockhashes_contract_call(
&mut db,
&evm_config,
&chain_spec,
&initialized_cfg,
&initialized_block_env,
parent_block.hash(),
Expand Down Expand Up @@ -320,20 +312,20 @@ where
{
let deposit_requests = parse_deposits_from_receipts(&chain_spec, receipts.iter().flatten())
.map_err(|err| PayloadBuilderError::Internal(RethError::Execution(err.into())))?;
let withdrawal_requests = post_block_withdrawal_requests_contract_call(
&evm_config,
&mut db,
&initialized_cfg,
&initialized_block_env,
)
.map_err(|err| PayloadBuilderError::Internal(err.into()))?;
let consolidation_requests = post_block_consolidation_requests_contract_call(
&evm_config,
&mut db,
&initialized_cfg,
&initialized_block_env,
)
.map_err(|err| PayloadBuilderError::Internal(err.into()))?;
let withdrawal_requests = system_caller
.post_block_withdrawal_requests_contract_call(
&mut db,
&initialized_cfg,
&initialized_block_env,
)
.map_err(|err| PayloadBuilderError::Internal(err.into()))?;
let consolidation_requests = system_caller
.post_block_consolidation_requests_contract_call(
&mut db,
&initialized_cfg,
&initialized_block_env,
)
.map_err(|err| PayloadBuilderError::Internal(err.into()))?;

let requests = [deposit_requests, withdrawal_requests, consolidation_requests].concat();
let requests_root = calculate_requests_root(&requests);
Expand Down
82 changes: 3 additions & 79 deletions crates/evm/src/system_calls/eip2935.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,52 +5,11 @@ use alloy_eips::eip2935::HISTORY_STORAGE_ADDRESS;

use crate::ConfigureEvm;
use alloy_primitives::B256;
use core::fmt::Display;
use reth_chainspec::EthereumHardforks;
use reth_execution_errors::{BlockExecutionError, BlockValidationError};
use reth_primitives::Header;
use revm::{interpreter::Host, Database, DatabaseCommit, Evm};
use revm_primitives::{BlockEnv, CfgEnvWithHandlerCfg, EnvWithHandlerCfg, ResultAndState};

/// Apply the [EIP-2935](https://eips.ethereum.org/EIPS/eip-2935) pre block contract call.
///
/// This constructs a new [`Evm`] with the given database and environment ([`CfgEnvWithHandlerCfg`]
/// and [`BlockEnv`]) to execute the pre block contract call.
///
/// This uses [`apply_blockhashes_contract_call`] to ultimately apply the
/// blockhash contract state change.
pub fn pre_block_blockhashes_contract_call<EvmConfig, DB>(
db: &mut DB,
evm_config: &EvmConfig,
chain_spec: impl EthereumHardforks,
initialized_cfg: &CfgEnvWithHandlerCfg,
initialized_block_env: &BlockEnv,
parent_block_hash: B256,
) -> Result<(), BlockExecutionError>
where
DB: Database + DatabaseCommit,
DB::Error: Display,
EvmConfig: ConfigureEvm<Header = Header>,
{
// Apply the pre-block EIP-2935 contract call
let mut evm_pre_block = Evm::builder()
.with_db(db)
.with_env_with_handler_cfg(EnvWithHandlerCfg::new_with_cfg_env(
initialized_cfg.clone(),
initialized_block_env.clone(),
Default::default(),
))
.build();

apply_blockhashes_contract_call(
evm_config,
chain_spec,
initialized_block_env.timestamp.to(),
initialized_block_env.number.to(),
parent_block_hash,
&mut evm_pre_block,
)
}
use revm::{interpreter::Host, Database, Evm};
use revm_primitives::ResultAndState;

/// Applies the pre-block call to the [EIP-2935] blockhashes contract, using the given block,
/// chain specification, and EVM.
Expand All @@ -65,7 +24,7 @@ where
///
/// [EIP-2935]: https://eips.ethereum.org/EIPS/eip-2935
#[inline]
pub fn transact_blockhashes_contract_call<EvmConfig, EXT, DB>(
pub(crate) fn transact_blockhashes_contract_call<EvmConfig, EXT, DB>(
evm_config: &EvmConfig,
chain_spec: impl EthereumHardforks,
block_timestamp: u64,
Expand Down Expand Up @@ -115,38 +74,3 @@ where

Ok(Some(res))
}

/// Applies the pre-block call to the [EIP-2935] blockhashes contract, using the given block,
/// chain specification, and EVM and commits the relevant state changes.
///
/// If Prague is not activated, or the block is the genesis block, then this is a no-op, and no
/// state changes are made.
///
/// [EIP-2935]: https://eips.ethereum.org/EIPS/eip-2935
#[inline]
pub fn apply_blockhashes_contract_call<EvmConfig, EXT, DB>(
evm_config: &EvmConfig,
chain_spec: impl EthereumHardforks,
block_timestamp: u64,
block_number: u64,
parent_block_hash: B256,
evm: &mut Evm<'_, EXT, DB>,
) -> Result<(), BlockExecutionError>
where
DB: Database + DatabaseCommit,
DB::Error: core::fmt::Display,
EvmConfig: ConfigureEvm<Header = Header>,
{
if let Some(res) = transact_blockhashes_contract_call(
evm_config,
chain_spec,
block_timestamp,
block_number,
parent_block_hash,
evm,
)? {
evm.context.evm.db.commit(res.state);
}

Ok(())
}
Loading
Loading