Skip to content

Commit

Permalink
feat: wire SystemCaller (paradigmxyz#11321)
Browse files Browse the repository at this point in the history
  • Loading branch information
fgimenez authored Sep 30, 2024
1 parent 09f0526 commit 6d57b9e
Show file tree
Hide file tree
Showing 12 changed files with 99 additions and 431 deletions.
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

0 comments on commit 6d57b9e

Please sign in to comment.