Skip to content

feat: parameterize executor creation over the database type - #394

Draft
tiljrd wants to merge 2 commits into
alloy-rs:mainfrom
tiljrd:feat/block-executor-factory-for
Draft

feat: parameterize executor creation over the database type#394
tiljrd wants to merge 2 commits into
alloy-rs:mainfrom
tiljrd:feat/block-executor-factory-for

Conversation

@tiljrd

@tiljrd tiljrd commented Jul 15, 2026

Copy link
Copy Markdown

Motivation

BlockExecutorFactory::Executor and create_executor are generic over every
DB: StateDB, so a factory must be able to build executors for any database.
An executor that needs database capabilities beyond Database + DatabaseCommit
cannot be written against this trait: the implementation is not allowed to
narrow DB, and StateDB cannot expose State-specific functionality without
giving up its blanket impl. #233 and #238 hit versions of this from the wrapper
side, and the BAL methods on BlockExecutor work around it with per-method
bounds (where <Self::Evm as Evm>::DB: BalIndexedDatabase) because a factory
has no way to state such a requirement itself.

We ran into this while building Arbitrum Reth. ArbOS applies state changes
between transactions and needs direct access to the underlying State, which
cannot be reached through Database + DatabaseCommit.

Solution

Split executor construction out of BlockExecutorFactory into a
database-parameterized trait:

  • BlockExecutorFactory keeps the chain-level associated types (EvmFactory,
    ExecutionCtx, Transaction, Receipt, TxExecutionResult).
  • The new BlockExecutorFactoryFor<DB: StateDB> carries the Executor GAT and
    create_executor. Factories implement it for the databases their executors
    support.

EthBlockExecutorFactory implements it for all DB: StateDB, so its behavior
and flexibility are unchanged, StateDB stays a pure alias with its blanket
impl, and executors keep working over plain CacheDB. A factory with stronger
requirements implements the trait for specific databases only, for example
&'db mut State<D>, which gives its executors typed access to State without
any changes to StateDB. A factory that requires BAL tracking could implement
it for DB: StateDB + BalIndexedDatabase and rely on the indexed execution
methods unconditionally.

BlockExecutorFor keeps its exact signature and now projects through the new
trait, so code using the alias does not change. The Arc impl is written by
hand because auto_impl cannot reconcile associated types projected from the
supertrait, which is the same limitation that came up in #234.

This is a breaking change for BlockExecutorFactory implementors. Migration is
mechanical: move the DB parameter from the Executor GAT and
create_executor into the impl header, as done for EthBlockExecutorFactory
here.

For reth, current main references BlockExecutorFactory in 7 files.
aliases.rs, the ethereum node config and the noop config compile unchanged.
ConfigureEvm's executor-creating helper methods and BasicBlockExecutor need
where clauses, and call sites that create executors over a generic database
need a one-line bound, on the order of 100-200 lines total. Happy to open the
companion reth PR if this direction is acceptable.

Opening as a draft to get feedback on the direction first.

PR Checklist

  • Added Tests
  • Added Documentation
  • Breaking changes

tiljrd and others added 2 commits July 15, 2026 13:26
Split executor construction out of BlockExecutorFactory into a new
BlockExecutorFactoryFor<DB> trait so that factories declare which
databases their executors support. Factories generic over any database
implement it for all DB: StateDB, as EthBlockExecutorFactory does,
while stacks whose executors need capabilities beyond StateDB (e.g.
the State transition layer or BAL index tracking) can implement it
for exactly the databases providing them.

The BlockExecutorFor alias keeps its signature and now projects
through the new trait. Arc forwarding is implemented manually because
auto_impl cannot reconcile associated types projected from the
supertrait.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant