Skip to content

Commit 4c4405d

Browse files
authored
docs: improve BlockExecutorFactory and ExecutionCtx documentation (#104)
* docs: improve BlockExecutorFactory and ExecutionCtx documentation Enhanced documentation to better explain the purpose and usage of ExecutionCtx in block execution, with concrete examples from real implementations. Key improvements: - Clarified that ExecutionCtx provides data for system calls outside normal tx execution - Added concrete example from EthBlockExecutionCtx showing actual fields - Explained specific use cases for each field (EIP-2935, EIP-4788, EIP-4895) - Enhanced BlockExecutorFactory trait docs with design philosophy - Improved create_executor docs with practical usage example - Emphasized the separation of concerns between EVM and block execution context This makes it clearer why ExecutionCtx exists separately from EVM's BlockEnv and what kind of data belongs in it. * docs
1 parent 6a7f74e commit 4c4405d

File tree

1 file changed

+86
-8
lines changed

1 file changed

+86
-8
lines changed

crates/evm/src/block/mod.rs

Lines changed: 86 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -301,25 +301,65 @@ where
301301

302302
/// A factory that can create [`BlockExecutor`]s.
303303
///
304-
/// This trait extends [`crate::EvmFactory`] and provides a way to construct a [`BlockExecutor`].
305-
/// Executor is expected to derive most of the context for block execution from the EVM (which
306-
/// includes [`revm::context::BlockEnv`]), and any additional context should be contained in
307-
/// configured [`ExecutionCtx`].
304+
/// This trait serves as the main entry point for block execution, providing a way to construct
305+
/// [`BlockExecutor`] instances with the necessary context. It separates the concerns of:
306+
/// - EVM configuration (handled by [`EvmFactory`])
307+
/// - Block-specific execution context (provided via [`ExecutionCtx`])
308308
///
309-
/// Every block executor factory is expected to contain and expose an [`EvmFactory`] instance.
309+
/// It allows for:
310+
/// - Reusable EVM configuration across multiple block executions
311+
/// - Separation of EVM-related state from block execution state
312+
/// - Flexible instantiation of executors with different contexts
313+
///
314+
/// # Relationship with EvmFactory
315+
///
316+
/// Every block executor factory contains an [`EvmFactory`] instance which handles:
317+
/// - EVM configuration and instantiation
318+
/// - Transaction environment setup
319+
/// - State database management
320+
///
321+
/// The block executor factory extends this by adding block-level execution concerns.
310322
///
311323
/// For more context on the executor design, see the documentation for [`BlockExecutor`].
312324
///
313325
/// [`ExecutionCtx`]: BlockExecutorFactory::ExecutionCtx
326+
/// [`EvmFactory`]: crate::EvmFactory
314327
#[auto_impl::auto_impl(Arc)]
315328
pub trait BlockExecutorFactory: 'static {
316329
/// The EVM factory used by the executor.
317330
type EvmFactory: EvmFactory;
318331

319-
/// Context required for block execution.
332+
/// Context required for block execution beyond what the EVM provides (e.g.
333+
/// [`EvmEnv`](crate::EvmEnv))
334+
///
335+
/// While the EVM contains transaction-level context (gas limits, caller, value) and
336+
/// block-level context (block number, timestamp, base fee), the `ExecutionCtx` provides
337+
/// additional block execution context that is specific to your consensus implementation.
338+
///
339+
/// # Purpose
320340
///
321-
/// This is similar to [`crate::EvmEnv`], but only contains context unrelated to EVM and
322-
/// required for execution of an entire block.
341+
/// This type provides data needed for system calls that occur outside normal transaction
342+
/// execution. Block execution requires additional context for:
343+
/// - **Pre-execution system calls**: Setting up block hash history, beacon block roots
344+
/// - **Post-execution system calls**: Applying block rewards, validator withdrawals
345+
/// - **Consensus-specific data**: Uncle/ommer blocks, L2 data availability info
346+
/// - **Protocol parameters**: Fork-specific rules, precompile configurations
347+
/// - **Precompile metadata**: Context for precompiles that require block-level data (e.g.
348+
/// parameters stored in the block body)
349+
///
350+
/// For example, in Ethereum: [`EthBlockExecutionCtx`](crate::eth::EthBlockExecutionCtx)
351+
/// contains:
352+
/// - Parent block hash for EIP-2935 block hash system call
353+
/// - Parent beacon block root for EIP-4788 beacon root system call
354+
/// - Uncle blocks for handling uncle rewards
355+
/// - Withdrawals for EIP-4895 validator withdrawals
356+
///
357+
/// # Design Considerations
358+
///
359+
/// - Must be [`Clone`] to support creating multiple executors, can use `Cow` borrowed from the
360+
/// block.
361+
/// - Should be lightweight (use references where possible)
362+
/// - Contains only block-level data, not transaction-specific data
323363
type ExecutionCtx<'a>: Clone;
324364

325365
/// Transaction type used by the executor, see [`BlockExecutor::Transaction`].
@@ -336,6 +376,44 @@ pub trait BlockExecutorFactory: 'static {
336376
fn evm_factory(&self) -> &Self::EvmFactory;
337377

338378
/// Creates an executor with given EVM and execution context.
379+
///
380+
/// This method combines:
381+
/// - An EVM instance (already configured with block environment and state)
382+
/// - The execution context (containing additional data for system calls)
383+
///
384+
/// To create a [`BlockExecutor`] that can:
385+
/// 1. Apply pre-execution system calls (e.g., EIP-2935 blockhashes, EIP-4788 beacon roots)
386+
/// 2. Execute transactions
387+
/// 3. Apply post-execution system calls (e.g., withdrawals, rewards)
388+
///
389+
/// # Parameters
390+
///
391+
/// - `evm`: A configured EVM instance with block environment and state
392+
/// - `ctx`: The execution context containing consensus-specific data needed for system calls
393+
///
394+
/// # Example
395+
///
396+
/// ```ignore
397+
/// // Create EVM with block environment
398+
/// let evm = factory.evm_factory().create_evm(block_env, state_db, inspector);
399+
///
400+
/// // Create execution context with consensus-specific data required for block execution
401+
/// let ctx = EthBlockExecutionCtx {
402+
/// parent_hash: parent_block.hash(),
403+
/// parent_beacon_block_root: parent_block.parent_beacon_block_root,
404+
/// ommers: &uncle_blocks,
405+
/// withdrawals: Some(Cow::Borrowed(&withdrawals)),
406+
/// };
407+
///
408+
/// // Create executor - it will use ctx for system calls
409+
/// let mut executor = factory.create_executor(evm, ctx);
410+
///
411+
/// // The executor will:
412+
/// // 1. Apply pre-execution changes
413+
/// // 2. Execute all transactions
414+
/// // 3. Apply post-execution changes (e.g., process withdrawals, apply rewards)
415+
/// let result = executor.execute_block(transactions)?;
416+
/// ```
339417
fn create_executor<'a, DB, I>(
340418
&'a self,
341419
evm: <Self::EvmFactory as EvmFactory>::Evm<&'a mut State<DB>, I>,

0 commit comments

Comments
 (0)