From 14f035633000084a4c717fe4b7e597a987148468 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Tue, 28 May 2024 14:39:51 +0200 Subject: [PATCH] chore: extract bundle state type (#8425) --- Cargo.lock | 11 + Cargo.toml | 2 + crates/evm/execution-types/Cargo.toml | 21 ++ crates/evm/execution-types/src/bundle.rs | 305 ++++++++++++++++ crates/evm/execution-types/src/lib.rs | 12 + crates/storage/provider/Cargo.toml | 3 +- .../bundle_state_with_receipts.rs | 338 ++---------------- 7 files changed, 376 insertions(+), 316 deletions(-) create mode 100644 crates/evm/execution-types/Cargo.toml create mode 100644 crates/evm/execution-types/src/bundle.rs create mode 100644 crates/evm/execution-types/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 77e4205ea..21bb6b125 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7054,6 +7054,16 @@ dependencies = [ "thiserror", ] +[[package]] +name = "reth-execution-types" +version = "0.2.0-beta.7" +dependencies = [ + "reth-evm", + "reth-primitives", + "reth-trie", + "revm", +] + [[package]] name = "reth-exex" version = "0.2.0-beta.7" @@ -7661,6 +7671,7 @@ dependencies = [ "reth-db", "reth-evm", "reth-execution-errors", + "reth-execution-types", "reth-fs-util", "reth-interfaces", "reth-metrics", diff --git a/Cargo.toml b/Cargo.toml index 1aa1f1bc2..bb9900ae1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,6 +19,7 @@ members = [ "crates/etl/", "crates/evm/", "crates/evm/execution-errors", + "crates/evm/execution-types", "crates/exex/", "crates/interfaces/", "crates/metrics/", @@ -245,6 +246,7 @@ reth-evm = { path = "crates/evm" } reth-evm-ethereum = { path = "crates/ethereum/evm" } reth-evm-optimism = { path = "crates/optimism/evm" } reth-execution-errors = { path = "crates/evm/execution-errors" } +reth-execution-types = { path = "crates/evm/execution-types" } reth-exex = { path = "crates/exex" } reth-fs-util = { path = "crates/fs-util" } reth-interfaces = { path = "crates/interfaces" } diff --git a/crates/evm/execution-types/Cargo.toml b/crates/evm/execution-types/Cargo.toml new file mode 100644 index 000000000..c998f9a9a --- /dev/null +++ b/crates/evm/execution-types/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "reth-execution-types" +version.workspace = true +edition.workspace = true +rust-version.workspace = true +license.workspace = true +homepage.workspace = true +repository.workspace = true + +[lints] +workspace = true + +[dependencies] +reth-primitives.workspace = true +reth-trie.workspace = true +reth-evm.workspace = true + +revm.workspace = true + +[features] +optimism = [] \ No newline at end of file diff --git a/crates/evm/execution-types/src/bundle.rs b/crates/evm/execution-types/src/bundle.rs new file mode 100644 index 000000000..2bc7eda45 --- /dev/null +++ b/crates/evm/execution-types/src/bundle.rs @@ -0,0 +1,305 @@ +use reth_evm::execute::BatchBlockExecutionOutput; +use reth_primitives::{ + logs_bloom, + revm::compat::{into_reth_acc, into_revm_acc}, + Account, Address, BlockNumber, Bloom, Bytecode, Log, Receipt, Receipts, StorageEntry, B256, + U256, +}; +use reth_trie::HashedPostState; +use revm::{ + db::{states::BundleState, BundleAccount}, + primitives::AccountInfo, +}; +use std::collections::HashMap; + +/// Bundle state of post execution changes and reverts. +/// +/// Aggregates the changes over an arbitrary number of blocks. +#[derive(Default, Debug, Clone, PartialEq, Eq)] +pub struct BundleStateWithReceipts { + /// Bundle state with reverts. + pub bundle: BundleState, + /// The collection of receipts. + /// Outer vector stores receipts for each block sequentially. + /// The inner vector stores receipts ordered by transaction number. + /// + /// If receipt is None it means it is pruned. + pub receipts: Receipts, + /// First block of bundle state. + pub first_block: BlockNumber, +} + +// TODO(mattsse): unify the types, currently there's a cyclic dependency between +impl From for BundleStateWithReceipts { + fn from(value: BatchBlockExecutionOutput) -> Self { + let BatchBlockExecutionOutput { bundle, receipts, first_block } = value; + Self { bundle, receipts, first_block } + } +} + +// TODO(mattsse): unify the types, currently there's a cyclic dependency between +impl From for BatchBlockExecutionOutput { + fn from(value: BundleStateWithReceipts) -> Self { + let BundleStateWithReceipts { bundle, receipts, first_block } = value; + Self { bundle, receipts, first_block } + } +} + +/// Type used to initialize revms bundle state. +pub type BundleStateInit = + HashMap, Option, HashMap)>; + +/// Types used inside RevertsInit to initialize revms reverts. +pub type AccountRevertInit = (Option>, Vec); + +/// Type used to initialize revms reverts. +pub type RevertsInit = HashMap>; + +impl BundleStateWithReceipts { + /// Create Bundle State. + pub fn new(bundle: BundleState, receipts: Receipts, first_block: BlockNumber) -> Self { + Self { bundle, receipts, first_block } + } + + /// Create new bundle state with receipts. + pub fn new_init( + state_init: BundleStateInit, + revert_init: RevertsInit, + contracts_init: Vec<(B256, Bytecode)>, + receipts: Receipts, + first_block: BlockNumber, + ) -> Self { + // sort reverts by block number + let mut reverts = revert_init.into_iter().collect::>(); + reverts.sort_unstable_by_key(|a| a.0); + + // initialize revm bundle + let bundle = BundleState::new( + state_init.into_iter().map(|(address, (original, present, storage))| { + ( + address, + original.map(into_revm_acc), + present.map(into_revm_acc), + storage.into_iter().map(|(k, s)| (k.into(), s)).collect(), + ) + }), + reverts.into_iter().map(|(_, reverts)| { + // does not needs to be sorted, it is done when taking reverts. + reverts.into_iter().map(|(address, (original, storage))| { + ( + address, + original.map(|i| i.map(into_revm_acc)), + storage.into_iter().map(|entry| (entry.key.into(), entry.value)), + ) + }) + }), + contracts_init.into_iter().map(|(code_hash, bytecode)| (code_hash, bytecode.0)), + ); + + Self { bundle, receipts, first_block } + } + + /// Return revm bundle state. + pub fn state(&self) -> &BundleState { + &self.bundle + } + + /// Returns mutable revm bundle state. + pub fn state_mut(&mut self) -> &mut BundleState { + &mut self.bundle + } + + /// Set first block. + pub fn set_first_block(&mut self, first_block: BlockNumber) { + self.first_block = first_block; + } + + /// Return iterator over all accounts + pub fn accounts_iter(&self) -> impl Iterator)> { + self.bundle.state().iter().map(|(a, acc)| (*a, acc.info.as_ref())) + } + + /// Return iterator over all [BundleAccount]s in the bundle + pub fn bundle_accounts_iter(&self) -> impl Iterator { + self.bundle.state().iter().map(|(a, acc)| (*a, acc)) + } + + /// Get account if account is known. + pub fn account(&self, address: &Address) -> Option> { + self.bundle.account(address).map(|a| a.info.clone().map(into_reth_acc)) + } + + /// Get storage if value is known. + /// + /// This means that depending on status we can potentially return U256::ZERO. + pub fn storage(&self, address: &Address, storage_key: U256) -> Option { + self.bundle.account(address).and_then(|a| a.storage_slot(storage_key)) + } + + /// Return bytecode if known. + pub fn bytecode(&self, code_hash: &B256) -> Option { + self.bundle.bytecode(code_hash).map(Bytecode) + } + + /// Returns [HashedPostState] for this bundle state. + /// See [HashedPostState::from_bundle_state] for more info. + pub fn hash_state_slow(&self) -> HashedPostState { + HashedPostState::from_bundle_state(&self.bundle.state) + } + + /// Transform block number to the index of block. + fn block_number_to_index(&self, block_number: BlockNumber) -> Option { + if self.first_block > block_number { + return None + } + let index = block_number - self.first_block; + if index >= self.receipts.len() as u64 { + return None + } + Some(index as usize) + } + + /// Returns an iterator over all block logs. + pub fn logs(&self, block_number: BlockNumber) -> Option> { + let index = self.block_number_to_index(block_number)?; + Some(self.receipts[index].iter().filter_map(|r| Some(r.as_ref()?.logs.iter())).flatten()) + } + + /// Return blocks logs bloom + pub fn block_logs_bloom(&self, block_number: BlockNumber) -> Option { + Some(logs_bloom(self.logs(block_number)?)) + } + + /// Returns the receipt root for all recorded receipts. + /// Note: this function calculated Bloom filters for every receipt and created merkle trees + /// of receipt. This is a expensive operation. + pub fn receipts_root_slow(&self, _block_number: BlockNumber) -> Option { + #[cfg(feature = "optimism")] + panic!("This should not be called in optimism mode. Use `optimism_receipts_root_slow` instead."); + #[cfg(not(feature = "optimism"))] + self.receipts.root_slow(self.block_number_to_index(_block_number)?) + } + + /// Returns the receipt root for all recorded receipts. + /// Note: this function calculated Bloom filters for every receipt and created merkle trees + /// of receipt. This is a expensive operation. + #[cfg(feature = "optimism")] + pub fn optimism_receipts_root_slow( + &self, + block_number: BlockNumber, + chain_spec: &reth_primitives::ChainSpec, + timestamp: u64, + ) -> Option { + self.receipts.optimism_root_slow( + self.block_number_to_index(block_number)?, + chain_spec, + timestamp, + ) + } + + /// Returns reference to receipts. + pub fn receipts(&self) -> &Receipts { + &self.receipts + } + + /// Returns mutable reference to receipts. + pub fn receipts_mut(&mut self) -> &mut Receipts { + &mut self.receipts + } + + /// Return all block receipts + pub fn receipts_by_block(&self, block_number: BlockNumber) -> &[Option] { + let Some(index) = self.block_number_to_index(block_number) else { return &[] }; + &self.receipts[index] + } + + /// Is bundle state empty of blocks. + pub fn is_empty(&self) -> bool { + self.len() == 0 + } + + /// Number of blocks in bundle state. + pub fn len(&self) -> usize { + self.receipts.len() + } + + /// Return first block of the bundle + pub fn first_block(&self) -> BlockNumber { + self.first_block + } + + /// Revert the state to the given block number. + /// + /// Returns false if the block number is not in the bundle state. + /// + /// # Note + /// + /// The provided block number will stay inside the bundle state. + pub fn revert_to(&mut self, block_number: BlockNumber) -> bool { + let Some(index) = self.block_number_to_index(block_number) else { return false }; + + // +1 is for number of blocks that we have as index is included. + let new_len = index + 1; + let rm_trx: usize = self.len() - new_len; + + // remove receipts + self.receipts.truncate(new_len); + // Revert last n reverts. + self.bundle.revert(rm_trx); + + true + } + + /// Splits the block range state at a given block number. + /// Returns two split states ([..at], [at..]). + /// The plain state of the 2nd bundle state will contain extra changes + /// that were made in state transitions belonging to the lower state. + /// + /// # Panics + /// + /// If the target block number is not included in the state block range. + pub fn split_at(self, at: BlockNumber) -> (Option, Self) { + if at == self.first_block { + return (None, self) + } + + let (mut lower_state, mut higher_state) = (self.clone(), self); + + // Revert lower state to [..at]. + lower_state.revert_to(at.checked_sub(1).unwrap()); + + // Truncate higher state to [at..]. + let at_idx = higher_state.block_number_to_index(at).unwrap(); + higher_state.receipts = Receipts::from_vec(higher_state.receipts.split_off(at_idx)); + higher_state.bundle.take_n_reverts(at_idx); + higher_state.first_block = at; + + (Some(lower_state), higher_state) + } + + /// Extend one state from another + /// + /// For state this is very sensitive operation and should be used only when + /// we know that other state was build on top of this one. + /// In most cases this would be true. + pub fn extend(&mut self, other: Self) { + self.bundle.extend(other.bundle); + self.receipts.extend(other.receipts.receipt_vec); + } + + /// Prepends present the state with the given BundleState. + /// It adds changes from the given state but does not override any existing changes. + /// + /// Reverts and receipts are not updated. + pub fn prepend_state(&mut self, mut other: BundleState) { + let other_len = other.reverts.len(); + // take this bundle + let this_bundle = std::mem::take(&mut self.bundle); + // extend other bundle with this + other.extend(this_bundle); + // discard other reverts + other.take_n_reverts(other_len); + // swap bundles + std::mem::swap(&mut self.bundle, &mut other) + } +} diff --git a/crates/evm/execution-types/src/lib.rs b/crates/evm/execution-types/src/lib.rs new file mode 100644 index 000000000..576913997 --- /dev/null +++ b/crates/evm/execution-types/src/lib.rs @@ -0,0 +1,12 @@ +//! Commonly used types for (EVM) block execution. + +#![doc( + html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", + html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", + issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" +)] +#![cfg_attr(not(test), warn(unused_crate_dependencies))] +#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] + +mod bundle; +pub use bundle::*; diff --git a/crates/storage/provider/Cargo.toml b/crates/storage/provider/Cargo.toml index c9eb5f7e3..d7cc0280f 100644 --- a/crates/storage/provider/Cargo.toml +++ b/crates/storage/provider/Cargo.toml @@ -15,6 +15,7 @@ workspace = true # reth reth-blockchain-tree-api.workspace = true reth-execution-errors.workspace = true +reth-execution-types.workspace = true reth-primitives.workspace = true reth-fs-util.workspace = true reth-storage-errors.workspace = true @@ -68,4 +69,4 @@ rand.workspace = true [features] test-utils = ["alloy-rlp", "reth-db/test-utils", "reth-nippy-jar/test-utils"] -optimism = ["reth-primitives/optimism"] +optimism = ["reth-primitives/optimism", "reth-execution-types/optimism"] diff --git a/crates/storage/provider/src/bundle_state/bundle_state_with_receipts.rs b/crates/storage/provider/src/bundle_state/bundle_state_with_receipts.rs index 52c9366fd..931194d89 100644 --- a/crates/storage/provider/src/bundle_state/bundle_state_with_receipts.rs +++ b/crates/storage/provider/src/bundle_state/bundle_state_with_receipts.rs @@ -7,311 +7,11 @@ use reth_db::{ tables, transaction::{DbTx, DbTxMut}, }; -use reth_evm::execute::BatchBlockExecutionOutput; -use reth_primitives::{ - logs_bloom, - revm::compat::{into_reth_acc, into_revm_acc}, - Account, Address, BlockHash, BlockNumber, Bloom, Bytecode, Log, Receipt, Receipts, - StaticFileSegment, StorageEntry, B256, U256, -}; +use reth_primitives::{BlockHash, BlockNumber, StaticFileSegment}; use reth_storage_errors::provider::{ProviderError, ProviderResult}; -use reth_trie::HashedPostState; + +pub use reth_execution_types::*; pub use revm::db::states::OriginalValuesKnown; -use revm::{ - db::{states::BundleState, BundleAccount}, - primitives::AccountInfo, -}; -use std::collections::HashMap; - -/// Bundle state of post execution changes and reverts -#[derive(Default, Debug, Clone, PartialEq, Eq)] -pub struct BundleStateWithReceipts { - /// Bundle state with reverts. - bundle: BundleState, - /// The collection of receipts. - /// Outer vector stores receipts for each block sequentially. - /// The inner vector stores receipts ordered by transaction number. - /// - /// If receipt is None it means it is pruned. - receipts: Receipts, - /// First block of bundle state. - first_block: BlockNumber, -} - -// TODO(mattsse): unify the types, currently there's a cyclic dependency between -impl From for BundleStateWithReceipts { - fn from(value: BatchBlockExecutionOutput) -> Self { - let BatchBlockExecutionOutput { bundle, receipts, first_block } = value; - Self { bundle, receipts, first_block } - } -} - -// TODO(mattsse): unify the types, currently there's a cyclic dependency between -impl From for BatchBlockExecutionOutput { - fn from(value: BundleStateWithReceipts) -> Self { - let BundleStateWithReceipts { bundle, receipts, first_block } = value; - Self { bundle, receipts, first_block } - } -} - -/// Type used to initialize revms bundle state. -pub type BundleStateInit = - HashMap, Option, HashMap)>; - -/// Types used inside RevertsInit to initialize revms reverts. -pub type AccountRevertInit = (Option>, Vec); - -/// Type used to initialize revms reverts. -pub type RevertsInit = HashMap>; - -impl BundleStateWithReceipts { - /// Create Bundle State. - pub fn new(bundle: BundleState, receipts: Receipts, first_block: BlockNumber) -> Self { - Self { bundle, receipts, first_block } - } - - /// Create new bundle state with receipts. - pub fn new_init( - state_init: BundleStateInit, - revert_init: RevertsInit, - contracts_init: Vec<(B256, Bytecode)>, - receipts: Receipts, - first_block: BlockNumber, - ) -> Self { - // sort reverts by block number - let mut reverts = revert_init.into_iter().collect::>(); - reverts.sort_unstable_by_key(|a| a.0); - - // initialize revm bundle - let bundle = BundleState::new( - state_init.into_iter().map(|(address, (original, present, storage))| { - ( - address, - original.map(into_revm_acc), - present.map(into_revm_acc), - storage.into_iter().map(|(k, s)| (k.into(), s)).collect(), - ) - }), - reverts.into_iter().map(|(_, reverts)| { - // does not needs to be sorted, it is done when taking reverts. - reverts.into_iter().map(|(address, (original, storage))| { - ( - address, - original.map(|i| i.map(into_revm_acc)), - storage.into_iter().map(|entry| (entry.key.into(), entry.value)), - ) - }) - }), - contracts_init.into_iter().map(|(code_hash, bytecode)| (code_hash, bytecode.0)), - ); - - Self { bundle, receipts, first_block } - } - - /// Return revm bundle state. - pub fn state(&self) -> &BundleState { - &self.bundle - } - - /// Returns mutable revm bundle state. - pub fn state_mut(&mut self) -> &mut BundleState { - &mut self.bundle - } - - /// Set first block. - pub fn set_first_block(&mut self, first_block: BlockNumber) { - self.first_block = first_block; - } - - /// Return iterator over all accounts - pub fn accounts_iter(&self) -> impl Iterator)> { - self.bundle.state().iter().map(|(a, acc)| (*a, acc.info.as_ref())) - } - - /// Return iterator over all [BundleAccount]s in the bundle - pub fn bundle_accounts_iter(&self) -> impl Iterator { - self.bundle.state().iter().map(|(a, acc)| (*a, acc)) - } - - /// Get account if account is known. - pub fn account(&self, address: &Address) -> Option> { - self.bundle.account(address).map(|a| a.info.clone().map(into_reth_acc)) - } - - /// Get storage if value is known. - /// - /// This means that depending on status we can potentially return U256::ZERO. - pub fn storage(&self, address: &Address, storage_key: U256) -> Option { - self.bundle.account(address).and_then(|a| a.storage_slot(storage_key)) - } - - /// Return bytecode if known. - pub fn bytecode(&self, code_hash: &B256) -> Option { - self.bundle.bytecode(code_hash).map(Bytecode) - } - - /// Returns [HashedPostState] for this bundle state. - /// See [HashedPostState::from_bundle_state] for more info. - pub fn hash_state_slow(&self) -> HashedPostState { - HashedPostState::from_bundle_state(&self.bundle.state) - } - - /// Transform block number to the index of block. - fn block_number_to_index(&self, block_number: BlockNumber) -> Option { - if self.first_block > block_number { - return None - } - let index = block_number - self.first_block; - if index >= self.receipts.len() as u64 { - return None - } - Some(index as usize) - } - - /// Returns an iterator over all block logs. - pub fn logs(&self, block_number: BlockNumber) -> Option> { - let index = self.block_number_to_index(block_number)?; - Some(self.receipts[index].iter().filter_map(|r| Some(r.as_ref()?.logs.iter())).flatten()) - } - - /// Return blocks logs bloom - pub fn block_logs_bloom(&self, block_number: BlockNumber) -> Option { - Some(logs_bloom(self.logs(block_number)?)) - } - - /// Returns the receipt root for all recorded receipts. - /// Note: this function calculated Bloom filters for every receipt and created merkle trees - /// of receipt. This is a expensive operation. - pub fn receipts_root_slow(&self, _block_number: BlockNumber) -> Option { - #[cfg(feature = "optimism")] - panic!("This should not be called in optimism mode. Use `optimism_receipts_root_slow` instead."); - #[cfg(not(feature = "optimism"))] - self.receipts.root_slow(self.block_number_to_index(_block_number)?) - } - - /// Returns the receipt root for all recorded receipts. - /// Note: this function calculated Bloom filters for every receipt and created merkle trees - /// of receipt. This is a expensive operation. - #[cfg(feature = "optimism")] - pub fn optimism_receipts_root_slow( - &self, - block_number: BlockNumber, - chain_spec: &reth_primitives::ChainSpec, - timestamp: u64, - ) -> Option { - self.receipts.optimism_root_slow( - self.block_number_to_index(block_number)?, - chain_spec, - timestamp, - ) - } - - /// Returns reference to receipts. - pub fn receipts(&self) -> &Receipts { - &self.receipts - } - - /// Returns mutable reference to receipts. - pub fn receipts_mut(&mut self) -> &mut Receipts { - &mut self.receipts - } - - /// Return all block receipts - pub fn receipts_by_block(&self, block_number: BlockNumber) -> &[Option] { - let Some(index) = self.block_number_to_index(block_number) else { return &[] }; - &self.receipts[index] - } - - /// Is bundle state empty of blocks. - pub fn is_empty(&self) -> bool { - self.len() == 0 - } - - /// Number of blocks in bundle state. - pub fn len(&self) -> usize { - self.receipts.len() - } - - /// Return first block of the bundle - pub fn first_block(&self) -> BlockNumber { - self.first_block - } - - /// Revert the state to the given block number. - /// - /// Returns false if the block number is not in the bundle state. - /// - /// # Note - /// - /// The provided block number will stay inside the bundle state. - pub fn revert_to(&mut self, block_number: BlockNumber) -> bool { - let Some(index) = self.block_number_to_index(block_number) else { return false }; - - // +1 is for number of blocks that we have as index is included. - let new_len = index + 1; - let rm_trx: usize = self.len() - new_len; - - // remove receipts - self.receipts.truncate(new_len); - // Revert last n reverts. - self.bundle.revert(rm_trx); - - true - } - - /// Splits the block range state at a given block number. - /// Returns two split states ([..at], [at..]). - /// The plain state of the 2nd bundle state will contain extra changes - /// that were made in state transitions belonging to the lower state. - /// - /// # Panics - /// - /// If the target block number is not included in the state block range. - pub fn split_at(self, at: BlockNumber) -> (Option, Self) { - if at == self.first_block { - return (None, self) - } - - let (mut lower_state, mut higher_state) = (self.clone(), self); - - // Revert lower state to [..at]. - lower_state.revert_to(at.checked_sub(1).unwrap()); - - // Truncate higher state to [at..]. - let at_idx = higher_state.block_number_to_index(at).unwrap(); - higher_state.receipts = Receipts::from_vec(higher_state.receipts.split_off(at_idx)); - higher_state.bundle.take_n_reverts(at_idx); - higher_state.first_block = at; - - (Some(lower_state), higher_state) - } - - /// Extend one state from another - /// - /// For state this is very sensitive operation and should be used only when - /// we know that other state was build on top of this one. - /// In most cases this would be true. - pub fn extend(&mut self, other: Self) { - self.bundle.extend(other.bundle); - self.receipts.extend(other.receipts.receipt_vec); - } - - /// Prepends present the state with the given BundleState. - /// It adds changes from the given state but does not override any existing changes. - /// - /// Reverts and receipts are not updated. - pub fn prepend_state(&mut self, mut other: BundleState) { - let other_len = other.reverts.len(); - // take this bundle - let this_bundle = std::mem::take(&mut self.bundle); - // extend other bundle with this - other.extend(this_bundle); - // discard other reverts - other.take_n_reverts(other_len); - // swap bundles - std::mem::swap(&mut self.bundle, &mut other) - } -} impl StateWriter for BundleStateWithReceipts { fn write_to_storage( @@ -380,29 +80,37 @@ impl BundleStateDataProvider for BundleStateWithReceipts { #[cfg(test)] mod tests { - use super::*; - use crate::{test_utils::create_test_provider_factory, AccountReader}; - use reth_db::{ - cursor::DbDupCursorRO, - database::Database, - models::{AccountBeforeTx, BlockNumberAddress}, - test_utils::create_test_rw_db, - }; - use reth_primitives::keccak256; - use reth_trie::{test_utils::state_root, StateRoot}; + use std::collections::{BTreeMap, HashMap}; + use revm::{ db::{ states::{ bundle_state::BundleRetention, changes::PlainStorageRevert, PlainStorageChangeset, }, - EmptyDB, + BundleState, EmptyDB, }, primitives::{ Account as RevmAccount, AccountInfo as RevmAccountInfo, AccountStatus, StorageSlot, }, DatabaseCommit, State, }; - use std::collections::BTreeMap; + + use reth_db::{ + cursor::DbDupCursorRO, + database::Database, + models::{AccountBeforeTx, BlockNumberAddress}, + test_utils::create_test_rw_db, + }; + use reth_primitives::{ + keccak256, + revm::compat::{into_reth_acc, into_revm_acc}, + Account, Address, Receipt, Receipts, StorageEntry, B256, U256, + }; + use reth_trie::{test_utils::state_root, StateRoot}; + + use crate::{test_utils::create_test_provider_factory, AccountReader}; + + use super::*; #[test] fn write_to_db_account_info() {