From 9a3a2ff9be5325271abc37f8a90daef41d2e74e9 Mon Sep 17 00:00:00 2001 From: Jakob Meier Date: Tue, 6 Sep 2022 20:04:39 +0200 Subject: [PATCH] refactor: trie cache configuration (#7566) This is a pure refactor, including two main refactors: - replace `TrieCacheFactory` with `TrieConfig` - move config constants into `TrieConfig` The motivation is to facilitate wider configuration and changes to the config format in follow-up PRs. See also #7564. --- core/store/src/config.rs | 2 +- core/store/src/lib.rs | 3 +- core/store/src/test_utils.rs | 5 +- core/store/src/trie/config.rs | 99 +++++++++++++++++++ core/store/src/trie/mod.rs | 6 +- core/store/src/trie/shard_tries.rs | 92 +++++++---------- core/store/src/trie/trie_storage.rs | 70 ++++--------- core/store/src/trie/trie_tests.rs | 24 +++-- nearcore/src/runtime/mod.rs | 30 +++--- .../src/estimator_context.rs | 4 +- 10 files changed, 195 insertions(+), 140 deletions(-) create mode 100644 core/store/src/trie/config.rs diff --git a/core/store/src/config.rs b/core/store/src/config.rs index 25b96f6c4c3..4a15d9deeae 100644 --- a/core/store/src/config.rs +++ b/core/store/src/config.rs @@ -44,7 +44,7 @@ pub struct StoreConfig { /// Default value: ShardUId {version: 1, shard_id: 3} -> 45_000_000 /// We're still experimenting with this parameter and it seems decreasing its value can improve /// the performance of the storage - pub trie_cache_capacities: Vec<(ShardUId, usize)>, + pub trie_cache_capacities: Vec<(ShardUId, u64)>, } /// Mode in which to open the storage. diff --git a/core/store/src/lib.rs b/core/store/src/lib.rs index eafbd2b2011..8a51078bf7b 100644 --- a/core/store/src/lib.rs +++ b/core/store/src/lib.rs @@ -32,8 +32,7 @@ pub use crate::trie::iterator::TrieIterator; pub use crate::trie::update::{TrieUpdate, TrieUpdateIterator, TrieUpdateValuePtr}; pub use crate::trie::{ estimator, split_state, ApplyStatePartResult, KeyForStateChanges, PartialStorage, ShardTries, - Trie, TrieCache, TrieCacheFactory, TrieCachingStorage, TrieChanges, TrieStorage, - WrappedTrieChanges, + Trie, TrieCache, TrieCachingStorage, TrieChanges, TrieConfig, TrieStorage, WrappedTrieChanges, }; mod columns; diff --git a/core/store/src/test_utils.rs b/core/store/src/test_utils.rs index 246b3d06519..4d7f5352bc6 100644 --- a/core/store/src/test_utils.rs +++ b/core/store/src/test_utils.rs @@ -5,7 +5,7 @@ use rand::seq::SliceRandom; use rand::Rng; use crate::db::TestDB; -use crate::{ShardTries, Store, TrieCacheFactory}; +use crate::{ShardTries, Store}; use near_primitives::account::id::AccountId; use near_primitives::hash::CryptoHash; use near_primitives::receipt::{DataReceipt, Receipt, ReceiptEnum}; @@ -26,8 +26,7 @@ pub fn create_tries() -> ShardTries { pub fn create_tries_complex(shard_version: ShardVersion, num_shards: NumShards) -> ShardTries { let store = create_test_store(); - let trie_cache_factory = TrieCacheFactory::new(Default::default(), shard_version, num_shards); - ShardTries::new(store, trie_cache_factory) + ShardTries::test_shard_version(store, shard_version, num_shards) } pub fn test_populate_trie( diff --git a/core/store/src/trie/config.rs b/core/store/src/trie/config.rs new file mode 100644 index 00000000000..b0db936fd15 --- /dev/null +++ b/core/store/src/trie/config.rs @@ -0,0 +1,99 @@ +use near_primitives::shard_layout::ShardUId; +use std::collections::HashMap; + +/// Default number of cache entries. +/// It was chosen to fit into RAM well. RAM spend on trie cache should not exceed 50_000 * 4 (number of shards) * +/// TRIE_LIMIT_CACHED_VALUE_SIZE * 2 (number of caches - for regular and view client) = 0.4 GB. +/// In our tests on a single shard, it barely occupied 40 MB, which is dominated by state cache size +/// with 512 MB limit. The total RAM usage for a single shard was 1 GB. +const TRIE_DEFAULT_SHARD_CACHE_SIZE: u64 = if cfg!(feature = "no_cache") { 1 } else { 50000 }; + +/// Default total size of values which may simultaneously exist the cache. +/// It is chosen by the estimation of the largest contract storage size we are aware as of 23/08/2022. +const DEFAULT_SHARD_CACHE_TOTAL_SIZE_LIMIT: u64 = + if cfg!(feature = "no_cache") { 1 } else { 3_000_000_000 }; + +/// Capacity for the deletions queue. +/// It is chosen to fit all hashes of deleted nodes for 3 completely full blocks. +const DEFAULT_SHARD_CACHE_DELETIONS_QUEUE_CAPACITY: usize = + if cfg!(feature = "no_cache") { 1 } else { 100_000 }; + +/// Values above this size (in bytes) are never cached. +/// Note that most of Trie inner nodes are smaller than this - e.g. branches use around 32 * 16 = 512 bytes. +const TRIE_LIMIT_CACHED_VALUE_SIZE: usize = 1000; + +/// Stores necessary configuration for the creation of tries. +#[derive(Default)] +pub struct TrieConfig { + pub shard_cache_config: ShardCacheConfig, + pub view_shard_cache_config: ShardCacheConfig, +} + +pub struct ShardCacheConfig { + /// Shard cache capacity in number of trie nodes. + pub default_max_entries: u64, + /// Limits the sum of all cached value sizes. + /// + /// This is useful to limit total memory consumption. However, crucially this + /// is not a hard limit. It only limits the sum of all cached values, not + /// factoring in the overhead for each entry. + pub default_max_total_bytes: u64, + /// Overrides `default_max_entries` per shard. + pub override_max_entries: HashMap, + /// Overrides `default_max_total_bytes` per shard. + pub override_max_total_bytes: HashMap, +} + +impl TrieConfig { + /// Shard cache capacity in number of trie nodes. + pub fn shard_cache_capacity(&self, shard_uid: ShardUId, is_view: bool) -> u64 { + if is_view { &self.view_shard_cache_config } else { &self.shard_cache_config } + .capacity(shard_uid) + } + + /// Shard cache capacity in total bytes. + pub fn shard_cache_total_size_limit(&self, shard_uid: ShardUId, is_view: bool) -> u64 { + if is_view { &self.view_shard_cache_config } else { &self.shard_cache_config } + .total_size_limit(shard_uid) + } + + /// Size limit in bytes per single value for caching in shard caches. + pub fn max_cached_value_size() -> usize { + TRIE_LIMIT_CACHED_VALUE_SIZE + } + + /// Capacity for deletion queue in which nodes are after unforced eviction. + /// + /// The shard cache uses LRU eviction policy for forced evictions. But when a + /// trie value is overwritten or deleted, the associated nodes are no longer + /// useful, with the exception of forks. + /// Thus, deleted and overwritten values are evicted to the deletion queue which + /// delays the actual eviction. + pub fn deletions_queue_capacity(&self) -> usize { + DEFAULT_SHARD_CACHE_DELETIONS_QUEUE_CAPACITY + } +} + +impl ShardCacheConfig { + fn capacity(&self, shard_uid: ShardUId) -> u64 { + self.override_max_entries.get(&shard_uid).cloned().unwrap_or(self.default_max_entries) + } + + fn total_size_limit(&self, shard_uid: ShardUId) -> u64 { + self.override_max_total_bytes + .get(&shard_uid) + .cloned() + .unwrap_or(self.default_max_total_bytes) + } +} + +impl Default for ShardCacheConfig { + fn default() -> Self { + Self { + default_max_entries: TRIE_DEFAULT_SHARD_CACHE_SIZE, + default_max_total_bytes: DEFAULT_SHARD_CACHE_TOTAL_SIZE_LIMIT, + override_max_entries: HashMap::default(), + override_max_total_bytes: HashMap::default(), + } + } +} diff --git a/core/store/src/trie/mod.rs b/core/store/src/trie/mod.rs index 172523f9dc7..469b77434a4 100644 --- a/core/store/src/trie/mod.rs +++ b/core/store/src/trie/mod.rs @@ -14,17 +14,17 @@ use near_primitives::state_record::is_delayed_receipt_key; use near_primitives::types::{StateRoot, StateRootNode}; use crate::flat_state::FlatState; +pub use crate::trie::config::TrieConfig; use crate::trie::insert_delete::NodesStorage; use crate::trie::iterator::TrieIterator; use crate::trie::nibble_slice::NibbleSlice; -pub use crate::trie::shard_tries::{ - KeyForStateChanges, ShardTries, TrieCacheFactory, WrappedTrieChanges, -}; +pub use crate::trie::shard_tries::{KeyForStateChanges, ShardTries, WrappedTrieChanges}; pub use crate::trie::trie_storage::{TrieCache, TrieCachingStorage, TrieStorage}; use crate::trie::trie_storage::{TrieMemoryPartialStorage, TrieRecordingStorage}; use crate::StorageError; pub use near_primitives::types::TrieNodesCount; +mod config; mod insert_delete; pub mod iterator; mod nibble_slice; diff --git a/core/store/src/trie/shard_tries.rs b/core/store/src/trie/shard_tries.rs index 6d16685d1e4..3eb1b2f0342 100644 --- a/core/store/src/trie/shard_tries.rs +++ b/core/store/src/trie/shard_tries.rs @@ -5,67 +5,21 @@ use std::sync::{Arc, RwLock}; use borsh::BorshSerialize; use near_primitives::borsh::maybestd::collections::HashMap; use near_primitives::hash::CryptoHash; -use near_primitives::shard_layout; -use near_primitives::shard_layout::{ShardUId, ShardVersion}; +use near_primitives::shard_layout::{self, ShardUId, ShardVersion}; use near_primitives::trie_key::TrieKey; use near_primitives::types::{ NumShards, RawStateChange, RawStateChangesWithTrieKey, StateChangeCause, StateRoot, }; -#[cfg(feature = "protocol_feature_flat_state")] -use near_primitives::state::ValueRef; -#[cfg(feature = "protocol_feature_flat_state")] -use near_primitives::state_record::is_delayed_receipt_key; - -#[cfg(feature = "protocol_feature_flat_state")] -use crate::flat_state::FlatState; -use crate::trie::trie_storage::{TrieCache, TrieCachingStorage}; +use crate::trie::config::TrieConfig; +use crate::trie::{TrieCache, TrieCachingStorage}; use crate::trie::{TrieRefcountChange, POISONED_LOCK_ERR}; use crate::{metrics, DBCol, DBOp, DBTransaction}; use crate::{Store, StoreUpdate, Trie, TrieChanges, TrieUpdate}; -/// Responsible for creation of trie caches, stores necessary configuration for it. -#[derive(Default)] -pub struct TrieCacheFactory { - capacities: HashMap, - shard_version: ShardVersion, - num_shards: NumShards, -} - -impl TrieCacheFactory { - pub fn new( - capacities: HashMap, - shard_version: ShardVersion, - num_shards: NumShards, - ) -> Self { - Self { capacities, shard_version, num_shards } - } - - /// Create new cache for the given shard uid. - pub fn create_cache(&self, shard_uid: &ShardUId, is_view: bool) -> TrieCache { - let capacity = if is_view { None } else { self.capacities.get(shard_uid) }; - match capacity { - Some(capacity) => TrieCache::with_capacities(*capacity, shard_uid.shard_id, is_view), - None => TrieCache::new(shard_uid.shard_id, is_view), - } - } - - /// Create caches on the initialization of storage structures. - pub fn create_initial_caches(&self, is_view: bool) -> HashMap { - assert_ne!(self.num_shards, 0); - let shards: Vec<_> = (0..self.num_shards) - .map(|shard_id| ShardUId { version: self.shard_version, shard_id: shard_id as u32 }) - .collect(); - shards - .iter() - .map(|&shard_uid| (shard_uid, self.create_cache(&shard_uid, is_view))) - .collect() - } -} - struct ShardTriesInner { store: Store, - trie_cache_factory: TrieCacheFactory, + trie_config: TrieConfig, /// Cache reserved for client actor to use caches: RwLock>, /// Cache for readers. @@ -76,19 +30,43 @@ struct ShardTriesInner { pub struct ShardTries(Arc); impl ShardTries { - pub fn new(store: Store, trie_cache_factory: TrieCacheFactory) -> Self { - let caches = trie_cache_factory.create_initial_caches(false); - let view_caches = trie_cache_factory.create_initial_caches(true); + pub fn new(store: Store, trie_config: TrieConfig, shard_uids: &[ShardUId]) -> Self { + let caches = Self::create_initial_caches(&trie_config, &shard_uids, false); + let view_caches = Self::create_initial_caches(&trie_config, &shard_uids, true); ShardTries(Arc::new(ShardTriesInner { store, - trie_cache_factory, + trie_config, caches: RwLock::new(caches), view_caches: RwLock::new(view_caches), })) } + /// Create `ShardTries` with a fixed number of shards with shard version 0. + /// + /// If your test cares about the shard version, use `test_shard_version` instead. pub fn test(store: Store, num_shards: NumShards) -> Self { - Self::new(store, TrieCacheFactory::new(Default::default(), 0, num_shards)) + let shard_version = 0; + Self::test_shard_version(store, shard_version, num_shards) + } + + pub fn test_shard_version(store: Store, version: ShardVersion, num_shards: NumShards) -> Self { + assert_ne!(0, num_shards); + let shard_uids: Vec = + (0..num_shards as u32).map(|shard_id| ShardUId { shard_id, version }).collect(); + let trie_config = TrieConfig::default(); + ShardTries::new(store, trie_config, &shard_uids) + } + + /// Create caches for all shards according to the trie config. + fn create_initial_caches( + config: &TrieConfig, + shard_uids: &[ShardUId], + is_view: bool, + ) -> HashMap { + shard_uids + .iter() + .map(|&shard_uid| (shard_uid, TrieCache::new(config, shard_uid, is_view))) + .collect() } pub fn is_same(&self, other: &Self) -> bool { @@ -116,7 +94,7 @@ impl ShardTries { let mut caches = caches_to_use.write().expect(POISONED_LOCK_ERR); caches .entry(shard_uid) - .or_insert_with(|| self.0.trie_cache_factory.create_cache(&shard_uid, is_view)) + .or_insert_with(|| TrieCache::new(&self.0.trie_config, shard_uid, is_view)) .clone() }; let storage = @@ -182,7 +160,7 @@ impl ShardTries { for (shard_uid, ops) in shards { let cache = caches .entry(shard_uid) - .or_insert_with(|| self.0.trie_cache_factory.create_cache(&shard_uid, false)) + .or_insert_with(|| TrieCache::new(&self.0.trie_config, shard_uid, false)) .clone(); cache.update_cache(ops); } diff --git a/core/store/src/trie/trie_storage.rs b/core/store/src/trie/trie_storage.rs index e63fcfa05dc..48ddc071eaf 100644 --- a/core/store/src/trie/trie_storage.rs +++ b/core/store/src/trie/trie_storage.rs @@ -1,20 +1,19 @@ -use std::borrow::Borrow; -use std::collections::{HashMap, HashSet, VecDeque}; -use std::sync::{Arc, Mutex}; - -use near_metrics::prometheus; -use near_metrics::prometheus::core::{GenericCounter, GenericGauge}; -use near_primitives::hash::CryptoHash; - use crate::db::refcount::decode_value_with_rc; +use crate::trie::config::TrieConfig; use crate::trie::POISONED_LOCK_ERR; use crate::{metrics, DBCol, StorageError, Store}; use lru::LruCache; +use near_metrics::prometheus; +use near_metrics::prometheus::core::{GenericCounter, GenericGauge}; use near_o11y::log_assert; +use near_primitives::hash::CryptoHash; use near_primitives::shard_layout::ShardUId; -use near_primitives::types::{TrieCacheMode, TrieNodesCount}; +use near_primitives::types::{ShardId, TrieCacheMode, TrieNodesCount}; +use std::borrow::Borrow; use std::cell::{Cell, RefCell}; +use std::collections::{HashMap, HashSet, VecDeque}; use std::io::ErrorKind; +use std::sync::{Arc, Mutex}; pub(crate) struct BoundedQueue { queue: VecDeque, @@ -72,7 +71,7 @@ pub struct TrieCacheInner { /// Upper bound for the total size. total_size_limit: u64, /// Shard id of the nodes being cached. - shard_id: u32, + shard_id: ShardId, /// Whether cache is used for view calls execution. is_view: bool, // Counters tracking operations happening inside the shard cache. @@ -94,7 +93,7 @@ impl TrieCacheInner { cache_capacity: usize, deletions_queue_capacity: usize, total_size_limit: u64, - shard_id: u32, + shard_id: ShardId, is_view: bool, ) -> Self { assert!(cache_capacity > 0 && total_size_limit > 0); @@ -208,16 +207,15 @@ impl TrieCacheInner { pub struct TrieCache(Arc>); impl TrieCache { - pub fn new(shard_id: u32, is_view: bool) -> Self { - Self::with_capacities(TRIE_DEFAULT_SHARD_CACHE_SIZE, shard_id, is_view) - } - - pub fn with_capacities(cap: usize, shard_id: u32, is_view: bool) -> Self { + pub fn new(config: &TrieConfig, shard_uid: ShardUId, is_view: bool) -> Self { + let capacity = config.shard_cache_capacity(shard_uid, is_view); + let total_size_limit = config.shard_cache_total_size_limit(shard_uid, is_view); + let queue_capacity = config.deletions_queue_capacity(); Self(Arc::new(Mutex::new(TrieCacheInner::new( - cap, - DEFAULT_SHARD_CACHE_DELETIONS_QUEUE_CAPACITY, - DEFAULT_SHARD_CACHE_TOTAL_SIZE_LIMIT, - shard_id, + capacity as usize, + queue_capacity, + total_size_limit, + shard_uid.shard_id(), is_view, )))) } @@ -235,7 +233,7 @@ impl TrieCache { for (hash, opt_value_rc) in ops { if let Some(value_rc) = opt_value_rc { if let (Some(value), _rc) = decode_value_with_rc(&value_rc) { - if value.len() < TRIE_LIMIT_CACHED_VALUE_SIZE { + if value.len() < TrieConfig::max_cached_value_size() { guard.put(hash, value.into()); } else { guard.metrics.shard_cache_too_large.inc(); @@ -341,34 +339,6 @@ impl TrieStorage for TrieMemoryPartialStorage { } } -/// Default number of cache entries. -/// It was chosen to fit into RAM well. RAM spend on trie cache should not exceed 50_000 * 4 (number of shards) * -/// TRIE_LIMIT_CACHED_VALUE_SIZE * 2 (number of caches - for regular and view client) = 0.4 GB. -/// In our tests on a single shard, it barely occupied 40 MB, which is dominated by state cache size -/// with 512 MB limit. The total RAM usage for a single shard was 1 GB. -#[cfg(not(feature = "no_cache"))] -const TRIE_DEFAULT_SHARD_CACHE_SIZE: usize = 50000; -#[cfg(feature = "no_cache")] -const TRIE_DEFAULT_SHARD_CACHE_SIZE: usize = 1; - -/// Default total size of values which may simultaneously exist the cache. -/// It is chosen by the estimation of the largest contract storage size we are aware as of 23/08/2022. -#[cfg(not(feature = "no_cache"))] -const DEFAULT_SHARD_CACHE_TOTAL_SIZE_LIMIT: u64 = 3_000_000_000; -#[cfg(feature = "no_cache")] -const DEFAULT_SHARD_CACHE_TOTAL_SIZE_LIMIT: u64 = 1; - -/// Capacity for the deletions queue. -/// It is chosen to fit all hashes of deleted nodes for 3 completely full blocks. -#[cfg(not(feature = "no_cache"))] -const DEFAULT_SHARD_CACHE_DELETIONS_QUEUE_CAPACITY: usize = 100_000; -#[cfg(feature = "no_cache")] -const DEFAULT_SHARD_CACHE_DELETIONS_QUEUE_CAPACITY: usize = 1; - -/// Values above this size (in bytes) are never cached. -/// Note that most of Trie inner nodes are smaller than this - e.g. branches use around 32 * 16 = 512 bytes. -pub(crate) const TRIE_LIMIT_CACHED_VALUE_SIZE: usize = 1000; - pub struct TrieCachingStorage { pub(crate) store: Store, pub(crate) shard_uid: ShardUId, @@ -514,7 +484,7 @@ impl TrieStorage for TrieCachingStorage { // It is fine to have a size limit for shard cache and **not** have a limit for chunk cache, because key // is always a value hash, so for each key there could be only one value, and it is impossible to have // **different** values for the given key in shard and chunk caches. - if val.len() < TRIE_LIMIT_CACHED_VALUE_SIZE { + if val.len() < TrieConfig::max_cached_value_size() { guard.put(*hash, val.clone()); } else { self.metrics.shard_cache_too_large.inc(); diff --git a/core/store/src/trie/trie_tests.rs b/core/store/src/trie/trie_tests.rs index 5ffcf08b896..4db0cde65c8 100644 --- a/core/store/src/trie/trie_tests.rs +++ b/core/store/src/trie/trie_tests.rs @@ -204,9 +204,9 @@ mod nodes_counter_tests { mod caching_storage_tests { use super::*; use crate::test_utils::{create_test_store, create_tries}; - use crate::trie::trie_storage::{TrieCache, TrieCachingStorage, TRIE_LIMIT_CACHED_VALUE_SIZE}; + use crate::trie::trie_storage::{TrieCache, TrieCachingStorage}; use crate::trie::TrieRefcountChange; - use crate::{Store, TrieChanges}; + use crate::{Store, TrieChanges, TrieConfig}; use assert_matches::assert_matches; use near_primitives::hash::hash; use near_primitives::types::TrieCacheMode; @@ -234,7 +234,7 @@ mod caching_storage_tests { let values = vec![value.clone()]; let shard_uid = ShardUId::single_shard(); let store = create_store_with_values(&values, shard_uid); - let trie_cache = TrieCache::new(0, false); + let trie_cache = TrieCache::new(&TrieConfig::default(), shard_uid, false); let trie_caching_storage = TrieCachingStorage::new(store, trie_cache.clone(), shard_uid, false); let key = hash(&value); @@ -256,8 +256,12 @@ mod caching_storage_tests { fn test_retrieve_error() { let shard_uid = ShardUId::single_shard(); let store = create_test_store(); - let trie_caching_storage = - TrieCachingStorage::new(store, TrieCache::new(0, false), shard_uid, false); + let trie_caching_storage = TrieCachingStorage::new( + store, + TrieCache::new(&TrieConfig::default(), shard_uid, false), + shard_uid, + false, + ); let value = vec![1u8]; let key = hash(&value); @@ -268,11 +272,11 @@ mod caching_storage_tests { /// Check that large values does not fall into shard cache, but fall into chunk cache. #[test] fn test_large_value() { - let value = vec![1u8].repeat(TRIE_LIMIT_CACHED_VALUE_SIZE + 1); + let value = vec![1u8].repeat(TrieConfig::max_cached_value_size() + 1); let values = vec![value.clone()]; let shard_uid = ShardUId::single_shard(); let store = create_store_with_values(&values, shard_uid); - let trie_cache = TrieCache::new(0, false); + let trie_cache = TrieCache::new(&TrieConfig::default(), shard_uid, false); let trie_caching_storage = TrieCachingStorage::new(store, trie_cache.clone(), shard_uid, false); let key = hash(&value); @@ -295,7 +299,7 @@ mod caching_storage_tests { let values = vec![vec![1u8]]; let shard_uid = ShardUId::single_shard(); let store = create_store_with_values(&values, shard_uid); - let trie_cache = TrieCache::new(0, false); + let trie_cache = TrieCache::new(&TrieConfig::default(), shard_uid, false); let trie_caching_storage = TrieCachingStorage::new(store, trie_cache.clone(), shard_uid, false); let value = &values[0]; @@ -344,7 +348,9 @@ mod caching_storage_tests { let values: Vec> = (0..shard_cache_size as u8 + 1).map(|i| vec![i]).collect(); let shard_uid = ShardUId::single_shard(); let store = create_store_with_values(&values, shard_uid); - let trie_cache = TrieCache::with_capacities(shard_cache_size, 0, false); + let mut trie_config = TrieConfig::default(); + trie_config.shard_cache_config.override_max_entries.insert(shard_uid, shard_cache_size); + let trie_cache = TrieCache::new(&trie_config, shard_uid, false); let trie_caching_storage = TrieCachingStorage::new(store, trie_cache.clone(), shard_uid, false); diff --git a/nearcore/src/runtime/mod.rs b/nearcore/src/runtime/mod.rs index f9dcc15fe5b..edf6e3c0428 100644 --- a/nearcore/src/runtime/mod.rs +++ b/nearcore/src/runtime/mod.rs @@ -52,7 +52,7 @@ use near_store::split_state::get_delayed_receipts; use near_store::{ get_genesis_hash, get_genesis_state_roots, set_genesis_hash, set_genesis_state_roots, ApplyStatePartResult, DBCol, PartialStorage, ShardTries, Store, StoreCompiledContractCache, - StoreUpdate, Trie, TrieCacheFactory, WrappedTrieChanges, + StoreUpdate, Trie, TrieConfig, WrappedTrieChanges, }; use near_vm_runner::precompile_contract; use node_runtime::adapter::ViewRuntimeAdapter; @@ -146,6 +146,12 @@ pub struct NightshadeRuntime { impl NightshadeRuntime { pub fn from_config(home_dir: &Path, store: Store, config: &NearConfig) -> Self { + let mut trie_config = TrieConfig::default(); + trie_config + .shard_cache_config + .override_max_entries + .extend(config.config.store.trie_cache_capacities.iter().cloned()); + Self::new( home_dir, store, @@ -155,7 +161,7 @@ impl NightshadeRuntime { config.client_config.max_gas_burnt_view, None, config.config.gc.gc_num_epochs_to_keep(), - config.config.store.trie_cache_capacities.clone(), + trie_config, ) } @@ -168,7 +174,7 @@ impl NightshadeRuntime { max_gas_burnt_view: Option, runtime_config_store: Option, gc_num_epochs_to_keep: u64, - trie_cache_capacities: Vec<(ShardUId, usize)>, + trie_config: TrieConfig, ) -> Self { let runtime_config_store = match runtime_config_store { Some(store) => store, @@ -187,12 +193,11 @@ impl NightshadeRuntime { ); let state_roots = Self::initialize_genesis_state_if_needed(store.clone(), home_dir, genesis); - let trie_cache_factory = TrieCacheFactory::new( - trie_cache_capacities.into_iter().collect(), - genesis_config.shard_layout.version(), - genesis.config.num_block_producer_seats_per_shard.len() as NumShards, + let tries = ShardTries::new( + store.clone(), + trie_config, + &genesis_config.shard_layout.get_shard_uids(), ); - let tries = ShardTries::new(store.clone(), trie_cache_factory); let epoch_manager = Arc::new(RwLock::new( EpochManager::new_from_genesis_config(store.clone(), &genesis_config) .expect("Failed to start Epoch Manager"), @@ -302,12 +307,11 @@ impl NightshadeRuntime { } }); assert!(has_protocol_account, "Genesis spec doesn't have protocol treasury account"); - let trie_cache_factory = TrieCacheFactory::new( - Default::default(), - genesis.config.shard_layout.version(), - num_shards, + let tries = ShardTries::new( + store, + TrieConfig::default(), + &genesis.config.shard_layout.get_shard_uids(), ); - let tries = ShardTries::new(store, trie_cache_factory); let runtime = Runtime::new(); let runtime_config_store = NightshadeRuntime::create_runtime_config_store(&genesis.config.chain_id); diff --git a/runtime/runtime-params-estimator/src/estimator_context.rs b/runtime/runtime-params-estimator/src/estimator_context.rs index 2ddb8b2b76f..9c086ea3681 100644 --- a/runtime/runtime-params-estimator/src/estimator_context.rs +++ b/runtime/runtime-params-estimator/src/estimator_context.rs @@ -2,7 +2,7 @@ use near_primitives::shard_layout::ShardUId; use std::collections::HashMap; use near_primitives::transaction::SignedTransaction; -use near_store::{TrieCache, TrieCachingStorage}; +use near_store::{TrieCache, TrieCachingStorage, TrieConfig}; use near_vm_logic::ExtCosts; use crate::config::{Config, GasMetric}; @@ -125,7 +125,7 @@ impl<'c> Testbed<'c> { let store = self.inner.store(); let caching_storage = TrieCachingStorage::new( store, - TrieCache::new(0, false), + TrieCache::new(&TrieConfig::default(), ShardUId::single_shard(), false), ShardUId::single_shard(), false, );