pub struct LEVM;Expand description
The struct implements the following functions: LEVM::execute_block LEVM::execute_tx LEVM::get_state_transitions LEVM::process_withdrawals
Implementations§
Source§impl LEVM
impl LEVM
Sourcepub fn rerun_block(
db: &mut GeneralizedDatabase,
block: &Block,
stop_index: Option<usize>,
vm_type: VMType,
crypto: &dyn Crypto,
) -> Result<(), EvmError>
pub fn rerun_block( db: &mut GeneralizedDatabase, block: &Block, stop_index: Option<usize>, vm_type: VMType, crypto: &dyn Crypto, ) -> Result<(), EvmError>
Execute all transactions of the block up until a certain transaction specified in stop_index.
The goal is to just mutate the state up to that point, without needing to process transaction receipts or requests.
Sourcepub fn trace_tx_prestate(
db: &mut GeneralizedDatabase,
block_header: &BlockHeader,
tx: &Transaction,
diff_mode: bool,
include_empty: bool,
vm_type: VMType,
crypto: &dyn Crypto,
) -> Result<PrestateResult, EvmError>
pub fn trace_tx_prestate( db: &mut GeneralizedDatabase, block_header: &BlockHeader, tx: &Transaction, diff_mode: bool, include_empty: bool, vm_type: VMType, crypto: &dyn Crypto, ) -> Result<PrestateResult, EvmError>
Executes tx and returns the prestateTracer result. diff_mode toggles between
pre-only and pre+post output. include_empty keeps entries that would otherwise
be all-default (must be false in diff mode). Assumes db already reflects all
prior txs in the block.
Sourcepub fn trace_tx_opcodes(
db: &mut GeneralizedDatabase,
block_header: &BlockHeader,
tx: &Transaction,
cfg: OpcodeTracerConfig,
vm_type: VMType,
crypto: &dyn Crypto,
) -> Result<OpcodeTraceResult, EvmError>
pub fn trace_tx_opcodes( db: &mut GeneralizedDatabase, block_header: &BlockHeader, tx: &Transaction, cfg: OpcodeTracerConfig, vm_type: VMType, crypto: &dyn Crypto, ) -> Result<OpcodeTraceResult, EvmError>
Run transaction with opcode (EIP-3155) tracer activated.
Sourcepub fn trace_tx_calls(
db: &mut GeneralizedDatabase,
block_header: &BlockHeader,
tx: &Transaction,
only_top_call: bool,
with_log: bool,
vm_type: VMType,
crypto: &dyn Crypto,
) -> Result<CallTrace, EvmError>
pub fn trace_tx_calls( db: &mut GeneralizedDatabase, block_header: &BlockHeader, tx: &Transaction, only_top_call: bool, with_log: bool, vm_type: VMType, crypto: &dyn Crypto, ) -> Result<CallTrace, EvmError>
Run transaction with callTracer activated.
Source§impl LEVM
impl LEVM
Sourcepub fn execute_block(
block: &Block,
db: &mut GeneralizedDatabase,
vm_type: VMType,
crypto: &dyn Crypto,
) -> Result<(BlockExecutionResult, Option<BlockAccessList>), EvmError>
pub fn execute_block( block: &Block, db: &mut GeneralizedDatabase, vm_type: VMType, crypto: &dyn Crypto, ) -> Result<(BlockExecutionResult, Option<BlockAccessList>), EvmError>
Execute a block and return the execution result.
Also records and returns the Block Access List (EIP-7928) for Amsterdam+ forks.
The BAL will be None for pre-Amsterdam forks.
Sourcepub fn execute_block_pipeline(
block: &Block,
db: &mut GeneralizedDatabase,
vm_type: VMType,
merkleizer: Option<Sender<Vec<AccountUpdate>>>,
queue_length: &AtomicUsize,
crypto: &dyn Crypto,
header_bal: Option<Arc<BlockAccessList>>,
bal_parallel_exec_enabled: bool,
) -> Result<(BlockExecutionResult, Option<BlockAccessList>), EvmError>
pub fn execute_block_pipeline( block: &Block, db: &mut GeneralizedDatabase, vm_type: VMType, merkleizer: Option<Sender<Vec<AccountUpdate>>>, queue_length: &AtomicUsize, crypto: &dyn Crypto, header_bal: Option<Arc<BlockAccessList>>, bal_parallel_exec_enabled: bool, ) -> Result<(BlockExecutionResult, Option<BlockAccessList>), EvmError>
merkleizer is Some on the streaming (non-BAL) path; the BAL validation path
passes None because the caller merkleizes optimistically from the input BAL and
the EVM-side bal_to_account_updates send is then redundant work.
Sourcepub fn validate_tx_execution(
bal_idx: u32,
seed_idx: u32,
current_state: &FxHashMap<Address, LevmAccount>,
codes: &FxHashMap<H256, Code>,
bal: &BlockAccessList,
index: &BalAddressIndex,
system_seed: &CacheDB,
store: &Arc<dyn Database>,
pure_reads: &FxHashSet<(Address, U256)>,
tx_initial: &FxHashMap<(Address, U256), U256>,
) -> Result<(), BalValidationError>
pub fn validate_tx_execution( bal_idx: u32, seed_idx: u32, current_state: &FxHashMap<Address, LevmAccount>, codes: &FxHashMap<H256, Code>, bal: &BlockAccessList, index: &BalAddressIndex, system_seed: &CacheDB, store: &Arc<dyn Database>, pure_reads: &FxHashSet<(Address, U256)>, tx_initial: &FxHashMap<(Address, U256), U256>, ) -> Result<(), BalValidationError>
Validates that a tx’s post-execution state matches BAL claims.
Replaces the previous snapshot->diff->validate approach:
- No HashMap clone needed (reconstructs seeded values from BAL)
- Uses pre-built index for O(1) account lookups
- Uses binary search on sorted change lists
bal_idx: block_access_index for this tx (tx_idx + 1)
seed_idx: max BAL index used for seeding (= tx_idx = bal_idx - 1)
current_state: post-execution account state from per-tx DB
codes: code cache from per-tx DB (for code change validation)
bal: the block access list
index: pre-built validation index
system_seed: pre-system-call state snapshot (for extraneous entry detection)
store: database (fallback for pre-state lookups)
pure_reads: slots the shadow recorder observed as pure reads (never
written); the execution->BAL check skips the seeded pre-state lookup for these since a
genuine read cannot diverge from its pre-tx value. Pass an empty set to
validate every slot unconditionally (e.g. from unit tests).
tx_initial: start-of-tx storage values the EVM already captured for
written slots ((addr, slot) -> pre_value); used as the storage seed
fast-path so seeded_storage avoids a store read. Pass an empty map to
force the store fallback (e.g. from unit tests).
Exposed as pub (rather than crate-private) solely so the direct
validate_tx_execution unit tests in the ethrex-test crate
(test/tests/blockchain/bal_validate_tx_execution_tests.rs) can call it.
Sourcepub fn warm_block(
block: &Block,
store: Arc<dyn Database>,
vm_type: VMType,
crypto: &dyn Crypto,
cancelled: &AtomicBool,
) -> Result<(), EvmError>
pub fn warm_block( block: &Block, store: Arc<dyn Database>, vm_type: VMType, crypto: &dyn Crypto, cancelled: &AtomicBool, ) -> Result<(), EvmError>
Pre-warms state by executing all transactions in parallel, grouped by sender.
The store parameter should be a CachingDatabase-wrapped store so that
parallel workers can benefit from shared caching. The same cache should
be used by the sequential execution phase.
Sourcepub fn warm_txs(
txs_with_sender: &[(&Transaction, Address)],
header: &BlockHeader,
store: Arc<dyn Database>,
vm_type: VMType,
crypto: &dyn Crypto,
should_stop: &(dyn Fn() -> bool + Sync),
) -> Result<(), EvmError>
pub fn warm_txs( txs_with_sender: &[(&Transaction, Address)], header: &BlockHeader, store: Arc<dyn Database>, vm_type: VMType, crypto: &dyn Crypto, should_stop: &(dyn Fn() -> bool + Sync), ) -> Result<(), EvmError>
Speculatively executes an arbitrary transaction set against header’s
parent state to warm shared caches (used by the mempool prewarmer and
warm_block). Sequential within a sender group, parallel across groups.
should_stop is polled before each sender group and again before each
transaction, so cancellation latency is bounded by one transaction’s
execution. Execution results are discarded — only cache population
matters.
Sourcepub fn bal_storage_slots(bal: &BlockAccessList) -> Vec<(Address, H256)>
pub fn bal_storage_slots(bal: &BlockAccessList) -> Vec<(Address, H256)>
Flattened (address, slot) storage worklist for a BAL, in natural account order (slots grouped per account for storage-trie locality).
Sourcepub fn warm_block_from_bal(
bal: &BlockAccessList,
store: Arc<dyn Database>,
cancelled: &AtomicBool,
) -> Result<(), EvmError>
pub fn warm_block_from_bal( bal: &BlockAccessList, store: Arc<dyn Database>, cancelled: &AtomicBool, ) -> Result<(), EvmError>
Concurrent block warmer for the BAL path: prefetches account states and contract code while execution runs.
Storage slots are deliberately NOT warmed here. They are prefetched
synchronously before the executor starts (see bal_storage_slots and the
call site in blockchain.rs); warming them concurrently here let the
executor race the warmer to the trie for SSTORE original values and cost
~22% of CPU. Keep storage warming synchronous and up front.
pub fn execute_tx( tx: &Transaction, tx_sender: Address, block_header: &BlockHeader, db: &mut GeneralizedDatabase, vm_type: VMType, crypto: &dyn Crypto, ) -> Result<ExecutionReport, EvmError>
pub fn undo_last_tx(db: &mut GeneralizedDatabase) -> Result<(), EvmError>
pub fn simulate_tx_from_generic( tx: &GenericTransaction, block_header: &BlockHeader, db: &mut GeneralizedDatabase, vm_type: VMType, crypto: &dyn Crypto, ) -> Result<ExecutionResult, EvmError>
Sourcepub fn simulate_frame_validation_prefix(
tx: &Transaction,
block_header: &BlockHeader,
db: &mut GeneralizedDatabase,
vm_type: VMType,
crypto: &dyn Crypto,
prefix: &ValidationPrefix,
_canonical_paymaster_code_hash: Option<H256>,
) -> Result<FrameValidationOutcome, EvmError>
pub fn simulate_frame_validation_prefix( tx: &Transaction, block_header: &BlockHeader, db: &mut GeneralizedDatabase, vm_type: VMType, crypto: &dyn Crypto, prefix: &ValidationPrefix, _canonical_paymaster_code_hash: Option<H256>, ) -> Result<FrameValidationOutcome, EvmError>
EIP-8141 mempool validation-prefix simulation (local peer policy, never
consensus). Builds a VM like LEVM::execute_tx over a fresh
simulation database, activates the [ValidationObserver] for the
transaction’s sender, runs ONLY the validation-prefix frames, and applies
the admission assertions:
- no prefix frame reverted;
- each verify/pay frame that must APPROVE did (the prefix established a payer);
- the deploy frame (if any) left non-empty code at the sender;
- total simulated prefix gas <= MAX_VERIFY_GAS;
- no validation-trace rule was violated.
canonical_paymaster_code_hash is the pinned canonical paymaster code
hash, when known (always None today, OQ1).
pub fn get_state_transitions( db: &mut GeneralizedDatabase, ) -> Result<Vec<AccountUpdate>, EvmError>
pub fn get_state_transitions_tx( db: &mut GeneralizedDatabase, ) -> Result<Vec<AccountUpdate>, EvmError>
pub fn process_withdrawals( db: &mut GeneralizedDatabase, withdrawals: &[Withdrawal], ) -> Result<(), EvmError>
pub fn beacon_root_contract_call( block_header: &BlockHeader, db: &mut GeneralizedDatabase, vm_type: VMType, crypto: &dyn Crypto, ) -> Result<(), EvmError>
pub fn process_block_hash_history( block_header: &BlockHeader, db: &mut GeneralizedDatabase, vm_type: VMType, crypto: &dyn Crypto, ) -> Result<(), EvmError>
Sourcepub fn install_expiry_verifier_code(
db: &mut GeneralizedDatabase,
crypto: &dyn Crypto,
) -> Result<(), EvmError>
pub fn install_expiry_verifier_code( db: &mut GeneralizedDatabase, crypto: &dyn Crypto, ) -> Result<(), EvmError>
Install the canonical EIP-8141 expiry verifier runtime code at EXPIRY_VERIFIER on Hegota activation (spec commit 0b197156: “At activation, clients must install…”). Idempotent: writes only when the existing code differs, so exactly one account update is produced (at the first Hegota block) and none afterwards.
pub fn create_access_list( tx: GenericTransaction, header: &BlockHeader, db: &mut GeneralizedDatabase, vm_type: VMType, crypto: &dyn Crypto, ) -> Result<(ExecutionResult, AccessList), VMError>
pub fn prepare_block( block: &Block, db: &mut GeneralizedDatabase, vm_type: VMType, crypto: &dyn Crypto, ) -> Result<(), EvmError>
Trait Implementations§
Auto Trait Implementations§
impl Freeze for LEVM
impl RefUnwindSafe for LEVM
impl Send for LEVM
impl Sync for LEVM
impl Unpin for LEVM
impl UnsafeUnpin for LEVM
impl UnwindSafe for LEVM
Blanket Implementations§
Source§impl<T> ArchivePointee for T
impl<T> ArchivePointee for T
Source§type ArchivedMetadata = ()
type ArchivedMetadata = ()
Source§fn pointer_metadata(
_: &<T as ArchivePointee>::ArchivedMetadata,
) -> <T as Pointee>::Metadata
fn pointer_metadata( _: &<T as ArchivePointee>::ArchivedMetadata, ) -> <T as Pointee>::Metadata
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> 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> LayoutRaw for T
impl<T> LayoutRaw for T
Source§fn layout_raw(_: <T as Pointee>::Metadata) -> Result<Layout, LayoutError>
fn layout_raw(_: <T as Pointee>::Metadata) -> Result<Layout, LayoutError>
Source§impl<T, N1, N2> Niching<NichedOption<T, N1>> for N2
impl<T, N1, N2> Niching<NichedOption<T, N1>> for N2
Source§unsafe fn is_niched(niched: *const NichedOption<T, N1>) -> bool
unsafe fn is_niched(niched: *const NichedOption<T, N1>) -> bool
Source§fn resolve_niched(out: Place<NichedOption<T, N1>>)
fn resolve_niched(out: Place<NichedOption<T, N1>>)
out indicating that a T is niched.