diff --git a/Cargo.lock b/Cargo.lock index 898170dfa9..92d4c133f6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4842,6 +4842,8 @@ dependencies = [ "reth-db", "reth-interfaces", "reth-primitives", + "reth-revm-primitives", + "revm-primitives", "thiserror", ] diff --git a/crates/consensus/src/validation.rs b/crates/consensus/src/validation.rs index b81172a6c1..b786fd618b 100644 --- a/crates/consensus/src/validation.rs +++ b/crates/consensus/src/validation.rs @@ -462,6 +462,10 @@ mod tests { Ok(None) } + fn header_td_by_number(&self, _number: BlockNumber) -> Result> { + Ok(None) + } + fn headers_range(&self, _range: impl RangeBounds) -> Result> { Ok(vec![]) } diff --git a/crates/executor/src/executor.rs b/crates/executor/src/executor.rs index f7362139f0..24125d5551 100644 --- a/crates/executor/src/executor.rs +++ b/crates/executor/src/executor.rs @@ -11,12 +11,12 @@ use reth_provider::StateProvider; use reth_revm::{ config::{WEI_2ETH, WEI_3ETH, WEI_5ETH}, database::SubState, - env::{fill_block_env, fill_cfg_env, fill_tx_env}, + env::{fill_cfg_and_block_env, fill_tx_env}, into_reth_log, to_reth_acc, }; use revm::{ db::AccountState, - primitives::{Account as RevmAccount, AccountInfo, Bytecode, ResultAndState, SpecId}, + primitives::{Account as RevmAccount, AccountInfo, Bytecode, ResultAndState}, EVM, }; use std::collections::{BTreeMap, HashMap}; @@ -65,9 +65,7 @@ where /// Initializes the config and block env. fn init_env(&mut self, header: &Header, total_difficulty: U256) { - fill_cfg_env(&mut self.evm.env.cfg, self.chain_spec, header, total_difficulty); - let after_merge = self.evm.env.cfg.spec_id >= SpecId::MERGE; - fill_block_env(&mut self.evm.env.block, header, after_merge); + fill_cfg_and_block_env(&mut self.evm.env, self.chain_spec, header, total_difficulty); } /// Commit change to database and return change diff that is used to update state and create diff --git a/crates/interfaces/src/error.rs b/crates/interfaces/src/error.rs index 94acbcb285..6b27e906bb 100644 --- a/crates/interfaces/src/error.rs +++ b/crates/interfaces/src/error.rs @@ -15,7 +15,7 @@ pub enum Error { Database(#[from] crate::db::Error), #[error(transparent)] - Provider(#[from] crate::provider::Error), + Provider(#[from] crate::provider::ProviderError), #[error(transparent)] Network(#[from] reth_network_api::NetworkError), diff --git a/crates/interfaces/src/provider.rs b/crates/interfaces/src/provider.rs index 102b56eeec..be00f65127 100644 --- a/crates/interfaces/src/provider.rs +++ b/crates/interfaces/src/provider.rs @@ -1,9 +1,9 @@ use reth_primitives::{Address, BlockHash, BlockNumber, TransitionId, TxNumber, H256}; -/// KV error type. They are using u32 to represent error code. +/// Bundled errors variants thrown by various providers. #[allow(missing_docs)] #[derive(Debug, thiserror::Error, PartialEq, Eq, Clone)] -pub enum Error { +pub enum ProviderError { /// The header hash is missing from the database. #[error("Block number {block_number} does not exist in database")] CanonicalHeader { block_number: BlockNumber }, @@ -68,4 +68,7 @@ pub enum Error { /// Reached the end of the transaction sender table. #[error("Got to the end of the transaction sender table")] EndOfTransactionSenderTable, + /// Thrown when required header related data was not found but was required. + #[error("requested data not found")] + HeaderNotFound, } diff --git a/crates/revm/revm-primitives/src/env.rs b/crates/revm/revm-primitives/src/env.rs index 087eccc8dc..c6bbf1802f 100644 --- a/crates/revm/revm-primitives/src/env.rs +++ b/crates/revm/revm-primitives/src/env.rs @@ -3,7 +3,19 @@ use reth_primitives::{ Address, ChainSpec, Head, Header, Transaction, TransactionKind, TransactionSigned, TxEip1559, TxEip2930, TxLegacy, U256, }; -use revm::primitives::{AnalysisKind, BlockEnv, CfgEnv, TransactTo, TxEnv}; +use revm::primitives::{AnalysisKind, BlockEnv, CfgEnv, Env, SpecId, TransactTo, TxEnv}; + +/// Convenience function to call both [fill_cfg_env] and [fill_block_env] +pub fn fill_cfg_and_block_env( + env: &mut Env, + chain_spec: &ChainSpec, + header: &Header, + total_difficulty: U256, +) { + fill_cfg_env(&mut env.cfg, chain_spec, header, total_difficulty); + let after_merge = env.cfg.spec_id >= SpecId::MERGE; + fill_block_env(&mut env.block, header, after_merge); +} /// Fill [CfgEnv] fields according to the chain spec and given header pub fn fill_cfg_env( diff --git a/crates/stages/src/error.rs b/crates/stages/src/error.rs index ee6c7b82e7..0698bf092f 100644 --- a/crates/stages/src/error.rs +++ b/crates/stages/src/error.rs @@ -1,7 +1,6 @@ use crate::pipeline::PipelineEvent; use reth_interfaces::{ - consensus, db::Error as DbError, executor, p2p::error::DownloadError, - provider::Error as ProviderError, + consensus, db::Error as DbError, executor, p2p::error::DownloadError, provider::ProviderError, }; use reth_primitives::BlockNumber; use reth_provider::TransactionError; diff --git a/crates/stages/src/pipeline/mod.rs b/crates/stages/src/pipeline/mod.rs index 88712737cd..794503bc58 100644 --- a/crates/stages/src/pipeline/mod.rs +++ b/crates/stages/src/pipeline/mod.rs @@ -426,7 +426,7 @@ mod tests { use crate::{StageId, UnwindOutput}; use assert_matches::assert_matches; use reth_db::mdbx::{self, test_utils, EnvKind}; - use reth_interfaces::{consensus, provider::Error as ProviderError, sync::NoopSyncStateUpdate}; + use reth_interfaces::{consensus, provider::ProviderError, sync::NoopSyncStateUpdate}; use tokio_stream::StreamExt; use utils::TestStage; diff --git a/crates/stages/src/stages/bodies.rs b/crates/stages/src/stages/bodies.rs index ff49bd0c1f..20b176d05d 100644 --- a/crates/stages/src/stages/bodies.rs +++ b/crates/stages/src/stages/bodies.rs @@ -13,7 +13,7 @@ use reth_db::{ use reth_interfaces::{ consensus::Consensus, p2p::bodies::{downloader::BodyDownloader, response::BlockResponse}, - provider::Error as ProviderError, + provider::ProviderError, }; use reth_provider::Transaction; use std::sync::Arc; diff --git a/crates/stages/src/stages/execution.rs b/crates/stages/src/stages/execution.rs index 8da23cbb6d..62490016b1 100644 --- a/crates/stages/src/stages/execution.rs +++ b/crates/stages/src/stages/execution.rs @@ -10,7 +10,7 @@ use reth_db::{ transaction::{DbTx, DbTxMut}, }; use reth_executor::execution_result::AccountChangeSet; -use reth_interfaces::provider::Error as ProviderError; +use reth_interfaces::provider::ProviderError; use reth_primitives::{Address, Block, ChainSpec, Hardfork, StorageEntry, H256, MAINNET, U256}; use reth_provider::{LatestStateProviderRef, Transaction}; use reth_revm::database::{State, SubState}; diff --git a/crates/stages/src/stages/headers.rs b/crates/stages/src/stages/headers.rs index 4d3c192498..ef258ce2cf 100644 --- a/crates/stages/src/stages/headers.rs +++ b/crates/stages/src/stages/headers.rs @@ -9,7 +9,7 @@ use reth_db::{ use reth_interfaces::{ consensus::{Consensus, ForkchoiceState}, p2p::headers::downloader::{HeaderDownloader, SyncTarget}, - provider::Error as ProviderError, + provider::ProviderError, }; use reth_primitives::{BlockNumber, SealedHeader}; use reth_provider::Transaction; diff --git a/crates/stages/src/stages/total_difficulty.rs b/crates/stages/src/stages/total_difficulty.rs index d8bee3af8b..6556bf81df 100644 --- a/crates/stages/src/stages/total_difficulty.rs +++ b/crates/stages/src/stages/total_difficulty.rs @@ -8,7 +8,7 @@ use reth_db::{ tables, transaction::{DbTx, DbTxMut}, }; -use reth_interfaces::{consensus::Error, provider::Error as ProviderError}; +use reth_interfaces::{consensus::Error, provider::ProviderError}; use reth_primitives::{ChainSpec, Hardfork, EMPTY_OMMER_ROOT, MAINNET, U256}; use reth_provider::Transaction; use tracing::*; diff --git a/crates/storage/provider/Cargo.toml b/crates/storage/provider/Cargo.toml index ce809e54c1..509009cbaf 100644 --- a/crates/storage/provider/Cargo.toml +++ b/crates/storage/provider/Cargo.toml @@ -11,6 +11,7 @@ description = "Reth storage provider." # reth reth-primitives = { path = "../../primitives" } reth-interfaces = { path = "../../interfaces" } +reth-revm-primitives = { path = "../../revm/revm-primitives" } reth-db = { path = "../db" } # misc @@ -19,6 +20,7 @@ auto_impl = "1.0" # feature test-utils parking_lot = { version = "0.12", optional = true } +revm-primitives = "1.0" [dev-dependencies] reth-db = { path = "../db", features = ["test-utils"] } diff --git a/crates/storage/provider/src/lib.rs b/crates/storage/provider/src/lib.rs index 5660770a91..d7941257ae 100644 --- a/crates/storage/provider/src/lib.rs +++ b/crates/storage/provider/src/lib.rs @@ -11,8 +11,8 @@ /// Various provider traits. mod traits; pub use traits::{ - AccountProvider, BlockHashProvider, BlockIdProvider, BlockProvider, HeaderProvider, - StateProvider, StateProviderFactory, TransactionsProvider, WithdrawalsProvider, + AccountProvider, BlockHashProvider, BlockIdProvider, BlockProvider, EvmEnvProvider, + HeaderProvider, StateProvider, StateProviderFactory, TransactionsProvider, WithdrawalsProvider, }; /// Provider trait implementations. @@ -35,4 +35,4 @@ pub use utils::{insert_block, insert_canonical_block}; pub mod test_utils; /// Re-export provider error. -pub use reth_interfaces::provider::Error; +pub use reth_interfaces::provider::ProviderError; diff --git a/crates/storage/provider/src/providers/mod.rs b/crates/storage/provider/src/providers/mod.rs index dd7f86bfc8..c67de018fb 100644 --- a/crates/storage/provider/src/providers/mod.rs +++ b/crates/storage/provider/src/providers/mod.rs @@ -1,6 +1,6 @@ use crate::{ - BlockHashProvider, BlockIdProvider, BlockProvider, Error, HeaderProvider, StateProviderFactory, - TransactionsProvider, WithdrawalsProvider, + BlockHashProvider, BlockIdProvider, BlockProvider, EvmEnvProvider, HeaderProvider, + ProviderError, StateProviderFactory, TransactionsProvider, WithdrawalsProvider, }; use reth_db::{ cursor::DbCursorRO, @@ -10,9 +10,14 @@ use reth_db::{ }; use reth_interfaces::Result; use reth_primitives::{ - Block, BlockHash, BlockId, BlockNumber, ChainInfo, ChainSpec, Hardfork, Header, + Block, BlockHash, BlockId, BlockNumber, ChainInfo, ChainSpec, Hardfork, Head, Header, TransactionSigned, TxHash, TxNumber, Withdrawal, H256, U256, }; +use reth_revm_primitives::{ + config::revm_spec, + env::{fill_block_env, fill_cfg_and_block_env, fill_cfg_env}, +}; +use revm_primitives::{BlockEnv, CfgEnv, Env, SpecId}; use std::{ops::RangeBounds, sync::Arc}; mod state; @@ -74,6 +79,10 @@ impl HeaderProvider for ShareableDatabase { })? } + fn header_td_by_number(&self, number: BlockNumber) -> Result> { + self.db.view(|tx| Ok(tx.get::(number)?.map(|td| td.0)))? + } + fn headers_range(&self, range: impl RangeBounds) -> Result> { self.db .view(|tx| { @@ -119,7 +128,7 @@ impl BlockProvider for ShareableDatabase { let id = BlockId::Number(number.into()); let tx = self.db.tx()?; let transactions = - self.transactions_by_block(id)?.ok_or(Error::BlockBody { number })?; + self.transactions_by_block(id)?.ok_or(ProviderError::BlockBody { number })?; let ommers = tx.get::(header.number)?.map(|o| o.ommers); let withdrawals = self.withdrawals_by_block(id, header.timestamp)?; @@ -231,6 +240,60 @@ impl WithdrawalsProvider for ShareableDatabase { } } +impl EvmEnvProvider for ShareableDatabase { + fn fill_env_at(&self, env: &mut Env, at: BlockId) -> Result<()> { + let hash = self.block_hash_for_id(at)?.ok_or(ProviderError::HeaderNotFound)?; + let header = self.header(&hash)?.ok_or(ProviderError::HeaderNotFound)?; + self.fill_env_with_header(env, &header) + } + + fn fill_env_with_header(&self, env: &mut Env, header: &Header) -> Result<()> { + let total_difficulty = + self.header_td_by_number(header.number)?.ok_or(ProviderError::HeaderNotFound)?; + fill_cfg_and_block_env(env, &self.chain_spec, header, total_difficulty); + Ok(()) + } + + fn fill_block_env_at(&self, block_env: &mut BlockEnv, at: BlockId) -> Result<()> { + let hash = self.block_hash_for_id(at)?.ok_or(ProviderError::HeaderNotFound)?; + let header = self.header(&hash)?.ok_or(ProviderError::HeaderNotFound)?; + + self.fill_block_env_with_header(block_env, &header) + } + + fn fill_block_env_with_header(&self, block_env: &mut BlockEnv, header: &Header) -> Result<()> { + let total_difficulty = + self.header_td_by_number(header.number)?.ok_or(ProviderError::HeaderNotFound)?; + let spec_id = revm_spec( + &self.chain_spec, + Head { + number: header.number, + timestamp: header.timestamp, + difficulty: header.difficulty, + total_difficulty, + // Not required + hash: Default::default(), + }, + ); + let after_merge = spec_id >= SpecId::MERGE; + fill_block_env(block_env, header, after_merge); + Ok(()) + } + + fn fill_cfg_env_at(&self, cfg: &mut CfgEnv, at: BlockId) -> Result<()> { + let hash = self.block_hash_for_id(at)?.ok_or(ProviderError::HeaderNotFound)?; + let header = self.header(&hash)?.ok_or(ProviderError::HeaderNotFound)?; + self.fill_cfg_env_with_header(cfg, &header) + } + + fn fill_cfg_env_with_header(&self, cfg: &mut CfgEnv, header: &Header) -> Result<()> { + let total_difficulty = + self.header_td_by_number(header.number)?.ok_or(ProviderError::HeaderNotFound)?; + fill_cfg_env(cfg, &self.chain_spec, header, total_difficulty); + Ok(()) + } +} + impl StateProviderFactory for ShareableDatabase { type HistorySP<'a> = HistoricalStateProvider<'a,>::TX> where Self: 'a; type LatestSP<'a> = LatestStateProvider<'a,>::TX> where Self: 'a; @@ -245,7 +308,7 @@ impl StateProviderFactory for ShareableDatabase { // get transition id let transition = tx .get::(block_number)? - .ok_or(Error::BlockTransition { block_number })?; + .ok_or(ProviderError::BlockTransition { block_number })?; Ok(HistoricalStateProvider::new(tx, transition)) } @@ -253,13 +316,14 @@ impl StateProviderFactory for ShareableDatabase { fn history_by_block_hash(&self, block_hash: BlockHash) -> Result> { let tx = self.db.tx()?; // get block number - let block_number = - tx.get::(block_hash)?.ok_or(Error::BlockHash { block_hash })?; + let block_number = tx + .get::(block_hash)? + .ok_or(ProviderError::BlockHash { block_hash })?; // get transition id let transition = tx .get::(block_number)? - .ok_or(Error::BlockTransition { block_number })?; + .ok_or(ProviderError::BlockTransition { block_number })?; Ok(HistoricalStateProvider::new(tx, transition)) } diff --git a/crates/storage/provider/src/providers/state/historical.rs b/crates/storage/provider/src/providers/state/historical.rs index eed7a0d21f..cd7ce2c8e7 100644 --- a/crates/storage/provider/src/providers/state/historical.rs +++ b/crates/storage/provider/src/providers/state/historical.rs @@ -1,6 +1,6 @@ use crate::{ - providers::state::macros::delegate_provider_impls, AccountProvider, BlockHashProvider, Error, - StateProvider, + providers::state::macros::delegate_provider_impls, AccountProvider, BlockHashProvider, + ProviderError, StateProvider, }; use reth_db::{ cursor::{DbCursorRO, DbDupCursorRO}, @@ -56,7 +56,7 @@ impl<'a, 'b, TX: DbTx<'a>> AccountProvider for HistoricalStateProviderRef<'a, 'b .tx .cursor_dup_read::()? .seek_by_key_subkey(changeset_transition_id, address)? - .ok_or(Error::AccountChangeset { + .ok_or(ProviderError::AccountChangeset { transition_id: changeset_transition_id, address, })?; @@ -95,7 +95,7 @@ impl<'a, 'b, TX: DbTx<'a>> StateProvider for HistoricalStateProviderRef<'a, 'b, .tx .cursor_dup_read::()? .seek_by_key_subkey((changeset_transition_id, address).into(), storage_key)? - .ok_or(Error::StorageChangeset { + .ok_or(ProviderError::StorageChangeset { transition_id: changeset_transition_id, address, storage_key, diff --git a/crates/storage/provider/src/test_utils/mock.rs b/crates/storage/provider/src/test_utils/mock.rs index 9a82741e17..a95bc0b7a1 100644 --- a/crates/storage/provider/src/test_utils/mock.rs +++ b/crates/storage/provider/src/test_utils/mock.rs @@ -1,13 +1,14 @@ use crate::{ - AccountProvider, BlockHashProvider, BlockIdProvider, BlockProvider, HeaderProvider, - StateProvider, StateProviderFactory, TransactionsProvider, + AccountProvider, BlockHashProvider, BlockIdProvider, BlockProvider, EvmEnvProvider, + HeaderProvider, StateProvider, StateProviderFactory, TransactionsProvider, }; use parking_lot::Mutex; use reth_interfaces::Result; use reth_primitives::{ - keccak256, Account, Address, Block, BlockHash, BlockId, BlockNumberOrTag, Bytes, ChainInfo, - Header, StorageKey, StorageValue, TransactionSigned, TxHash, H256, U256, + keccak256, Account, Address, Block, BlockHash, BlockId, BlockNumber, BlockNumberOrTag, Bytes, + ChainInfo, Header, StorageKey, StorageValue, TransactionSigned, TxHash, H256, U256, }; +use revm_primitives::{BlockEnv, CfgEnv, Env}; use std::{collections::HashMap, ops::RangeBounds, sync::Arc}; /// A mock implementation for Provider interfaces. @@ -108,6 +109,15 @@ impl HeaderProvider for MockEthProvider { })) } + fn header_td_by_number(&self, number: BlockNumber) -> Result> { + let lock = self.headers.lock(); + let sum = lock + .values() + .filter(|h| h.number <= number) + .fold(U256::ZERO, |td, h| td + h.difficulty); + Ok(Some(sum)) + } + fn headers_range( &self, range: impl RangeBounds, @@ -211,6 +221,11 @@ impl AccountProvider for MockEthProvider { } impl StateProvider for MockEthProvider { + fn storage(&self, account: Address, storage_key: StorageKey) -> Result> { + let lock = self.accounts.lock(); + Ok(lock.get(&account).and_then(|account| account.storage.get(&storage_key)).cloned()) + } + fn bytecode_by_hash(&self, code_hash: H256) -> Result> { let lock = self.accounts.lock(); Ok(lock.values().find_map(|account| { @@ -222,10 +237,35 @@ impl StateProvider for MockEthProvider { } })) } +} - fn storage(&self, account: Address, storage_key: StorageKey) -> Result> { - let lock = self.accounts.lock(); - Ok(lock.get(&account).and_then(|account| account.storage.get(&storage_key)).cloned()) +impl EvmEnvProvider for MockEthProvider { + fn fill_env_at(&self, _env: &mut Env, _at: BlockId) -> Result<()> { + unimplemented!() + } + + fn fill_env_with_header(&self, _env: &mut Env, _header: &Header) -> Result<()> { + unimplemented!() + } + + fn fill_block_env_at(&self, _block_env: &mut BlockEnv, _at: BlockId) -> Result<()> { + unimplemented!() + } + + fn fill_block_env_with_header( + &self, + _block_env: &mut BlockEnv, + _header: &Header, + ) -> Result<()> { + unimplemented!() + } + + fn fill_cfg_env_at(&self, _cfg: &mut CfgEnv, _at: BlockId) -> Result<()> { + unimplemented!() + } + + fn fill_cfg_env_with_header(&self, _cfg: &mut CfgEnv, _header: &Header) -> Result<()> { + unimplemented!() } } diff --git a/crates/storage/provider/src/test_utils/noop.rs b/crates/storage/provider/src/test_utils/noop.rs index a71d4882ab..8f24ea6fb4 100644 --- a/crates/storage/provider/src/test_utils/noop.rs +++ b/crates/storage/provider/src/test_utils/noop.rs @@ -1,12 +1,13 @@ use crate::{ - AccountProvider, BlockHashProvider, BlockIdProvider, BlockProvider, HeaderProvider, - StateProvider, StateProviderFactory, TransactionsProvider, + AccountProvider, BlockHashProvider, BlockIdProvider, BlockProvider, EvmEnvProvider, + HeaderProvider, StateProvider, StateProviderFactory, TransactionsProvider, }; use reth_interfaces::Result; use reth_primitives::{ Account, Address, Block, BlockHash, BlockId, BlockNumber, Bytes, ChainInfo, Header, StorageKey, StorageValue, TransactionSigned, TxHash, TxNumber, H256, U256, }; +use revm_primitives::{BlockEnv, CfgEnv, Env}; use std::ops::RangeBounds; /// Supports various api interfaces for testing purposes. @@ -75,6 +76,10 @@ impl HeaderProvider for NoopProvider { Ok(None) } + fn header_td_by_number(&self, _number: BlockNumber) -> Result> { + Ok(None) + } + fn headers_range(&self, _range: impl RangeBounds) -> Result> { Ok(vec![]) } @@ -96,6 +101,36 @@ impl StateProvider for NoopProvider { } } +impl EvmEnvProvider for NoopProvider { + fn fill_env_at(&self, _env: &mut Env, _at: BlockId) -> Result<()> { + Ok(()) + } + + fn fill_env_with_header(&self, _env: &mut Env, _header: &Header) -> Result<()> { + Ok(()) + } + + fn fill_block_env_at(&self, _block_env: &mut BlockEnv, _at: BlockId) -> Result<()> { + Ok(()) + } + + fn fill_block_env_with_header( + &self, + _block_env: &mut BlockEnv, + _header: &Header, + ) -> Result<()> { + Ok(()) + } + + fn fill_cfg_env_at(&self, _cfg: &mut CfgEnv, _at: BlockId) -> Result<()> { + Ok(()) + } + + fn fill_cfg_env_with_header(&self, _cfg: &mut CfgEnv, _header: &Header) -> Result<()> { + Ok(()) + } +} + impl StateProviderFactory for NoopProvider { type HistorySP<'a> = NoopProvider where Self: 'a; type LatestSP<'a> = NoopProvider where Self: 'a; diff --git a/crates/storage/provider/src/traits/evm_env.rs b/crates/storage/provider/src/traits/evm_env.rs new file mode 100644 index 0000000000..6f422e298c --- /dev/null +++ b/crates/storage/provider/src/traits/evm_env.rs @@ -0,0 +1,27 @@ +use reth_interfaces::Result; +use reth_primitives::{BlockId, Header}; +use revm_primitives::{BlockEnv, CfgEnv, Env}; + +/// A provider type that knows chain specific information required to configure an [Env] +/// +/// This type is mainly used to provide required data to configure the EVM environment. +#[auto_impl::auto_impl(&, Arc)] +pub trait EvmEnvProvider: Send + Sync { + /// Fills the [CfgEnv] and [BlockEnv] fields with values specific to the given [BlockId]. + fn fill_env_at(&self, env: &mut Env, at: BlockId) -> Result<()>; + + /// Fills the [CfgEnv] and [BlockEnv] fields with values specific to the given [Header]. + fn fill_env_with_header(&self, env: &mut Env, header: &Header) -> Result<()>; + + /// Fills the [BlockEnv] fields with values specific to the given [BlockId]. + fn fill_block_env_at(&self, block_env: &mut BlockEnv, at: BlockId) -> Result<()>; + + /// Fills the [BlockEnv] fields with values specific to the given [Header]. + fn fill_block_env_with_header(&self, block_env: &mut BlockEnv, header: &Header) -> Result<()>; + + /// Fills the [CfgEnv] fields with values specific to the given [BlockId]. + fn fill_cfg_env_at(&self, cfg: &mut CfgEnv, at: BlockId) -> Result<()>; + + /// Fills the [CfgEnv] fields with values specific to the given [Header]. + fn fill_cfg_env_with_header(&self, cfg: &mut CfgEnv, header: &Header) -> Result<()>; +} diff --git a/crates/storage/provider/src/traits/header.rs b/crates/storage/provider/src/traits/header.rs index 720ed30111..9f1c741e9c 100644 --- a/crates/storage/provider/src/traits/header.rs +++ b/crates/storage/provider/src/traits/header.rs @@ -28,6 +28,9 @@ pub trait HeaderProvider: Send + Sync { /// Get total difficulty by block hash. fn header_td(&self, hash: &BlockHash) -> Result>; + /// Get total difficulty by block number. + fn header_td_by_number(&self, number: BlockNumber) -> Result>; + /// Get headers in range of block numbers fn headers_range(&self, range: impl RangeBounds) -> Result>; } diff --git a/crates/storage/provider/src/traits/mod.rs b/crates/storage/provider/src/traits/mod.rs index 7fe073df45..7552ca7f63 100644 --- a/crates/storage/provider/src/traits/mod.rs +++ b/crates/storage/provider/src/traits/mod.rs @@ -12,6 +12,9 @@ pub use block_hash::BlockHashProvider; mod block_id; pub use block_id::BlockIdProvider; +mod evm_env; +pub use evm_env::EvmEnvProvider; + mod header; pub use header::HeaderProvider; diff --git a/crates/storage/provider/src/transaction.rs b/crates/storage/provider/src/transaction.rs index c5e60053f6..b1c1898fdc 100644 --- a/crates/storage/provider/src/transaction.rs +++ b/crates/storage/provider/src/transaction.rs @@ -7,7 +7,7 @@ use reth_db::{ tables, transaction::{DbTx, DbTxMut}, }; -use reth_interfaces::{db::Error as DbError, provider::Error as ProviderError}; +use reth_interfaces::{db::Error as DbError, provider::ProviderError}; use reth_primitives::{BlockHash, BlockNumber, Header, TransitionId, TxNumber, U256}; use std::{ fmt::Debug, diff --git a/crates/storage/provider/src/utils.rs b/crates/storage/provider/src/utils.rs index fff1c6f5b4..086cc7fc8c 100644 --- a/crates/storage/provider/src/utils.rs +++ b/crates/storage/provider/src/utils.rs @@ -3,7 +3,7 @@ use reth_db::{ tables, transaction::{DbTx, DbTxMut}, }; -use reth_interfaces::{provider::Error as ProviderError, Result}; +use reth_interfaces::{provider::ProviderError, Result}; use reth_primitives::{SealedBlock, U256}; /// Insert block data into corresponding tables. Used mainly for testing & internal tooling.