feat: parameterize executor creation over the database type - #394
Draft
tiljrd wants to merge 2 commits into
Draft
Conversation
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
BlockExecutorFactory::Executorandcreate_executorare generic over everyDB: StateDB, so a factory must be able to build executors for any database.An executor that needs database capabilities beyond
Database + DatabaseCommitcannot be written against this trait: the implementation is not allowed to
narrow
DB, andStateDBcannot exposeState-specific functionality withoutgiving up its blanket impl. #233 and #238 hit versions of this from the wrapper
side, and the BAL methods on
BlockExecutorwork around it with per-methodbounds (
where <Self::Evm as Evm>::DB: BalIndexedDatabase) because a factoryhas 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, whichcannot be reached through
Database + DatabaseCommit.Solution
Split executor construction out of
BlockExecutorFactoryinto adatabase-parameterized trait:
BlockExecutorFactorykeeps the chain-level associated types (EvmFactory,ExecutionCtx,Transaction,Receipt,TxExecutionResult).BlockExecutorFactoryFor<DB: StateDB>carries theExecutorGAT andcreate_executor. Factories implement it for the databases their executorssupport.
EthBlockExecutorFactoryimplements it for allDB: StateDB, so its behaviorand flexibility are unchanged,
StateDBstays a pure alias with its blanketimpl, and executors keep working over plain
CacheDB. A factory with strongerrequirements implements the trait for specific databases only, for example
&'db mut State<D>, which gives its executors typed access toStatewithoutany changes to
StateDB. A factory that requires BAL tracking could implementit for
DB: StateDB + BalIndexedDatabaseand rely on the indexed executionmethods unconditionally.
BlockExecutorForkeeps its exact signature and now projects through the newtrait, so code using the alias does not change. The
Arcimpl is written byhand because
auto_implcannot reconcile associated types projected from thesupertrait, which is the same limitation that came up in #234.
This is a breaking change for
BlockExecutorFactoryimplementors. Migration ismechanical: move the
DBparameter from theExecutorGAT andcreate_executorinto the impl header, as done forEthBlockExecutorFactoryhere.
For reth, current main references
BlockExecutorFactoryin 7 files.aliases.rs, the ethereum node config and the noop config compile unchanged.ConfigureEvm's executor-creating helper methods andBasicBlockExecutorneedwhere 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