Skip to content

Commit

Permalink
Add object state cache for moveos (#2914)
Browse files Browse the repository at this point in the history
add cache in StateDBStore
  • Loading branch information
pause125 authored Nov 27, 2024
1 parent f2ccbde commit b70ff13
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 6 deletions.
13 changes: 13 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,7 @@ tower_governor = { version = "0.4.3", features = ["tracing"] }
pin-project = "1.1.7"
mirai-annotations = "1.12.0"
lru = "0.11.0"
quick_cache = "0.6.9"
bs58 = "0.5.1"
dirs-next = "2.0.0"
anstream = { version = "0.3" }
Expand Down
19 changes: 19 additions & 0 deletions moveos/moveos-config/src/store_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,3 +80,22 @@ impl Default for RocksdbConfig {
}
}
}

#[derive(Copy, Clone, Debug, Deserialize, PartialEq, Eq, Serialize, Parser)]
#[serde(default, deny_unknown_fields)]
pub struct MoveOSStoreConfig {
#[clap(
name = "moveos-store-state-cache-size",
long,
help = "MoveOS store state cache size"
)]
pub state_cache_size: usize,
}

impl Default for MoveOSStoreConfig {
fn default() -> Self {
Self {
state_cache_size: 10_000,
}
}
}
3 changes: 2 additions & 1 deletion moveos/moveos-store/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,5 @@ moveos-types = { workspace = true }
raw-store = { workspace = true }
moveos-config = { workspace = true }
accumulator = { workspace = true }
metrics = { workspace = true }
metrics = { workspace = true }
quick_cache = { workspace = true }
6 changes: 4 additions & 2 deletions moveos/moveos-store/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use accumulator::inmemory::InMemoryAccumulator;
use anyhow::{Error, Result};
use bcs::to_bytes;
use move_core_types::language_storage::StructTag;
use moveos_config::store_config::RocksdbConfig;
use moveos_config::store_config::{MoveOSStoreConfig, RocksdbConfig};
use moveos_config::DataDirPath;
use moveos_types::genesis_info::GenesisInfo;
use moveos_types::h256::H256;
Expand Down Expand Up @@ -100,8 +100,10 @@ impl MoveOSStore {
}

pub fn new_with_instance(instance: StoreInstance, registry: &Registry) -> Result<Self> {
let store_config = MoveOSStoreConfig::default();
let node_store = NodeDBStore::new(instance.clone());
let state_store = StateDBStore::new(node_store.clone(), registry);
let state_store =
StateDBStore::new(node_store.clone(), registry, store_config.state_cache_size);

let store = Self {
node_store,
Expand Down
22 changes: 19 additions & 3 deletions moveos/moveos-store/src/state_store/statedb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use moveos_types::state_resolver::StateKV;
use moveos_types::state_resolver::StateResolver;
use moveos_types::state_resolver::StatelessResolver;
use prometheus::Registry;
use quick_cache::sync::Cache;
use smt::{SMTIterator, TreeChangeSet};
use smt::{SMTree, UpdateSet};
use std::collections::BTreeMap;
Expand All @@ -31,14 +32,16 @@ pub struct StateDBStore {
pub node_store: NodeDBStore,
smt: SMTree<FieldKey, ObjectState, NodeDBStore>,
metrics: Arc<StateDBMetrics>,
cache: Arc<Cache<(H256, FieldKey), Option<ObjectState>>>,
}

impl StateDBStore {
pub fn new(node_store: NodeDBStore, registry: &Registry) -> Self {
pub fn new(node_store: NodeDBStore, registry: &Registry, cache_size: usize) -> Self {
Self {
node_store: node_store.clone(),
smt: SMTree::new(node_store, registry),
metrics: Arc::new(StateDBMetrics::new(registry)),
cache: Arc::new(Cache::new(cache_size)),
}
}

Expand Down Expand Up @@ -97,6 +100,8 @@ impl StateDBStore {
Op::Delete => {
//TODO clean up the removed object fields
update_set.remove(field_key);
let pre_state_root = obj_change.metadata.state_root();
self.cache.remove(&(pre_state_root, field_key));
return Ok(());
}
},
Expand Down Expand Up @@ -126,7 +131,8 @@ impl StateDBStore {
let new_state_root = tree_change_set.state_root;
obj.update_state_root(new_state_root);
obj_change.update_state_root(new_state_root);
update_set.put(field_key, obj);
update_set.put(field_key, obj.clone());
self.cache.insert((new_state_root, field_key), Some(obj));

Ok(())
}
Expand Down Expand Up @@ -225,7 +231,14 @@ impl StatelessResolver for StateDBStore {
if state_root == *GENESIS_STATE_ROOT {
return Ok(None);
}
let result = self.smt.get(state_root, *key)?;

let result = if let Some(state) = self.cache.get(&(state_root, *key)) {
state
} else {
let state = self.smt.get(state_root, *key)?;
self.cache.insert((state_root, *key), state.clone());
state
};
if tracing::enabled!(tracing::Level::TRACE) {
let result_info = match &result {
Some(state) => format!("Some({})", state.metadata.object_type),
Expand Down Expand Up @@ -261,6 +274,9 @@ impl StatelessResolver for StateDBStore {
.with_label_values(&[fn_name])
.start_timer();
let result = self.smt.list(state_root, cursor, limit)?;
for (key, state) in &result {
self.cache.insert((state_root, *key), Some(state.clone()));
}

// Only statistics object value bytes to avoid performance loss caused by serialization
let size = result
Expand Down

0 comments on commit b70ff13

Please sign in to comment.