emv: add BlockHeader trait and default fill_block_env (#10993)

This commit is contained in:
Thomas Coratger
2024-09-18 19:36:55 +02:00
committed by GitHub
parent c2019e35de
commit 06b9792792
9 changed files with 85 additions and 83 deletions

1
Cargo.lock generated
View File

@ -7228,6 +7228,7 @@ dependencies = [
"reth-execution-types",
"reth-metrics",
"reth-primitives",
"reth-primitives-traits",
"reth-prune-types",
"reth-storage-errors",
"revm",

View File

@ -122,26 +122,6 @@ impl ConfigureEvmEnv for EthEvmConfig {
cfg_env.handler_cfg.spec_id = spec_id;
}
fn fill_block_env(&self, block_env: &mut BlockEnv, header: &Self::Header, after_merge: bool) {
block_env.number = U256::from(header.number);
block_env.coinbase = header.beneficiary;
block_env.timestamp = U256::from(header.timestamp);
if after_merge {
block_env.prevrandao = Some(header.mix_hash);
block_env.difficulty = U256::ZERO;
} else {
block_env.difficulty = header.difficulty;
block_env.prevrandao = None;
}
block_env.basefee = U256::from(header.base_fee_per_gas.unwrap_or_default());
block_env.gas_limit = U256::from(header.gas_limit);
// EIP-4844 excess blob gas of this block, introduced in Cancun
if let Some(excess_blob_gas) = header.excess_blob_gas {
block_env.set_blob_excess_gas_and_price(excess_blob_gas);
}
}
fn next_cfg_and_block_env(
&self,
parent: &Self::Header,

View File

@ -15,6 +15,7 @@ workspace = true
reth-chainspec.workspace = true
reth-execution-errors.workspace = true
reth-primitives.workspace = true
reth-primitives-traits.workspace = true
revm-primitives.workspace = true
reth-prune-types.workspace = true
reth-metrics = { workspace = true, optional = true }

View File

@ -15,6 +15,7 @@ use core::ops::Deref;
use crate::builder::RethEvmBuilder;
use reth_primitives::{Address, TransactionSigned, TransactionSignedEcRecovered, B256, U256};
use reth_primitives_traits::BlockHeader;
use revm::{Database, Evm, GetInspector};
use revm_primitives::{
BlockEnv, Bytes, CfgEnvWithHandlerCfg, Env, EnvWithHandlerCfg, SpecId, TxEnv,
@ -109,7 +110,7 @@ pub trait ConfigureEvm: ConfigureEvmEnv {
#[auto_impl::auto_impl(&, Arc)]
pub trait ConfigureEvmEnv: Send + Sync + Unpin + Clone + 'static {
/// The header type used by the EVM.
type Header;
type Header: BlockHeader;
/// Returns a [`TxEnv`] from a [`TransactionSignedEcRecovered`].
fn tx_env(&self, transaction: &TransactionSignedEcRecovered) -> TxEnv {
@ -142,7 +143,25 @@ pub trait ConfigureEvmEnv: Send + Sync + Unpin + Clone + 'static {
);
/// Fill [`BlockEnv`] field according to the chain spec and given header
fn fill_block_env(&self, block_env: &mut BlockEnv, header: &Self::Header, after_merge: bool);
fn fill_block_env(&self, block_env: &mut BlockEnv, header: &Self::Header, after_merge: bool) {
block_env.number = U256::from(header.number());
block_env.coinbase = header.beneficiary();
block_env.timestamp = U256::from(header.timestamp());
if after_merge {
block_env.prevrandao = Some(header.mix_hash());
block_env.difficulty = U256::ZERO;
} else {
block_env.difficulty = header.difficulty();
block_env.prevrandao = None;
}
block_env.basefee = U256::from(header.base_fee_per_gas().unwrap_or_default());
block_env.gas_limit = U256::from(header.gas_limit());
// EIP-4844 excess blob gas of this block, introduced in Cancun
if let Some(excess_blob_gas) = header.excess_blob_gas() {
block_env.set_blob_excess_gas_and_price(excess_blob_gas);
}
}
/// Convenience function to call both [`fill_cfg_env`](ConfigureEvmEnv::fill_cfg_env) and
/// [`ConfigureEvmEnv::fill_block_env`].

View File

@ -127,26 +127,6 @@ impl ConfigureEvmEnv for OptimismEvmConfig {
cfg_env.handler_cfg.is_optimism = self.chain_spec.is_optimism();
}
fn fill_block_env(&self, block_env: &mut BlockEnv, header: &Self::Header, after_merge: bool) {
block_env.number = U256::from(header.number);
block_env.coinbase = header.beneficiary;
block_env.timestamp = U256::from(header.timestamp);
if after_merge {
block_env.prevrandao = Some(header.mix_hash);
block_env.difficulty = U256::ZERO;
} else {
block_env.difficulty = header.difficulty;
block_env.prevrandao = None;
}
block_env.basefee = U256::from(header.base_fee_per_gas.unwrap_or_default());
block_env.gas_limit = U256::from(header.gas_limit);
// EIP-4844 excess blob gas of this block, introduced in Cancun
if let Some(excess_blob_gas) = header.excess_blob_gas {
block_env.set_blob_excess_gas_and_price(excess_blob_gas);
}
}
fn next_cfg_and_block_env(
&self,
parent: &Self::Header,

View File

@ -527,3 +527,64 @@ impl<'a> arbitrary::Arbitrary<'a> for Header {
))
}
}
/// Trait for extracting specific Ethereum block data from a header
pub trait BlockHeader {
/// Retrieves the beneficiary (miner) of the block
fn beneficiary(&self) -> Address;
/// Retrieves the difficulty of the block
fn difficulty(&self) -> U256;
/// Retrieves the block number
fn number(&self) -> BlockNumber;
/// Retrieves the gas limit of the block
fn gas_limit(&self) -> u64;
/// Retrieves the timestamp of the block
fn timestamp(&self) -> u64;
/// Retrieves the mix hash of the block
fn mix_hash(&self) -> B256;
/// Retrieves the base fee per gas of the block, if available
fn base_fee_per_gas(&self) -> Option<u64>;
/// Retrieves the excess blob gas of the block, if available
fn excess_blob_gas(&self) -> Option<u64>;
}
impl BlockHeader for Header {
fn beneficiary(&self) -> Address {
self.beneficiary
}
fn difficulty(&self) -> U256 {
self.difficulty
}
fn number(&self) -> BlockNumber {
self.number
}
fn gas_limit(&self) -> u64 {
self.gas_limit
}
fn timestamp(&self) -> u64 {
self.timestamp
}
fn mix_hash(&self) -> B256 {
self.mix_hash
}
fn base_fee_per_gas(&self) -> Option<u64> {
self.base_fee_per_gas
}
fn excess_blob_gas(&self) -> Option<u64> {
self.excess_blob_gas
}
}

View File

@ -45,4 +45,4 @@ pub use storage::StorageEntry;
pub mod header;
#[cfg(any(test, feature = "arbitrary", feature = "test-utils"))]
pub use header::test_utils;
pub use header::{Header, HeaderError, SealedHeader};
pub use header::{BlockHeader, Header, HeaderError, SealedHeader};

View File

@ -114,26 +114,6 @@ impl ConfigureEvmEnv for MyEvmConfig {
self.inner.fill_cfg_env(cfg_env, header, total_difficulty);
}
fn fill_block_env(&self, block_env: &mut BlockEnv, header: &Self::Header, after_merge: bool) {
block_env.number = U256::from(header.number);
block_env.coinbase = header.beneficiary;
block_env.timestamp = U256::from(header.timestamp);
if after_merge {
block_env.prevrandao = Some(header.mix_hash);
block_env.difficulty = U256::ZERO;
} else {
block_env.difficulty = header.difficulty;
block_env.prevrandao = None;
}
block_env.basefee = U256::from(header.base_fee_per_gas.unwrap_or_default());
block_env.gas_limit = U256::from(header.gas_limit);
// EIP-4844 excess blob gas of this block, introduced in Cancun
if let Some(excess_blob_gas) = header.excess_blob_gas {
block_env.set_blob_excess_gas_and_price(excess_blob_gas);
}
}
fn next_cfg_and_block_env(
&self,
parent: &Self::Header,

View File

@ -170,26 +170,6 @@ impl ConfigureEvmEnv for MyEvmConfig {
self.inner.fill_cfg_env(cfg_env, header, total_difficulty)
}
fn fill_block_env(&self, block_env: &mut BlockEnv, header: &Self::Header, after_merge: bool) {
block_env.number = U256::from(header.number);
block_env.coinbase = header.beneficiary;
block_env.timestamp = U256::from(header.timestamp);
if after_merge {
block_env.prevrandao = Some(header.mix_hash);
block_env.difficulty = U256::ZERO;
} else {
block_env.difficulty = header.difficulty;
block_env.prevrandao = None;
}
block_env.basefee = U256::from(header.base_fee_per_gas.unwrap_or_default());
block_env.gas_limit = U256::from(header.gas_limit);
// EIP-4844 excess blob gas of this block, introduced in Cancun
if let Some(excess_blob_gas) = header.excess_blob_gas {
block_env.set_blob_excess_gas_and_price(excess_blob_gas);
}
}
fn next_cfg_and_block_env(
&self,
parent: &Self::Header,