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

@ -377,29 +377,27 @@ impl ProviderCaches {
/// A builder for [`ProviderCaches`].
#[derive(Debug)]
pub(crate) struct ProviderCacheBuilder {
/// Code cache size
code_cache_size: u64,
/// Code cache entries
code_cache_entries: u64,
/// Storage cache size
storage_cache_size: u64,
/// Storage cache entries
storage_cache_entries: u64,
/// Account cache size
account_cache_size: u64,
/// Account cache entries
account_cache_entries: u64,
}
impl ProviderCacheBuilder {
/// Build a [`ProviderCaches`] struct, so that provider caches can be easily cloned.
pub(crate) fn build_caches(self) -> ProviderCaches {
// TODO: the total cache size could be a CLI configuration parameter.
const TOTAL_CACHE_SIZE: u64 = 4 * 1024 * 1024 * 1024; // 4GB
let storage_cache_size = (TOTAL_CACHE_SIZE * 8888) / 10000; // 88.88% 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
pub(crate) fn build_caches(self, total_cache_size: u64) -> ProviderCaches {
let storage_cache_size = (total_cache_size * 8888) / 10000; // 88.88% 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 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 {
// values based on results from measure_storage_cache_overhead test
let base_weight = 39_000;
@ -411,7 +409,7 @@ impl ProviderCacheBuilder {
.time_to_idle(TIME_TO_IDLE)
.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 {
match value {
Some(account) => {
@ -437,7 +435,7 @@ impl ProviderCacheBuilder {
.time_to_idle(TIME_TO_IDLE)
.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 {
match value {
Some(bytecode) => {
@ -466,9 +464,9 @@ impl Default for ProviderCacheBuilder {
// Storage cache: up to 10M accounts but limited to 8GB
// Account cache: up to 10M accounts but limited to 0.5GB
Self {
code_cache_size: 10_000_000,
storage_cache_size: 10_000_000,
account_cache_size: 10_000_000,
code_cache_entries: 10_000_000,
storage_cache_entries: 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_CROSS_BLOCK_CACHE_SIZE: u64 = 4 * 1024 * 1024 * 1024;
/// The configuration of the engine tree.
#[derive(Debug)]
pub struct TreeConfig {
@ -48,6 +50,8 @@ pub struct TreeConfig {
always_compare_trie_updates: bool,
/// Whether to use cross-block caching and parallel prewarming
use_caching_and_prewarming: bool,
/// Cross-block cache size in bytes.
cross_block_cache_size: u64,
}
impl Default for TreeConfig {
@ -61,6 +65,7 @@ impl Default for TreeConfig {
use_state_root_task: false,
always_compare_trie_updates: 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,
always_compare_trie_updates: bool,
use_caching_and_prewarming: bool,
cross_block_cache_size: u64,
) -> Self {
Self {
persistence_threshold,
@ -87,6 +93,7 @@ impl TreeConfig {
use_state_root_task,
always_compare_trie_updates,
use_caching_and_prewarming,
cross_block_cache_size,
}
}
@ -131,6 +138,11 @@ impl TreeConfig {
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.
pub const fn with_persistence_threshold(mut self, persistence_threshold: u64) -> Self {
self.persistence_threshold = persistence_threshold;
@ -191,4 +203,10 @@ impl TreeConfig {
self.always_compare_trie_updates = always_compare_trie_updates;
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>)
};
let (caches, cache_metrics) =
if let Some(cache) = self.take_latest_cache(block.parent_hash()) {
cache.split()
} else {
(ProviderCacheBuilder::default().build_caches(), CachedStateMetrics::zeroed())
};
let (caches, cache_metrics) = if let Some(cache) =
self.take_latest_cache(block.parent_hash())
{
cache.split()
} 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
// complete