Skip to content
Open
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
52 changes: 48 additions & 4 deletions crates/evm/src/block/state.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,53 @@
//! State database abstraction.

use core::fmt::Debug;
use revm::{
database::{states::bundle_state::BundleRetention, BundleState, State},
DatabaseCommit,
};

use crate::Database;
use revm::DatabaseCommit;

/// Alias trait for [`Database`] and [`DatabaseCommit`].
pub trait StateDB: Database + DatabaseCommit {}
/// A type which has the state of the blockchain.
///
/// This trait encapsulates some of the functionality found in [`State`]
#[auto_impl::auto_impl(&mut, Box)]
pub trait StateDB: Database + DatabaseCommit {
/// Gets a reference to the internal [`BundleState`]
fn bundle_state(&self) -> &BundleState;

/// Gets a mutable reference to the internal [`BundleState`]
fn bundle_state_mut(&mut self) -> &mut BundleState;

/// This will not apply any pending [`revm::database::TransitionState`].
///
/// It is recommended to call [`StateDB::merge_transitions`] before taking the bundle.
///
/// If the `State` has been built with the
/// [`revm::database::StateBuilder::with_bundle_prestate`] option, the pre-state will be
/// taken along with any changes made by [`StateDB::merge_transitions`].
fn take_bundle(&mut self) -> BundleState {
core::mem::take(self.bundle_state_mut())
}

/// Take all transitions and merge them inside [`BundleState`].
///
/// This action will create final post state and all reverts so that
/// we at any time revert state of bundle to the state before transition
/// is applied.
fn merge_transitions(&mut self, retention: BundleRetention);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it is not entirely clear to me why this abstraction is needed, what is your usecase? right now basic block executors are already agnostic of concrete db

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@klkvr did you miss this comment?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need this abstraction because our access list block builder needs to be able to wrap revm::State

Copy link
Member

@klkvr klkvr Mar 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah yep sorry missed it, just to confirm — you need this so that your custom block builder can use BasicBlockBuilder::finish API directly instead of duplicating the logic?

i'm quite happy with the way current abstraction works in a sense that it allows any database to be used for a BlockExecutor. if we need an additional abstraction for State db specific methods i'd prefer it to not affect BlockExecutorFactory trait at all but instead only be used for the reth's block builder construction methods

i'd be open to moving StateDB trait entirely into reth for this

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not entirely sure what you're suggesting. We already have StateDB used in the BlockExecutor impls. What is your reasoning for not wanting this? The previous implementation relied directly on revm::State, which is strictly less flexible.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yep and current implementation works with any database which is very flexible which is why I'm a bit hesitant on making it stricter


impl<DB: revm::Database + Debug> StateDB for State<DB> {
fn bundle_state(&self) -> &BundleState {
&self.bundle_state
}

fn bundle_state_mut(&mut self) -> &mut BundleState {
&mut self.bundle_state
}

impl<T> StateDB for T where T: Database + DatabaseCommit {}
fn merge_transitions(&mut self, retention: BundleRetention) {
Self::merge_transitions(self, retention);
}
}