feat: add cross-block cache size cli arg (#14305)

This commit is contained in:
Federico Gimenez
2025-02-10 20:31:40 +01:00
committed by GitHub
parent 731b771fa2
commit d9e660bd56
7 changed files with 64 additions and 27 deletions

View File

@ -708,6 +708,11 @@ Engine:
--engine.caching-and-prewarming --engine.caching-and-prewarming
Enable cross-block caching and parallel prewarming Enable cross-block caching and parallel prewarming
--engine.cross-block-cache-size <CROSS_BLOCK_CACHE_SIZE>
Configure the size of cross-block cache in megabytes
[default: 4096]
--engine.state-root-task-compare-updates --engine.state-root-task-compare-updates
Enable comparing trie updates from the state root task to the trie updates from the regular state root calculation Enable comparing trie updates from the state root task to the trie updates from the regular state root calculation

View File

@ -377,29 +377,27 @@ impl ProviderCaches {
/// A builder for [`ProviderCaches`]. /// A builder for [`ProviderCaches`].
#[derive(Debug)] #[derive(Debug)]
pub(crate) struct ProviderCacheBuilder { pub(crate) struct ProviderCacheBuilder {
/// Code cache size /// Code cache entries
code_cache_size: u64, code_cache_entries: u64,
/// Storage cache size /// Storage cache entries
storage_cache_size: u64, storage_cache_entries: u64,
/// Account cache size /// Account cache entries
account_cache_size: u64, account_cache_entries: u64,
} }
impl ProviderCacheBuilder { impl ProviderCacheBuilder {
/// Build a [`ProviderCaches`] struct, so that provider caches can be easily cloned. /// Build a [`ProviderCaches`] struct, so that provider caches can be easily cloned.
pub(crate) fn build_caches(self) -> ProviderCaches { pub(crate) fn build_caches(self, total_cache_size: u64) -> ProviderCaches {
// TODO: the total cache size could be a CLI configuration parameter. let storage_cache_size = (total_cache_size * 8888) / 10000; // 88.88% of total
const TOTAL_CACHE_SIZE: u64 = 4 * 1024 * 1024 * 1024; // 4GB let account_cache_size = (total_cache_size * 556) / 10000; // 5.56% of total
let storage_cache_size = (TOTAL_CACHE_SIZE * 8888) / 10000; // 88.88% of total let code_cache_size = (total_cache_size * 556) / 10000; // 5.56% of total
let account_cache_size = (TOTAL_CACHE_SIZE * 556) / 10000; // 5.56% of total
let code_cache_size = (TOTAL_CACHE_SIZE * 556) / 10000; // 5.56% of total
const EXPIRY_TIME: Duration = Duration::from_secs(7200); // 2 hours const EXPIRY_TIME: Duration = Duration::from_secs(7200); // 2 hours
const TIME_TO_IDLE: Duration = Duration::from_secs(3600); // 1 hour const TIME_TO_IDLE: Duration = Duration::from_secs(3600); // 1 hour
let storage_cache = CacheBuilder::new(self.storage_cache_size) let storage_cache = CacheBuilder::new(self.storage_cache_entries)
.weigher(|_key: &Address, value: &AccountStorageCache| -> u32 { .weigher(|_key: &Address, value: &AccountStorageCache| -> u32 {
// values based on results from measure_storage_cache_overhead test // values based on results from measure_storage_cache_overhead test
let base_weight = 39_000; let base_weight = 39_000;
@ -411,7 +409,7 @@ impl ProviderCacheBuilder {
.time_to_idle(TIME_TO_IDLE) .time_to_idle(TIME_TO_IDLE)
.build_with_hasher(DefaultHashBuilder::default()); .build_with_hasher(DefaultHashBuilder::default());
let account_cache = CacheBuilder::new(self.account_cache_size) let account_cache = CacheBuilder::new(self.account_cache_entries)
.weigher(|_key: &Address, value: &Option<Account>| -> u32 { .weigher(|_key: &Address, value: &Option<Account>| -> u32 {
match value { match value {
Some(account) => { Some(account) => {
@ -437,7 +435,7 @@ impl ProviderCacheBuilder {
.time_to_idle(TIME_TO_IDLE) .time_to_idle(TIME_TO_IDLE)
.build_with_hasher(DefaultHashBuilder::default()); .build_with_hasher(DefaultHashBuilder::default());
let code_cache = CacheBuilder::new(self.code_cache_size) let code_cache = CacheBuilder::new(self.code_cache_entries)
.weigher(|_key: &B256, value: &Option<Bytecode>| -> u32 { .weigher(|_key: &B256, value: &Option<Bytecode>| -> u32 {
match value { match value {
Some(bytecode) => { Some(bytecode) => {
@ -466,9 +464,9 @@ impl Default for ProviderCacheBuilder {
// Storage cache: up to 10M accounts but limited to 8GB // Storage cache: up to 10M accounts but limited to 8GB
// Account cache: up to 10M accounts but limited to 0.5GB // Account cache: up to 10M accounts but limited to 0.5GB
Self { Self {
code_cache_size: 10_000_000, code_cache_entries: 10_000_000,
storage_cache_size: 10_000_000, storage_cache_entries: 10_000_000,
account_cache_size: 10_000_000, account_cache_entries: 10_000_000,
} }
} }
} }

View File

@ -20,6 +20,8 @@ const DEFAULT_MAX_INVALID_HEADER_CACHE_LENGTH: u32 = 256;
const DEFAULT_MAX_EXECUTE_BLOCK_BATCH_SIZE: usize = 4; const DEFAULT_MAX_EXECUTE_BLOCK_BATCH_SIZE: usize = 4;
const DEFAULT_CROSS_BLOCK_CACHE_SIZE: u64 = 4 * 1024 * 1024 * 1024;
/// The configuration of the engine tree. /// The configuration of the engine tree.
#[derive(Debug)] #[derive(Debug)]
pub struct TreeConfig { pub struct TreeConfig {
@ -48,6 +50,8 @@ pub struct TreeConfig {
always_compare_trie_updates: bool, always_compare_trie_updates: bool,
/// Whether to use cross-block caching and parallel prewarming /// Whether to use cross-block caching and parallel prewarming
use_caching_and_prewarming: bool, use_caching_and_prewarming: bool,
/// Cross-block cache size in bytes.
cross_block_cache_size: u64,
} }
impl Default for TreeConfig { impl Default for TreeConfig {
@ -61,6 +65,7 @@ impl Default for TreeConfig {
use_state_root_task: false, use_state_root_task: false,
always_compare_trie_updates: false, always_compare_trie_updates: false,
use_caching_and_prewarming: false, use_caching_and_prewarming: false,
cross_block_cache_size: DEFAULT_CROSS_BLOCK_CACHE_SIZE,
} }
} }
} }
@ -77,6 +82,7 @@ impl TreeConfig {
use_state_root_task: bool, use_state_root_task: bool,
always_compare_trie_updates: bool, always_compare_trie_updates: bool,
use_caching_and_prewarming: bool, use_caching_and_prewarming: bool,
cross_block_cache_size: u64,
) -> Self { ) -> Self {
Self { Self {
persistence_threshold, persistence_threshold,
@ -87,6 +93,7 @@ impl TreeConfig {
use_state_root_task, use_state_root_task,
always_compare_trie_updates, always_compare_trie_updates,
use_caching_and_prewarming, use_caching_and_prewarming,
cross_block_cache_size,
} }
} }
@ -131,6 +138,11 @@ impl TreeConfig {
self.always_compare_trie_updates self.always_compare_trie_updates
} }
/// Return the cross-block cache size.
pub const fn cross_block_cache_size(&self) -> u64 {
self.cross_block_cache_size
}
/// Setter for persistence threshold. /// Setter for persistence threshold.
pub const fn with_persistence_threshold(mut self, persistence_threshold: u64) -> Self { pub const fn with_persistence_threshold(mut self, persistence_threshold: u64) -> Self {
self.persistence_threshold = persistence_threshold; self.persistence_threshold = persistence_threshold;
@ -191,4 +203,10 @@ impl TreeConfig {
self.always_compare_trie_updates = always_compare_trie_updates; self.always_compare_trie_updates = always_compare_trie_updates;
self self
} }
/// Setter for cross block cache size.
pub const fn with_cross_block_cache_size(mut self, cross_block_cache_size: u64) -> Self {
self.cross_block_cache_size = cross_block_cache_size;
self
}
} }

View File

@ -2460,12 +2460,16 @@ where
(None, None, None, Box::new(NoopHook::default()) as Box<dyn OnStateHook>) (None, None, None, Box::new(NoopHook::default()) as Box<dyn OnStateHook>)
}; };
let (caches, cache_metrics) = let (caches, cache_metrics) = if let Some(cache) =
if let Some(cache) = self.take_latest_cache(block.parent_hash()) { self.take_latest_cache(block.parent_hash())
cache.split() {
} else { cache.split()
(ProviderCacheBuilder::default().build_caches(), CachedStateMetrics::zeroed()) } else {
}; (
ProviderCacheBuilder::default().build_caches(self.config.cross_block_cache_size()),
CachedStateMetrics::zeroed(),
)
};
// Use cached state provider before executing, used in execution after prewarming threads // Use cached state provider before executing, used in execution after prewarming threads
// complete // complete

View File

@ -566,8 +566,9 @@ where
.with_memory_block_buffer_target(builder.config.engine.memory_block_buffer_target) .with_memory_block_buffer_target(builder.config.engine.memory_block_buffer_target)
.with_state_root_task(builder.config.engine.state_root_task_enabled) .with_state_root_task(builder.config.engine.state_root_task_enabled)
.with_caching_and_prewarming(builder.config.engine.caching_and_prewarming_enabled) .with_caching_and_prewarming(builder.config.engine.caching_and_prewarming_enabled)
.with_always_compare_trie_updates( .with_always_compare_trie_updates(builder.config.engine.state_root_task_compare_updates)
builder.config.engine.state_root_task_compare_updates, .with_cross_block_cache_size(
builder.config.engine.cross_block_cache_size * 1024 * 1024,
); );
let launcher = let launcher =

View File

@ -2,7 +2,10 @@
use clap::Args; use clap::Args;
use crate::node_config::{DEFAULT_MEMORY_BLOCK_BUFFER_TARGET, DEFAULT_PERSISTENCE_THRESHOLD}; use crate::node_config::{
DEFAULT_CROSS_BLOCK_CACHE_SIZE_MB, DEFAULT_MEMORY_BLOCK_BUFFER_TARGET,
DEFAULT_PERSISTENCE_THRESHOLD,
};
/// Parameters for configuring the engine driver. /// Parameters for configuring the engine driver.
#[derive(Debug, Clone, Args, PartialEq, Eq)] #[derive(Debug, Clone, Args, PartialEq, Eq)]
@ -24,6 +27,10 @@ pub struct EngineArgs {
#[arg(long = "engine.caching-and-prewarming")] #[arg(long = "engine.caching-and-prewarming")]
pub caching_and_prewarming_enabled: bool, pub caching_and_prewarming_enabled: bool,
/// Configure the size of cross-block cache in megabytes
#[arg(long = "engine.cross-block-cache-size", default_value_t = DEFAULT_CROSS_BLOCK_CACHE_SIZE_MB)]
pub cross_block_cache_size: u64,
/// Enable comparing trie updates from the state root task to the trie updates from the regular /// Enable comparing trie updates from the state root task to the trie updates from the regular
/// state root calculation. /// state root calculation.
#[arg(long = "engine.state-root-task-compare-updates")] #[arg(long = "engine.state-root-task-compare-updates")]
@ -38,6 +45,7 @@ impl Default for EngineArgs {
state_root_task_enabled: false, state_root_task_enabled: false,
state_root_task_compare_updates: false, state_root_task_compare_updates: false,
caching_and_prewarming_enabled: false, caching_and_prewarming_enabled: false,
cross_block_cache_size: DEFAULT_CROSS_BLOCK_CACHE_SIZE_MB,
} }
} }
} }

View File

@ -37,6 +37,9 @@ pub const DEFAULT_PERSISTENCE_THRESHOLD: u64 = 2;
/// How close to the canonical head we persist blocks. /// How close to the canonical head we persist blocks.
pub const DEFAULT_MEMORY_BLOCK_BUFFER_TARGET: u64 = 2; pub const DEFAULT_MEMORY_BLOCK_BUFFER_TARGET: u64 = 2;
/// Default size of cross-block cache in megabytes.
pub const DEFAULT_CROSS_BLOCK_CACHE_SIZE_MB: u64 = 4 * 1024;
/// This includes all necessary configuration to launch the node. /// This includes all necessary configuration to launch the node.
/// The individual configuration options can be overwritten before launching the node. /// The individual configuration options can be overwritten before launching the node.
/// ///