diff --git a/Cargo.lock b/Cargo.lock index e1dafe7..bd04cac 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -224,6 +224,7 @@ dependencies = [ "eth2_ssz_derive", "ethereum-types 0.14.1", "lazy_static", + "metrics", "once_cell", "serde", "tiny-keccak", diff --git a/common/append_merkle/Cargo.toml b/common/append_merkle/Cargo.toml index 21543b2..954a4c9 100644 --- a/common/append_merkle/Cargo.toml +++ b/common/append_merkle/Cargo.toml @@ -12,4 +12,6 @@ eth2_ssz_derive = "0.3.0" serde = { version = "1.0.137", features = ["derive"] } lazy_static = "1.4.0" tracing = "0.1.36" -once_cell = "1.19.0" \ No newline at end of file +once_cell = "1.19.0" + +metrics = { workspace = true } diff --git a/common/append_merkle/src/lib.rs b/common/append_merkle/src/lib.rs index e0548fe..ccb2ebb 100644 --- a/common/append_merkle/src/lib.rs +++ b/common/append_merkle/src/lib.rs @@ -1,4 +1,5 @@ mod merkle_tree; +mod metrics; mod proof; mod sha3; @@ -7,6 +8,7 @@ use std::cmp::Ordering; use std::collections::{BTreeMap, HashMap}; use std::fmt::Debug; use std::marker::PhantomData; +use std::time::Instant; use tracing::{trace, warn}; pub use crate::merkle_tree::{ @@ -138,15 +140,18 @@ impl> AppendMerkleTree { } pub fn append(&mut self, new_leaf: E) { + let start_time = Instant::now(); if new_leaf == E::null() { // appending null is not allowed. return; } self.layers[0].push(new_leaf); self.recompute_after_append_leaves(self.leaves() - 1); + metrics::APPEND.update_since(start_time); } pub fn append_list(&mut self, mut leaf_list: Vec) { + let start_time = Instant::now(); if leaf_list.contains(&E::null()) { // appending null is not allowed. return; @@ -154,6 +159,8 @@ impl> AppendMerkleTree { let start_index = self.leaves(); self.layers[0].append(&mut leaf_list); self.recompute_after_append_leaves(start_index); + + metrics::APPEND_LIST.update_since(start_time); } /// Append a leaf list by providing their intermediate node hash. @@ -162,6 +169,7 @@ impl> AppendMerkleTree { /// Other nodes in the subtree will be set to `null` nodes. /// TODO: Optimize to avoid storing the `null` nodes? pub fn append_subtree(&mut self, subtree_depth: usize, subtree_root: E) -> Result<()> { + let start_time = Instant::now(); if subtree_root == E::null() { // appending null is not allowed. bail!("subtree_root is null"); @@ -169,10 +177,13 @@ impl> AppendMerkleTree { let start_index = self.leaves(); self.append_subtree_inner(subtree_depth, subtree_root)?; self.recompute_after_append_subtree(start_index, subtree_depth - 1); + + metrics::APPEND_SUBTREE.update_since(start_time); Ok(()) } pub fn append_subtree_list(&mut self, subtree_list: Vec<(usize, E)>) -> Result<()> { + let start_time = Instant::now(); if subtree_list.iter().any(|(_, root)| root == &E::null()) { // appending null is not allowed. bail!("subtree_list contains null"); @@ -182,12 +193,14 @@ impl> AppendMerkleTree { self.append_subtree_inner(subtree_depth, subtree_root)?; self.recompute_after_append_subtree(start_index, subtree_depth - 1); } + metrics::APPEND_SUBTREE_LIST.update_since(start_time); Ok(()) } /// Change the value of the last leaf and return the new merkle root. /// This is needed if our merkle-tree in memory only keeps intermediate nodes instead of real leaves. pub fn update_last(&mut self, updated_leaf: E) { + let start_time = Instant::now(); if updated_leaf == E::null() { // updating to null is not allowed. return; @@ -199,6 +212,7 @@ impl> AppendMerkleTree { *self.layers[0].last_mut().unwrap() = updated_leaf; } self.recompute_after_append_leaves(self.leaves() - 1); + metrics::UPDATE_LAST.update_since(start_time); } /// Fill an unknown `null` leaf with its real value. diff --git a/common/append_merkle/src/metrics.rs b/common/append_merkle/src/metrics.rs new file mode 100644 index 0000000..cafa42f --- /dev/null +++ b/common/append_merkle/src/metrics.rs @@ -0,0 +1,11 @@ +use std::sync::Arc; + +use metrics::{register_timer, Timer}; + +lazy_static::lazy_static! { + pub static ref APPEND: Arc = register_timer("append_merkle_append"); + pub static ref APPEND_LIST: Arc = register_timer("append_merkle_append_list"); + pub static ref APPEND_SUBTREE: Arc = register_timer("append_merkle_append_subtree"); + pub static ref APPEND_SUBTREE_LIST: Arc = register_timer("append_merkle_append_subtree_list"); + pub static ref UPDATE_LAST: Arc = register_timer("append_merkle_update_last"); +} diff --git a/node/storage/src/log_store/flow_store.rs b/node/storage/src/log_store/flow_store.rs index 687386c..994f96a 100644 --- a/node/storage/src/log_store/flow_store.rs +++ b/node/storage/src/log_store/flow_store.rs @@ -234,6 +234,7 @@ impl FlowWrite for FlowStore { /// Return the roots of completed chunks. The order is guaranteed to be increasing /// by chunk index. fn append_entries(&self, data: ChunkArray) -> Result> { + let start_time = Instant::now(); let mut to_seal_set = self.seal_manager.to_seal_set.write(); trace!("append_entries: {} {}", data.start_index, data.data.len()); if data.data.len() % BYTES_PER_SECTOR != 0 { @@ -276,6 +277,8 @@ impl FlowWrite for FlowStore { batch_list.push((chunk_index, batch)); } + + metrics::APPEND_ENTRIES.update_since(start_time); self.db.put_entry_batch_list(batch_list) } @@ -385,6 +388,7 @@ impl FlowDBStore { &self, batch_list: Vec<(u64, EntryBatch)>, ) -> Result> { + let start_time = Instant::now(); let mut completed_batches = Vec::new(); let mut tx = self.kvdb.transaction(); for (batch_index, batch) in batch_list { @@ -405,6 +409,7 @@ impl FlowDBStore { } } self.kvdb.write(tx)?; + metrics::PUT_ENTRY_BATCH_LIST.update_since(start_time); Ok(completed_batches) } diff --git a/node/storage/src/log_store/log_manager.rs b/node/storage/src/log_store/log_manager.rs index b9cdcc0..d75a091 100644 --- a/node/storage/src/log_store/log_manager.rs +++ b/node/storage/src/log_store/log_manager.rs @@ -1280,6 +1280,7 @@ pub fn sub_merkle_tree(leaf_data: &[u8]) -> Result { } pub fn data_to_merkle_leaves(leaf_data: &[u8]) -> Result> { + let start_time = Instant::now(); if leaf_data.len() % ENTRY_SIZE != 0 { bail!("merkle_tree: mismatched data size"); } @@ -1295,6 +1296,8 @@ pub fn data_to_merkle_leaves(leaf_data: &[u8]) -> Result> { .map(Sha3Algorithm::leaf) .collect() }; + + metrics::DATA_TO_MERKLE_LEAVES.update_since(start_time); Ok(r) } diff --git a/node/storage/src/log_store/metrics.rs b/node/storage/src/log_store/metrics.rs index 2b9ead4..64c480e 100644 --- a/node/storage/src/log_store/metrics.rs +++ b/node/storage/src/log_store/metrics.rs @@ -11,6 +11,9 @@ lazy_static::lazy_static! { pub static ref APPEND_SUBTREE_LIST: Arc = register_timer("log_store_log_manager_append_subtree_list"); + pub static ref DATA_TO_MERKLE_LEAVES: Arc = + register_timer("log_store_log_manager_data_to_merkle_leaves"); + pub static ref COPY_TX_AND_FINALIZE: Arc = register_timer("log_store_log_manager_copy_tx_and_finalize"); @@ -19,7 +22,12 @@ lazy_static::lazy_static! { pub static ref PUT_BATCH_ROOT_LIST: Arc = register_timer("log_store_flow_store_put_batch_root_list"); pub static ref INSERT_SUBTREE_LIST: Arc = - register_timer("log_store_log_manager_insert_subtree_list"); + register_timer("log_store_flow_store_insert_subtree_list"); - pub static ref PUT_MPT_NODE: Arc = register_timer("log_store_log_manager_put_mpt_node"); + pub static ref PUT_MPT_NODE: Arc = register_timer("log_store_flow_store_put_mpt_node"); + + pub static ref PUT_ENTRY_BATCH_LIST: Arc = + register_timer("log_store_flow_store_put_entry_batch_list"); + + pub static ref APPEND_ENTRIES: Arc = register_timer("log_store_flow_store_append_entries"); }