diff --git a/CHANGELOG.md b/CHANGELOG.md index 6f8f7d6d28f..c601d59a521 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,10 @@ ## Perf +### 2026-08-03 + +- Size the default RocksDB shared block cache from the memory the process may actually use — 40% of the smaller of physical memory and the cgroup limit, clamped to 512 MiB..=12 GiB — instead of a flat 12 GiB. The flat default was 71% of a 16 GiB host, leaving no headroom for trie layers, execution and the mempool; `--rocksdb.block-cache-size` still overrides it + ### 2026-07-22 - Unify full-sync batch import onto the per-block execution pipeline, validating every block's state root and reusing the pipeline's BAL-driven parallel execution instead of the bespoke "execute all, apply once" batch path [#7008](https://github.com/lambdaclass/ethrex/pull/7008) diff --git a/cmd/ethrex/cli.rs b/cmd/ethrex/cli.rs index 88e5dbe82b9..5aaba122eb7 100644 --- a/cmd/ethrex/cli.rs +++ b/cmd/ethrex/cli.rs @@ -101,25 +101,13 @@ pub struct Options { #[arg( long = "rocksdb.block-cache-size", value_name = "BYTES", - default_value_t = ethrex_storage::DEFAULT_ROCKSDB_BLOCK_CACHE_SIZE_BYTES, - help = "RocksDB shared block cache size in bytes (default 12 GiB). \ - Bounds RocksDB resident memory; lower only on memory-constrained hosts.", - long_help = "RocksDB shared block cache size in bytes. With cache_index_and_filter_blocks \ - enabled it holds data blocks plus the per-SST index and bloom-filter blocks, \ - so it is the effective ceiling on RocksDB's resident memory.\n\ - \n\ - Default 12 GiB keeps the filter/index working set resident plus hot EVM state. \ - A sweep on a synced mainnet node (32 GiB cap) found 8-16 GiB all keep up with \ - head-following (filters resident, disk near-idle, no slow blocks); larger gives \ - no gain because the OS page cache backstops the uncompressed state CFs, and \ - ~8 GiB is the floor where the filter set starts to thrash.\n\ - \n\ - Lower only on memory-constrained hosts, accepting reduced throughput. \ - ETHREX_ROCKSDB_BLOCK_CACHE_SIZE sets the same value.", + help = "RocksDB shared block cache size in bytes, the effective ceiling on RocksDB's \ + resident memory. Defaults to 40% of the memory available to the process \ + (physical or cgroup limit, whichever is lower), clamped to 512 MiB..=12 GiB.", help_heading = "Storage options", - env = "ETHREX_ROCKSDB_BLOCK_CACHE_SIZE", + env = "ETHREX_ROCKSDB_BLOCK_CACHE_SIZE" )] - pub rocksdb_block_cache_size: usize, + pub rocksdb_block_cache_size: Option, #[arg(long = "syncmode", default_value = "snap", value_name = "SYNC_MODE", value_parser = utils::parse_sync_mode, help = "The way in which the node will sync its state.", long_help = "Can be either \"full\" or \"snap\" with \"snap\" as default value.", help_heading = "P2P options", env = "ETHREX_SYNCMODE")] pub syncmode: SyncMode, #[arg( @@ -539,7 +527,7 @@ impl Default for Options { network: Default::default(), bootnodes: Default::default(), datadir: Default::default(), - rocksdb_block_cache_size: ethrex_storage::DEFAULT_ROCKSDB_BLOCK_CACHE_SIZE_BYTES, + rocksdb_block_cache_size: None, syncmode: Default::default(), metrics_addr: "0.0.0.0".to_owned(), metrics_port: Default::default(), diff --git a/cmd/ethrex/initializers.rs b/cmd/ethrex/initializers.rs index 5bdd3b96089..09b8301b05d 100644 --- a/cmd/ethrex/initializers.rs +++ b/cmd/ethrex/initializers.rs @@ -26,8 +26,8 @@ use ethrex_p2p::{ utils::public_key_from_signing_key, }; use ethrex_storage::{ - DB_COMMIT_THRESHOLD, EngineType, Store, StoreConfig, error::StoreError, has_valid_db, - read_chain_id_from_db, + DB_COMMIT_THRESHOLD, EngineType, Store, StoreConfig, default_rocksdb_block_cache_size, + error::StoreError, has_valid_db, read_chain_id_from_db, }; use local_ip_address::{local_ip, local_ipv6}; use rand::rngs::OsRng; @@ -740,7 +740,9 @@ pub async fn init_l1( ethrex_crypto::kzg::warm_up_trusted_setup(); let store_config = StoreConfig { - rocksdb_block_cache_size: opts.rocksdb_block_cache_size, + rocksdb_block_cache_size: opts + .rocksdb_block_cache_size + .unwrap_or_else(default_rocksdb_block_cache_size), ..StoreConfig::default() }; let store_result = if opts.skip_genesis_validation { diff --git a/cmd/ethrex/l2/initializers.rs b/cmd/ethrex/l2/initializers.rs index 9a82baae979..88fbb27ec6d 100644 --- a/cmd/ethrex/l2/initializers.rs +++ b/cmd/ethrex/l2/initializers.rs @@ -221,7 +221,10 @@ pub async fn init_l2( let genesis = network.get_genesis()?; let store_config = StoreConfig { - rocksdb_block_cache_size: opts.node_opts.rocksdb_block_cache_size, + rocksdb_block_cache_size: opts + .node_opts + .rocksdb_block_cache_size + .unwrap_or_else(ethrex_storage::default_rocksdb_block_cache_size), ..StoreConfig::default() }; let store = init_store_with_config(&datadir, genesis.clone(), store_config).await?; diff --git a/crates/storage/backend/rocksdb.rs b/crates/storage/backend/rocksdb.rs index 81eeac3249e..b61ba7b3da6 100644 --- a/crates/storage/backend/rocksdb.rs +++ b/crates/storage/backend/rocksdb.rs @@ -586,11 +586,9 @@ mod tests { #[test] fn merge_operator_survives_flush_and_compaction() { let dir = tempfile::tempdir().unwrap(); - let backend = RocksDBBackend::open( - dir.path(), - crate::store::DEFAULT_ROCKSDB_BLOCK_CACHE_SIZE_BYTES, - ) - .unwrap(); + let backend = + RocksDBBackend::open(dir.path(), crate::store::MAX_ROCKSDB_BLOCK_CACHE_SIZE_BYTES) + .unwrap(); let cf = backend.db.cf_handle(TRANSACTION_LOCATIONS).unwrap(); let tx_hash = H256::from_low_u64_be(0xabcd); @@ -633,11 +631,9 @@ mod tests { #[test] fn merge_operator_dedupes_across_compaction() { let dir = tempfile::tempdir().unwrap(); - let backend = RocksDBBackend::open( - dir.path(), - crate::store::DEFAULT_ROCKSDB_BLOCK_CACHE_SIZE_BYTES, - ) - .unwrap(); + let backend = + RocksDBBackend::open(dir.path(), crate::store::MAX_ROCKSDB_BLOCK_CACHE_SIZE_BYTES) + .unwrap(); let cf = backend.db.cf_handle(TRANSACTION_LOCATIONS).unwrap(); let tx_hash = H256::from_low_u64_be(0x1234); diff --git a/crates/storage/lib.rs b/crates/storage/lib.rs index b6a23e2985a..d1b3d49d155 100644 --- a/crates/storage/lib.rs +++ b/crates/storage/lib.rs @@ -78,9 +78,11 @@ pub mod utils; pub use layering::apply_prefix; pub use store::{ - AccountUpdatesList, BATCH_COMMIT_THRESHOLD, DB_COMMIT_THRESHOLD, - DEFAULT_ROCKSDB_BLOCK_CACHE_SIZE_BYTES, EngineType, Store, StoreConfig, UpdateBatch, - has_valid_db, hash_address, hash_key, read_chain_id_from_db, + AccountUpdatesList, BATCH_COMMIT_THRESHOLD, DB_COMMIT_THRESHOLD, EngineType, + MAX_ROCKSDB_BLOCK_CACHE_SIZE_BYTES, MIN_ROCKSDB_BLOCK_CACHE_SIZE_BYTES, + ROCKSDB_BLOCK_CACHE_MEMORY_PERCENT, Store, StoreConfig, UpdateBatch, + default_rocksdb_block_cache_size, has_valid_db, hash_address, hash_key, read_chain_id_from_db, + rocksdb_block_cache_size_for, }; /// Store Schema Version, must be updated on any breaking change. diff --git a/crates/storage/store.rs b/crates/storage/store.rs index e0288d1267e..2ef87b36b2a 100644 --- a/crates/storage/store.rs +++ b/crates/storage/store.rs @@ -75,7 +75,7 @@ const IN_MEMORY_COMMIT_THRESHOLD: usize = 10000; /// import only ever extend a single canonical chain (no competing forks to mis-commit). pub const BATCH_COMMIT_THRESHOLD: usize = 4; -/// Default size in bytes of the RocksDB shared block cache: 12 GiB. +/// Ceiling on the RocksDB shared block cache: 12 GiB. /// /// This cache holds both data blocks AND the index/bloom-filter blocks for every /// open SST file (because we enable `cache_index_and_filter_blocks`), so its size @@ -84,7 +84,131 @@ pub const BATCH_COMMIT_THRESHOLD: usize = 4; /// synced mainnet node (32 GiB cap) found 8-16 GiB all keep up with head-following, /// with larger giving no gain (the OS page cache backstops the uncompressed state /// CFs) and ~8 GiB the floor where the filter set starts to thrash. -pub const DEFAULT_ROCKSDB_BLOCK_CACHE_SIZE_BYTES: usize = 12 * 1024 * 1024 * 1024; +pub const MAX_ROCKSDB_BLOCK_CACHE_SIZE_BYTES: usize = 12 * 1024 * 1024 * 1024; + +/// Floor on the RocksDB shared block cache: 512 MiB. Below this the per-SST +/// index and filter blocks no longer stay resident and every trie read pays an +/// extra disk seek, which is worse than the memory it saves. Applied even when +/// it exceeds [`ROCKSDB_BLOCK_CACHE_MEMORY_PERCENT`] of a very small host, and +/// even when it exceeds the detected limit outright: a node given less than this +/// much memory cannot follow the chain anyway, so the floor is the more useful +/// failure mode than a cache too small to hold the filters. +pub const MIN_ROCKSDB_BLOCK_CACHE_SIZE_BYTES: usize = 512 * 1024 * 1024; + +/// Share of the host's (or cgroup's) memory the block cache may claim by default. +/// +/// The rest has to cover the in-memory trie-layer backlog, block execution, the +/// mempool, peer buffers and allocator slack, so the cache cannot have most of the +/// machine. At 40% a 32 GiB host lands on the 12 GiB ceiling and a 16 GiB host gets +/// ~6.4 GiB — under the ~8 GiB thrash floor, but that is the memory-constrained +/// tradeoff the ceiling's docs describe, and it leaves the node room not to be +/// OOM-killed. +pub const ROCKSDB_BLOCK_CACHE_MEMORY_PERCENT: usize = 40; + +/// Default RocksDB shared block cache size, derived from the memory this process +/// is actually allowed to use. +/// +/// A fixed default cannot serve both a 64 GiB validator and a 16 GiB CI runner: the +/// ceiling alone is 71% of a 16 GiB host, which leaves no headroom for the rest of +/// the node. Sizes to [`ROCKSDB_BLOCK_CACHE_MEMORY_PERCENT`] of the detected limit, +/// clamped to [`MIN_ROCKSDB_BLOCK_CACHE_SIZE_BYTES`] ..= +/// [`MAX_ROCKSDB_BLOCK_CACHE_SIZE_BYTES`]. Falls back to the ceiling when the limit +/// cannot be detected, preserving the previous behavior. +pub fn default_rocksdb_block_cache_size() -> usize { + rocksdb_block_cache_size_for(host_memory_limit_bytes()) +} + +/// Pure part of [`default_rocksdb_block_cache_size`]: the clamp, with the detected +/// memory limit supplied by the caller. `None` means detection failed. +pub fn rocksdb_block_cache_size_for(memory_limit: Option) -> usize { + let Some(limit) = memory_limit else { + return MAX_ROCKSDB_BLOCK_CACHE_SIZE_BYTES; + }; + (limit.saturating_mul(ROCKSDB_BLOCK_CACHE_MEMORY_PERCENT) / 100).clamp( + MIN_ROCKSDB_BLOCK_CACHE_SIZE_BYTES, + MAX_ROCKSDB_BLOCK_CACHE_SIZE_BYTES, + ) +} + +/// Memory this process may use: the smaller of the host's physical memory and the +/// cgroup memory limit, so a container gets sized against its own limit rather than +/// the machine it happens to run on. `None` when nothing could be read (non-Linux, +/// or an unreadable/absent `/proc`), which callers treat as "unknown". +fn host_memory_limit_bytes() -> Option { + [physical_memory_bytes(), cgroup_memory_limit_bytes()] + .into_iter() + .flatten() + .min() +} + +/// `MemTotal` from `/proc/meminfo`, in bytes. +fn physical_memory_bytes() -> Option { + let meminfo = std::fs::read_to_string("/proc/meminfo").ok()?; + let kib: usize = meminfo + .lines() + .find_map(|line| line.strip_prefix("MemTotal:"))? + .split_whitespace() + .next()? + .parse() + .ok()?; + kib.checked_mul(1024) +} + +/// The cgroup memory limit that applies to this process, in bytes: `memory.max` +/// under cgroup v2, falling back to `memory.limit_in_bytes` under v1. Both report +/// "no limit" out of band — v2 with the literal `max`, v1 with a sentinel near +/// `u64::MAX` — which yields `None` here (v1's sentinel simply exceeds any real +/// `MemTotal`, so the `min` above discards it). +/// +/// The limit may sit on any cgroup between the one the process belongs to and the +/// mount root — a systemd slice, a Kubernetes pod's parent, an outer container — and +/// the mount root itself is usually unlimited, so reading the root alone would miss +/// it. The process's own cgroup comes from `/proc/self/cgroup` and every level up to +/// the root is read, with the smallest limit winning. +fn cgroup_memory_limit_bytes() -> Option { + let cgroups = std::fs::read_to_string("/proc/self/cgroup").ok()?; + let v2 = cgroups + .lines() + .find_map(|line| line.strip_prefix("0::")) + .and_then(|relative| { + cgroup_limit_up_to_root(Path::new("/sys/fs/cgroup"), relative, "memory.max") + }); + v2.or_else(|| { + let relative = cgroups.lines().find_map(|line| { + // `hierarchy-ID:controller-list:cgroup-path` + let mut fields = line.splitn(3, ':'); + let controllers = fields.nth(1)?; + let path = fields.next()?; + controllers + .split(',') + .any(|controller| controller == "memory") + .then_some(path) + })?; + cgroup_limit_up_to_root( + Path::new("/sys/fs/cgroup/memory"), + relative, + "memory.limit_in_bytes", + ) + }) +} + +/// Smallest value of `file` across `/` and each of its ancestors up +/// to `mount`, skipping levels whose file is absent or reports no limit. +fn cgroup_limit_up_to_root(mount: &Path, relative: &str, file: &str) -> Option { + let mut dir = mount.join(relative.trim_start_matches('/')); + let mut limit: Option = None; + loop { + if let Some(value) = std::fs::read_to_string(dir.join(file)) + .ok() + .and_then(|contents| contents.trim().parse::().ok()) + { + limit = Some(limit.map_or(value, |current| current.min(value))); + } + if dir == mount || !dir.pop() { + return limit; + } + } +} /// Tunable configuration for [`Store::new_with_config`] and related constructors. /// @@ -107,7 +231,7 @@ pub struct StoreConfig { impl Default for StoreConfig { fn default() -> Self { Self { - rocksdb_block_cache_size: DEFAULT_ROCKSDB_BLOCK_CACHE_SIZE_BYTES, + rocksdb_block_cache_size: default_rocksdb_block_cache_size(), persist_channel_capacity: DEFAULT_PERSIST_CHANNEL_CAPACITY, } } @@ -5018,8 +5142,8 @@ pub fn read_chain_id_from_db(path: &Path) -> Option { #[cfg(feature = "rocksdb")] { // The cache size is irrelevant for this one-shot chain-id read (the LRU - // is sized as a ceiling, not pre-allocated), so we use the default. - let backend = match RocksDBBackend::open(path, DEFAULT_ROCKSDB_BLOCK_CACHE_SIZE_BYTES) { + // is sized as a ceiling, not pre-allocated), so we use the ceiling. + let backend = match RocksDBBackend::open(path, MAX_ROCKSDB_BLOCK_CACHE_SIZE_BYTES) { Ok(backend) => backend, Err(e) => { warn!("Failed to open RocksDB at {path:?} to read chain ID: {e}"); @@ -6314,3 +6438,93 @@ mod flatkeyvalue_completeness_tests { ]))); } } + +#[cfg(test)] +mod cgroup_memory_limit_tests { + use super::*; + use std::fs; + + /// Builds `/` and writes `contents` into the `file` of every + /// directory the map names, keyed by path relative to `root` ("" is the root). + fn cgroup_tree(root: &Path, relative: &str, file: &str, limits: &[(&str, &str)]) { + fs::create_dir_all(root.join(relative)).expect("create cgroup tree"); + for (dir, contents) in limits { + fs::write(root.join(dir).join(file), contents).expect("write limit"); + } + } + + /// A limit set on an ancestor cgroup (a systemd slice, a pod's parent) applies to + /// the process, so it must be found even though the process's own cgroup is + /// unlimited and the mount root reports `max`. + #[test] + fn ancestor_limit_applies() { + let tmp = tempfile::tempdir().expect("tempdir"); + let root = tmp.path(); + cgroup_tree( + root, + "system.slice/ethrex.service", + "memory.max", + &[("", "max"), ("system.slice", "4294967296")], + ); + + assert_eq!( + cgroup_limit_up_to_root(root, "/system.slice/ethrex.service", "memory.max"), + Some(4 * 1024 * 1024 * 1024) + ); + } + + /// With limits at several levels the tightest one is what the kernel enforces. + #[test] + fn smallest_limit_in_the_chain_wins() { + let tmp = tempfile::tempdir().expect("tempdir"); + let root = tmp.path(); + cgroup_tree( + root, + "kubepods/pod123/container", + "memory.max", + &[ + ("kubepods", "8589934592"), + ("kubepods/pod123", "2147483648"), + ("kubepods/pod123/container", "4294967296"), + ], + ); + + assert_eq!( + cgroup_limit_up_to_root(root, "kubepods/pod123/container", "memory.max"), + Some(2 * 1024 * 1024 * 1024) + ); + } + + /// An unlimited chain is "unknown", not zero: v2 writes the literal `max` and v1 a + /// sentinel near `u64::MAX`, and absent files must not count either. + #[test] + fn unlimited_chain_yields_no_limit() { + let tmp = tempfile::tempdir().expect("tempdir"); + let root = tmp.path(); + cgroup_tree(root, "docker/abc", "memory.max", &[("", "max")]); + + assert_eq!( + cgroup_limit_up_to_root(root, "docker/abc", "memory.max"), + None + ); + // A cgroup path that does not exist under this mount (a v1 controller that is + // not mounted, a stale line in /proc/self/cgroup) reads as unknown too. + assert_eq!( + cgroup_limit_up_to_root(root, "not/here", "memory.max"), + None + ); + } + + /// The root cgroup is itself a level: a limit set there still applies. + #[test] + fn root_limit_applies_to_the_root_cgroup() { + let tmp = tempfile::tempdir().expect("tempdir"); + let root = tmp.path(); + cgroup_tree(root, "", "memory.limit_in_bytes", &[("", "536870912")]); + + assert_eq!( + cgroup_limit_up_to_root(root, "/", "memory.limit_in_bytes"), + Some(512 * 1024 * 1024) + ); + } +} diff --git a/docs/CLI.md b/docs/CLI.md index 3620d6be568..f926324585a 100644 --- a/docs/CLI.md +++ b/docs/CLI.md @@ -202,14 +202,9 @@ P2P options: Storage options: --rocksdb.block-cache-size - RocksDB shared block cache size in bytes. With cache_index_and_filter_blocks enabled it holds data blocks plus the per-SST index and bloom-filter blocks, so it is the effective ceiling on RocksDB's resident memory. - - Default 12 GiB keeps the filter/index working set resident plus hot EVM state. A sweep on a synced mainnet node (32 GiB cap) found 8-16 GiB all keep up with head-following (filters resident, disk near-idle, no slow blocks); larger gives no gain because the OS page cache backstops the uncompressed state CFs, and ~8 GiB is the floor where the filter set starts to thrash. - - Lower only on memory-constrained hosts, accepting reduced throughput. ETHREX_ROCKSDB_BLOCK_CACHE_SIZE sets the same value. + RocksDB shared block cache size in bytes, the effective ceiling on RocksDB's resident memory. Defaults to 40% of the memory available to the process (physical or cgroup limit, whichever is lower), clamped to 512 MiB..=12 GiB. [env: ETHREX_ROCKSDB_BLOCK_CACHE_SIZE=] - [default: 12884901888] RPC options: --http.addr
diff --git a/test/tests/storage/mod.rs b/test/tests/storage/mod.rs index 9f94f09f3d8..c13b3ff7c3d 100644 --- a/test/tests/storage/mod.rs +++ b/test/tests/storage/mod.rs @@ -1,4 +1,5 @@ mod deferred_persistence_tests; mod fcu_race_tests; +mod rocksdb_block_cache_tests; mod store_tests; mod trie_db_tests; diff --git a/test/tests/storage/rocksdb_block_cache_tests.rs b/test/tests/storage/rocksdb_block_cache_tests.rs new file mode 100644 index 00000000000..e32095cbe5d --- /dev/null +++ b/test/tests/storage/rocksdb_block_cache_tests.rs @@ -0,0 +1,75 @@ +//! Sizing of the RocksDB shared block cache default. + +use ethrex_storage::{ + MAX_ROCKSDB_BLOCK_CACHE_SIZE_BYTES, MIN_ROCKSDB_BLOCK_CACHE_SIZE_BYTES, + ROCKSDB_BLOCK_CACHE_MEMORY_PERCENT, default_rocksdb_block_cache_size, + rocksdb_block_cache_size_for, +}; + +const GIB: usize = 1024 * 1024 * 1024; + +/// An undetectable memory limit SHALL fall back to the ceiling, preserving the +/// behavior from before the default became memory-aware. +#[test] +fn undetected_memory_limit_falls_back_to_the_ceiling() { + assert_eq!( + rocksdb_block_cache_size_for(None), + MAX_ROCKSDB_BLOCK_CACHE_SIZE_BYTES + ); +} + +/// Hosts large enough that the percentage exceeds the ceiling SHALL get the ceiling, +/// so a big machine keeps the tuned 12 GiB rather than scaling without bound. +#[test] +fn large_hosts_are_capped_at_the_ceiling() { + for limit in [32 * GIB, 64 * GIB, 1024 * GIB] { + assert_eq!( + rocksdb_block_cache_size_for(Some(limit)), + MAX_ROCKSDB_BLOCK_CACHE_SIZE_BYTES, + "{limit} bytes must clamp to the ceiling" + ); + } +} + +/// The case this sizing exists for: on a 16 GiB host the flat 12 GiB default was 71% of +/// the machine, leaving no headroom for trie layers, execution and the mempool. The +/// memory-aware default SHALL leave the majority of such a host to the rest of the node. +#[test] +fn memory_constrained_host_keeps_headroom() { + let limit = 16 * GIB; + let cache = rocksdb_block_cache_size_for(Some(limit)); + + assert_eq!(cache, limit * ROCKSDB_BLOCK_CACHE_MEMORY_PERCENT / 100); + assert!( + cache < MAX_ROCKSDB_BLOCK_CACHE_SIZE_BYTES, + "a 16 GiB host must not be handed the ceiling" + ); + assert!( + limit - cache > limit / 2, + "more than half of a 16 GiB host must stay available to the node" + ); +} + +/// Tiny hosts SHALL still get the floor: below it the per-SST index and filter blocks +/// stop staying resident and every trie read pays an extra seek. +#[test] +fn tiny_hosts_get_the_floor() { + assert_eq!( + rocksdb_block_cache_size_for(Some(GIB)), + MIN_ROCKSDB_BLOCK_CACHE_SIZE_BYTES + ); + assert_eq!( + rocksdb_block_cache_size_for(Some(0)), + MIN_ROCKSDB_BLOCK_CACHE_SIZE_BYTES + ); +} + +/// Whatever this machine reports, the resolved default SHALL land inside the clamp. +#[test] +fn resolved_default_is_within_the_clamp() { + let cache = default_rocksdb_block_cache_size(); + assert!( + (MIN_ROCKSDB_BLOCK_CACHE_SIZE_BYTES..=MAX_ROCKSDB_BLOCK_CACHE_SIZE_BYTES).contains(&cache), + "resolved default {cache} outside the clamp" + ); +} diff --git a/tooling/migrations/src/bin/bench_migration.rs b/tooling/migrations/src/bin/bench_migration.rs index 1cf313b0475..912826c0fab 100644 --- a/tooling/migrations/src/bin/bench_migration.rs +++ b/tooling/migrations/src/bin/bench_migration.rs @@ -64,7 +64,7 @@ fn main() { let backend = ethrex_storage::backend::rocksdb::RocksDBBackend::open( db_path, - ethrex_storage::DEFAULT_ROCKSDB_BLOCK_CACHE_SIZE_BYTES, + ethrex_storage::default_rocksdb_block_cache_size(), ) .expect("Failed to open RocksDB");