refactor: move salt bucket capacity lookup into revm::Database trait#188
refactor: move salt bucket capacity lookup into revm::Database trait#188WonderLawrence wants to merge 7 commits intomainfrom
Conversation
fd83d28 to
b85bede
Compare
b85bede to
6b530c3
Compare
6b530c3 to
96092a6
Compare
|
Concern: forking This forks two upstream crates (
Consider defining a separate trait (e.g. in |
| /// The parent block number. | ||
| parent_block: BlockNumber, | ||
| /// The external environment for SALT bucket information. | ||
| salt_env: SaltEnvImpl, |
There was a problem hiding this comment.
Would it make sense to store db as a member variable, rather than passing a reference on every interface call?
There was a problem hiding this comment.
Since mega-evm can only see the Database type passed from the upper layer, and this type does not implement the Clone Trait, this implementation requires that the same db instance be stored in at least two places. Therefore, there is a conflict here.
I have also tried the suggested approach, such as introducing a separate mega-evm/crates/mega-evm/src/evm/factory.rs Line 138 in 96092a6 Database type. If we change it as described above, compilation here will fail because adding the Bucket Trait on top of Database would narrow the types of generic parameters accepted by the create_evm method in EvmFactory.If we further modify create_evm, the mega-reth layer would require more adaptation work for such changes. Therefore, if we introduce a new Bucket Trait, considering the numerous places where Database is depended upon, this could be a very broad change across the codebase.
|
DevinByte
left a comment
There was a problem hiding this comment.
Forking upstream revm::Database to add a MegaETH-specific method is a high-cost trade-off. Adding salt_bucket_capacity to the core Database trait forces every Database implementor (including MemoryDatabase, SandboxDb, ErrorInjectingDatabase, and any future ones) to implement a MegaETH-specific concern, even when SALT is irrelevant to them. It also increases the ongoing maintenance burden of syncing with upstream revm. A local extension trait (trait DatabaseExt: Database { fn salt_bucket_capacity(...) }) would achieve the same goal without polluting the upstream interface.
I’m not sure what problem this is addressing or why the change is necessary. This should be discussed further.
Summary
This PR refactors how SALT bucket capacity is queried during EVM execution for v1.4.1, removing the
SaltEnvabstraction and integrating capacity lookup directly into therevm::Databasetrait via a newsalt_bucket_capacity(address, Option<U256>) -> (usize, u64)method.Problem
Previously, bucket capacity was provided through
ExternalEnvTypes::SaltEnv— an external environment trait injected viaExternalEnvFactory. This required the factory to accept ablock: BlockNumberparameter to return historically-correct capacity values. The design was overly complex and coupled gas calculation to an external oracle abstraction rather than the database layer.Changes
SaltEnvtrait andExternalEnvs::salt_envfield: All SALT bucket capacity queries now go throughdb.salt_bucket_capacity(address, key)on therevm::Databasetrait (added in the upstreammegaeth-labs/revm-database-interfacefork)DynamicGasCostis no longer generic:DynamicGasCost<SaltEnvImpl>→DynamicGasCost; gas functions (sstore_set_gas,new_account_gas,create_contract_gas) now takedb: &DBdirectlyExternalEnvFactory::external_envsdrops theblockparameter: Block context for historical capacity resolution is now handled at the database level by the caller (e.g.StateProviderDatabasewrapping aHistoricalStateProviderRef)TestDatabaseWrapperintroduced: ReplacesTestExternalEnvs::with_bucket_capacityfor test setups; wraps anyrevm::Databaseand provides configurable per-bucket capacity overridesMotivation
The
revm::Databaseis already the single source of truth for all state during execution. Routing capacity queries through it allows historical replay correctness to be handled entirely at the storage layer (see megaeth-labs/mega-reth#1489), without requiring the EVM execution layer to know about block numbers or provider types.