diff --git a/cmd/ethrex/cli.rs b/cmd/ethrex/cli.rs index 7f7647f786b..1671993666d 100644 --- a/cmd/ethrex/cli.rs +++ b/cmd/ethrex/cli.rs @@ -158,6 +158,14 @@ pub struct Options { env = "ETHREX_NO_MIGRATE" )] pub no_migrate: bool, + #[arg( + long = "no-precompile-cache", + action = ArgAction::SetTrue, + help = "Disable the per-block precompile result cache (benchmarking only).", + help_heading = "Node options", + env = "ETHREX_NO_PRECOMPILE_CACHE" + )] + pub no_precompile_cache: bool, #[arg( long = "log.dir", value_name = "LOG_DIR", @@ -450,6 +458,7 @@ impl Default for Options { max_blobs_per_block: None, precompute_witnesses: false, no_migrate: false, + no_precompile_cache: false, } } } @@ -641,6 +650,7 @@ impl Subcommand { BlockchainOptions { r#type: blockchain_type, perf_logs_enabled: true, + precompile_cache_enabled: !opts.no_precompile_cache, ..Default::default() }, ) diff --git a/cmd/ethrex/initializers.rs b/cmd/ethrex/initializers.rs index e52546325c8..46a524d413e 100644 --- a/cmd/ethrex/initializers.rs +++ b/cmd/ethrex/initializers.rs @@ -524,6 +524,7 @@ pub async fn init_l1( r#type: BlockchainType::L1, max_blobs_per_block: opts.max_blobs_per_block, precompute_witnesses: opts.precompute_witnesses, + precompile_cache_enabled: !opts.no_precompile_cache, }, ); diff --git a/cmd/ethrex/l2/initializers.rs b/cmd/ethrex/l2/initializers.rs index 1cc4887eeda..6c28535c037 100644 --- a/cmd/ethrex/l2/initializers.rs +++ b/cmd/ethrex/l2/initializers.rs @@ -219,6 +219,7 @@ pub async fn init_l2( perf_logs_enabled: true, max_blobs_per_block: None, // L2 doesn't support blob transactions precompute_witnesses: opts.node_opts.precompute_witnesses, + precompile_cache_enabled: true, }; let blockchain = init_blockchain(store.clone(), blockchain_opts.clone()); diff --git a/crates/blockchain/blockchain.rs b/crates/blockchain/blockchain.rs index 078e12a87a9..98ebe601fd1 100644 --- a/crates/blockchain/blockchain.rs +++ b/crates/blockchain/blockchain.rs @@ -227,6 +227,10 @@ pub struct BlockchainOptions { pub max_blobs_per_block: Option, /// If true, computes execution witnesses upon receiving newPayload messages and stores them in local storage pub precompute_witnesses: bool, + /// If true (default), per-block execution caches precompile results between the + /// warmer thread and the executor. Set to false (via `--no-precompile-cache`) to + /// disable the cache for benchmarking purposes. + pub precompile_cache_enabled: bool, } impl Default for BlockchainOptions { @@ -237,6 +241,7 @@ impl Default for BlockchainOptions { r#type: BlockchainType::default(), max_blobs_per_block: None, precompute_witnesses: false, + precompile_cache_enabled: true, } } } @@ -447,8 +452,9 @@ impl Blockchain { // Wrap the store with CachingDatabase so both warming and execution // can benefit from shared caching of state lookups let original_store = vm.db.store.clone(); - let caching_store: Arc = - Arc::new(CachingDatabase::new(original_store)); + let caching_store: Arc = Arc::new( + CachingDatabase::new(original_store, self.options.precompile_cache_enabled), + ); // Replace the VM's store with the caching version vm.db.store = caching_store.clone(); diff --git a/crates/vm/levm/src/db/mod.rs b/crates/vm/levm/src/db/mod.rs index cafdd1cbef0..6700635819f 100644 --- a/crates/vm/levm/src/db/mod.rs +++ b/crates/vm/levm/src/db/mod.rs @@ -58,29 +58,25 @@ pub struct CachingDatabase { storage: RwLock, /// Cached contract code code: RwLock, - /// Shared precompile result cache (warmer populates, executor reuses) - precompile_cache: PrecompileCache, + /// Shared precompile result cache (warmer populates, executor reuses). + /// `None` when the cache is disabled via `BlockchainOptions::precompile_cache_enabled = false`. + precompile_cache: Option, /// Cached chain config (constant for the lifetime of this database) chain_config: OnceLock, } impl CachingDatabase { - pub fn new(inner: Arc) -> Self { + pub fn new(inner: Arc, precompile_cache_enabled: bool) -> Self { Self { inner, accounts: RwLock::new(FxHashMap::default()), storage: RwLock::new(FxHashMap::default()), code: RwLock::new(FxHashMap::default()), - precompile_cache: PrecompileCache::new(), + precompile_cache: precompile_cache_enabled.then(PrecompileCache::new), chain_config: OnceLock::new(), } } - /// Access the shared precompile result cache. - pub fn precompile_cache(&self) -> &PrecompileCache { - &self.precompile_cache - } - fn read_accounts(&self) -> Result, DatabaseError> { self.accounts.read().map_err(poison_error_to_db_error) } @@ -180,7 +176,7 @@ impl Database for CachingDatabase { } fn precompile_cache(&self) -> Option<&PrecompileCache> { - Some(&self.precompile_cache) + self.precompile_cache.as_ref() } fn prefetch_accounts(&self, addresses: &[Address]) -> Result<(), DatabaseError> {