pub struct TrieDB<F, H>where
F: TrieDBProvider,
H: TrieHinter,{
pub fetcher: F,
pub hinter: H,
/* private fields */
}Expand description
A Trie DB that caches open state in-memory.
When accounts that don’t already exist within the cached TrieNode are queried, the database
fetches the preimages of the trie nodes on the path to the account using the PreimageFetcher
(F generic). This allows for data to be fetched in a verifiable manner given an initial
trusted state root as it is needed during execution.
The TrieDB is intended to be wrapped by a State, which is then used by revm to
capture state transitions during block execution.
Behavior:
- When an account is queried and the trie path has not already been opened by Self::basic, we
fall through to the
PreimageFetcherto fetch the preimages of the trie nodes on the path to the account. After it has been fetched, the path will be cached until the next call to Self::state_root. - When querying for the code hash of an account, the
TrieDBProvideris consulted to fetch the code hash of the account. - When a
BundleStatechangeset is committed to the parentStatedatabase, the changes are first applied to theState’s cache, then the trie hash is recomputed with Self::state_root. - When the block hash of a block number is needed via Self::block_hash, the
HeaderByHashFetcheris consulted to walk back to the desired block number by revealing the parent hash of block headers until the desired block number is reached, up to a maximum of BLOCK_HASH_HISTORY blocks back relative to the current parent block hash.
Example Construction:
use alloy_consensus::{Header, Sealable};
use alloy_evm::{EvmEnv, EvmFactory, block::BlockExecutorFactory};
use alloy_op_evm::{
OpBlockExecutionCtx, OpBlockExecutorFactory, OpEvmFactory, block::OpAlloyReceiptBuilder,
};
use alloy_op_hardforks::OpChainHardforks;
use alloy_primitives::{B256, Bytes};
use kona_executor::{NoopTrieDBProvider, TrieDB};
use kona_mpt::NoopTrieHinter;
use revm::database::{State, states::bundle_state::BundleRetention};
let mock_parent_block_header = Header::default();
let trie_db =
TrieDB::new(mock_parent_block_header.seal_slow(), NoopTrieDBProvider, NoopTrieHinter);
let executor_factory = OpBlockExecutorFactory::new(
OpAlloyReceiptBuilder::default(),
OpChainHardforks::op_mainnet(),
OpEvmFactory::default(),
);
let mut state = State::builder().with_database(trie_db).with_bundle_update().build();
let evm = executor_factory.evm_factory().create_evm(&mut state, EvmEnv::default());
let executor = executor_factory.create_executor(evm, OpBlockExecutionCtx::default());
// Execute your block's transactions...
drop(executor);
state.merge_transitions(BundleRetention::Reverts);
let bundle = state.take_bundle();
let state_root = state.database.state_root(&bundle).expect("Failed to compute state root");Fields§
§fetcher: FThe TrieDBProvider
hinter: HThe TrieHinter
Implementations§
Source§impl<F, H> TrieDB<F, H>where
F: TrieDBProvider,
H: TrieHinter,
impl<F, H> TrieDB<F, H>where
F: TrieDBProvider,
H: TrieHinter,
Sourcepub fn new(parent_block_header: Sealed<Header>, fetcher: F, hinter: H) -> Self
pub fn new(parent_block_header: Sealed<Header>, fetcher: F, hinter: H) -> Self
Creates a new TrieDB with the given root node.
Sourcepub fn take_root_node(self) -> TrieNode
pub fn take_root_node(self) -> TrieNode
Consumes Self and takes the current state root of the trie DB.
Sourcepub const fn root(&self) -> &TrieNode
pub const fn root(&self) -> &TrieNode
Returns a shared reference to the root TrieNode of the trie DB.
Sourcepub const fn storage_roots(&self) -> &HashMap<Address, TrieNode>
pub const fn storage_roots(&self) -> &HashMap<Address, TrieNode>
Returns the mapping of Addresses to storage roots.
Sourcepub const fn parent_block_header(&self) -> &Sealed<Header>
pub const fn parent_block_header(&self) -> &Sealed<Header>
Returns a reference to the current parent block header of the trie DB.
Sourcepub fn set_parent_block_header(&mut self, parent_block_header: Sealed<Header>)
pub fn set_parent_block_header(&mut self, parent_block_header: Sealed<Header>)
Sets the parent block header of the trie DB. Should be called after a block has been executed and the Header has been created.
§Takes
parent_block_header: The parent block header of the current block.
Sourcepub fn state_root(&mut self, bundle: &BundleState) -> TrieDBResult<B256>
pub fn state_root(&mut self, bundle: &BundleState) -> TrieDBResult<B256>
Applies a BundleState changeset to the TrieNode and recomputes the state root hash.
§Takes
bundle: The BundleState changeset to apply to the trie DB.
§Returns
Ok(B256): The new state root hash of the trie DB.Err(_): If the state root hash could not be computed.
Sourcepub fn get_trie_account(
&mut self,
address: &Address,
block_number: u64,
) -> TrieDBResult<Option<TrieAccount>>
pub fn get_trie_account( &mut self, address: &Address, block_number: u64, ) -> TrieDBResult<Option<TrieAccount>>
Fetches the TrieAccount of an account from the trie DB.
§Takes
address: The address of the account.
§Returns
Ok(Some(TrieAccount)): The TrieAccount of the account.Ok(None): If the account does not exist in the trie.Err(_): If the account could not be fetched.
Trait Implementations§
Source§impl<F, H> Database for TrieDB<F, H>where
F: TrieDBProvider,
H: TrieHinter,
impl<F, H> Database for TrieDB<F, H>where
F: TrieDBProvider,
H: TrieHinter,
Source§type Error = TrieDBError
type Error = TrieDBError
Source§fn basic(
&mut self,
address: Address,
) -> Result<Option<AccountInfo>, Self::Error>
fn basic( &mut self, address: Address, ) -> Result<Option<AccountInfo>, Self::Error>
Source§fn code_by_hash(&mut self, code_hash: B256) -> Result<Bytecode, Self::Error>
fn code_by_hash(&mut self, code_hash: B256) -> Result<Bytecode, Self::Error>
Auto Trait Implementations§
impl<F, H> !Freeze for TrieDB<F, H>
impl<F, H> RefUnwindSafe for TrieDB<F, H>where
F: RefUnwindSafe,
H: RefUnwindSafe,
impl<F, H> Send for TrieDB<F, H>
impl<F, H> Sync for TrieDB<F, H>
impl<F, H> Unpin for TrieDB<F, H>
impl<F, H> UnwindSafe for TrieDB<F, H>where
F: UnwindSafe,
H: UnwindSafe,
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> FmtForward for T
impl<T> FmtForward for T
Source§fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
self to use its Binary implementation when Debug-formatted.Source§fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
self to use its Display implementation when
Debug-formatted.Source§fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
self to use its LowerExp implementation when
Debug-formatted.Source§fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
self to use its LowerHex implementation when
Debug-formatted.Source§fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
self to use its Octal implementation when Debug-formatted.Source§fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
self to use its Pointer implementation when
Debug-formatted.Source§fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
self to use its UpperExp implementation when
Debug-formatted.Source§fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
self to use its UpperHex implementation when
Debug-formatted.Source§impl<TxEnv, T> FromRecoveredTx<&T> for TxEnvwhere
TxEnv: FromRecoveredTx<T>,
impl<TxEnv, T> FromRecoveredTx<&T> for TxEnvwhere
TxEnv: FromRecoveredTx<T>,
Source§impl<TxEnv, T> FromTxWithEncoded<&T> for TxEnvwhere
TxEnv: FromTxWithEncoded<T>,
impl<TxEnv, T> FromTxWithEncoded<&T> for TxEnvwhere
TxEnv: FromTxWithEncoded<T>,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
Source§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
Source§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read moreSource§fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read moreSource§fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
Source§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R,
) -> R
fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
Source§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
self, then passes self.as_ref() into the pipe function.Source§fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
self, then passes self.as_mut() into the pipe
function.Source§fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
self, then passes self.deref() into the pipe function.Source§impl<T> Tap for T
impl<T> Tap for T
Source§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
Borrow<B> of a value. Read moreSource§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
BorrowMut<B> of a value. Read moreSource§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
AsRef<R> view of a value. Read moreSource§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
AsMut<R> view of a value. Read moreSource§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
Deref::Target of a value. Read moreSource§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
Deref::Target of a value. Read moreSource§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
.tap() only in debug builds, and is erased in release builds.Source§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
.tap_mut() only in debug builds, and is erased in release
builds.Source§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
.tap_borrow() only in debug builds, and is erased in release
builds.Source§fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
.tap_borrow_mut() only in debug builds, and is erased in release
builds.Source§fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
.tap_ref() only in debug builds, and is erased in release
builds.Source§fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
.tap_ref_mut() only in debug builds, and is erased in release
builds.Source§fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
.tap_deref() only in debug builds, and is erased in release
builds.