From f8f8ec854b0f3b09854119265386c8658c1160d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BB=A4=E7=8B=90=E4=B8=80=E5=86=B2?= <43949039+anonymousGiga@users.noreply.github.com> Date: Thu, 7 Mar 2024 13:27:32 +0800 Subject: [PATCH] Revert "refactor: refactoring of perf metric related code. (#48)" This reverts commit 3203e2a5373cf6edcaef01b1ff9cf958e9cc3e1e. --- Cargo.lock | 3 + crates/perf-metrics/Cargo.toml | 3 + crates/perf-metrics/src/dashboard/cache.rs | 65 ++- crates/perf-metrics/src/dashboard/opcode.rs | 207 ++++----- crates/perf-metrics/src/dashboard/tps_gas.rs | 5 +- crates/perf-metrics/src/metrics/duration.rs | 72 +-- crates/perf-metrics/src/metrics/metric.rs | 435 ++++++++++++++++++- crates/perf-metrics/src/metrics/mod.rs | 3 +- crates/perf-metrics/src/metrics/tps_gas.rs | 6 +- crates/storage/libmdbx-rs/Cargo.toml | 1 + 10 files changed, 600 insertions(+), 200 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d082cc1ae98eb..32fb656298e9b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4969,7 +4969,9 @@ name = "perf-metrics" version = "0.1.0" dependencies = [ "ctor 0.2.6", + "libc", "minstant", + "reth-mdbx-sys", "revm", "revm-utils", "tokio", @@ -6248,6 +6250,7 @@ dependencies = [ "libc", "libffi", "parking_lot 0.12.1", + "perf-metrics", "pprof", "rand 0.8.5", "rand_xorshift", diff --git a/crates/perf-metrics/Cargo.toml b/crates/perf-metrics/Cargo.toml index a5b18d25e2953..1a2cd76774d03 100644 --- a/crates/perf-metrics/Cargo.toml +++ b/crates/perf-metrics/Cargo.toml @@ -12,6 +12,9 @@ tokio = { workspace = true, features = ["sync"] } revm-utils = { workspace = true, optional = true } revm = { workspace = true, optional = true } +ffi = { package = "reth-mdbx-sys", path = "../storage/libmdbx-rs/mdbx-sys" } +libc = "0.2" + [features] enable_opcode_metrics = [ "revm-utils", diff --git a/crates/perf-metrics/src/dashboard/cache.rs b/crates/perf-metrics/src/dashboard/cache.rs index e3dfa66800aaf..a683890bf3b7f 100644 --- a/crates/perf-metrics/src/dashboard/cache.rs +++ b/crates/perf-metrics/src/dashboard/cache.rs @@ -38,14 +38,37 @@ impl Default for CacheStats { } } -impl From<&CacheDbRecord> for CacheStats { - fn from(record: &CacheDbRecord) -> Self { +impl Print for CacheStats { + fn print_title(&self) { + println!("================================================ Metric of State ==========================================="); + println!( + "{: COL_WIDTH_MIDDLE$}{:>COL_WIDTH_MIDDLE$}{:>COL_WIDTH_BIG$}{:>COL_WIDTH_BIG$}{:>COL_WIDTH_BIG$}", + "State functions", "Hits", "Misses", "Miss ratio (%)","Penalty time(s)", "Avg penalty (us)" + ); + } + + fn print_content(&self) { + self.print_item("blockhash", Function::BlockHash as usize); + self.print_item("code_by_hash", Function::CodeByHash as usize); + self.print_item("load_account/basic", Function::LoadCacheAccount as usize); + self.print_item("storage", Function::Storage as usize); + self.print_item("total", CACHE_STATS_LEN - 1); + } +} + +trait StatsAndPrint { + fn stats(&self) -> CacheStats; + fn print_penalty_distribution(&self); +} + +impl StatsAndPrint for CacheDbRecord { + fn stats(&self) -> CacheStats { let mut cache_stats = CacheStats::default(); - let total_stats = record.access_count(); - let hit_stats = record.hit_stats(); - let miss_stats = record.miss_stats(); - let penalty_stats = record.penalty_stats(); + let total_stats = self.access_count(); + let hit_stats = self.hit_stats(); + let miss_stats = self.miss_stats(); + let penalty_stats = self.penalty_stats(); for index in 0..total_stats.function.len() { cache_stats.functions[index].hits = hit_stats.function[index]; @@ -71,32 +94,8 @@ impl From<&CacheDbRecord> for CacheStats { cache_stats } -} - -impl Print for CacheStats { - fn print_title(&self) { - println!("================================================ Metric of State ==========================================="); - println!( - "{: COL_WIDTH_MIDDLE$}{:>COL_WIDTH_MIDDLE$}{:>COL_WIDTH_BIG$}{:>COL_WIDTH_BIG$}{:>COL_WIDTH_BIG$}", - "State functions", "Hits", "Misses", "Miss ratio (%)","Penalty time(s)", "Avg penalty (us)" - ); - } - - fn print_content(&self) { - self.print_item("blockhash", Function::BlockHash as usize); - self.print_item("code_by_hash", Function::CodeByHash as usize); - self.print_item("load_account/basic", Function::LoadCacheAccount as usize); - self.print_item("storage", Function::Storage as usize); - self.print_item("total", CACHE_STATS_LEN - 1); - } -} - -trait PrintPenalty { - fn print_penalty(&self); -} -impl PrintPenalty for CacheDbRecord { - fn print_penalty(&self) { + fn print_penalty_distribution(&self) { println!(); println!("================Penalty percentile============="); self.penalty_stats().percentile.print_content(); @@ -106,8 +105,8 @@ impl PrintPenalty for CacheDbRecord { impl Print for CacheDbRecord { fn print(&self, _block_number: u64) { - Into::::into(self).print(_block_number); - self.print_penalty(); + self.stats().print(_block_number); + self.print_penalty_distribution(); } } diff --git a/crates/perf-metrics/src/dashboard/opcode.rs b/crates/perf-metrics/src/dashboard/opcode.rs index 62efdc393de09..bea051f65784f 100644 --- a/crates/perf-metrics/src/dashboard/opcode.rs +++ b/crates/perf-metrics/src/dashboard/opcode.rs @@ -1,24 +1,20 @@ //! This module is used to support the display of opcode statistics metrics. -use super::commons::*; use revm::revm_opcode::*; -use revm_utils::{metrics::types::OpcodeRecord, time_utils::convert_cycles_to_ns_f64}; -use std::collections::BTreeMap; +use revm_utils::metrics::types::OpcodeRecord; -const MGAS_TO_GAS: u64 = 1_000_000u64; -const COL_WIDTH: usize = 15; -const OPCODE_NUMBER: usize = 256; +pub(crate) const OPCODE_NUMBER: usize = 256; #[derive(Debug, Clone, Copy, Default)] -struct OpcodeInfo { +pub(crate) struct OpcodeInfo { /// opcode category - category: &'static str, + pub(crate) category: &'static str, /// gas fee - gas: u64, + pub(crate) gas: u64, /// opcode cost a fixed gas fee? - static_gas: bool, + pub(crate) static_gas: bool, } -const MERGE_MAP: [Option<(u8, OpcodeInfo)>; OPCODE_NUMBER] = [ +pub(crate) const MERGE_MAP: [Option<(u8, OpcodeInfo)>; OPCODE_NUMBER] = [ Some((STOP, OpcodeInfo { category: "stop", gas: 0, static_gas: true })), //0x00 Some((ADD, OpcodeInfo { category: "arithmetic", gas: 3, static_gas: true })), //0x01 Some((MUL, OpcodeInfo { category: "arithmetic", gas: 5, static_gas: true })), //0x02 @@ -277,6 +273,12 @@ const MERGE_MAP: [Option<(u8, OpcodeInfo)>; OPCODE_NUMBER] = [ Some((SELFDESTRUCT, OpcodeInfo { category: "host", gas: 5000, static_gas: false })), //0xff ]; +use super::commons::*; +use revm_utils::time_utils::convert_cycles_to_ns_f64; +use std::collections::BTreeMap; +const MGAS_TO_GAS: u64 = 1_000_000u64; + +const COL_WIDTH: usize = 15; #[derive(Default, Debug)] struct OpcodeMergeRecord { count: u64, @@ -336,6 +338,92 @@ impl OpcodeStat { } } +#[derive(Debug)] +struct OpcodeStats { + overall: OpcodeStat, + opcode: [Option; OPCODE_NUMBER], + merge_records: BTreeMap<&'static str, OpcodeMergeRecord>, +} + +const ARRAY_REPEAT_VALUE: std::option::Option = None; +impl Default for OpcodeStats { + fn default() -> Self { + Self { + overall: OpcodeStat::default(), + opcode: [ARRAY_REPEAT_VALUE; OPCODE_NUMBER], + merge_records: BTreeMap::new(), + } + } +} + +impl OpcodeStats { + fn print_opcode_title(&self) { + println!("===========================================================================Metric of instruction======================================================================"); + println!( + "{: COL_WIDTH$}{:>COL_WIDTH$}{:>COL_WIDTH$}{:>COL_WIDTH$} \ + {:>COL_WIDTH$}{:>COL_WIDTH$}{:>COL_WIDTH$}{:>COL_WIDTH$}{:>COL_WIDTH$}{:>COL_WIDTH$}", + "Opcode", + "Count", + "Count (%)", + "Time (s)", + "Time (%)", + "Cost (ns)", + "Total Mgas", + "Gas (%)", + "Static gas", + "Dyn. gas", + "Category" + ); + } + + fn print_opcodes(&self) { + println!(); + self.print_opcode_title(); + self.overall.print("overall"); + for i in 0..OPCODE_NUMBER { + let name = OpCode::new(i as u8); + if name.is_none() { + continue + } + self.opcode[i] + .as_ref() + .expect("opcode record should not empty") + .print(name.unwrap().as_str()); + } + println!(); + } + + fn print_category(&self) { + println!("\n"); + println!("=========================================================================================="); + println!( + "{:COL_WIDTH$}{:>COL_WIDTH$}{:>COL_WIDTH$}{:>COL_WIDTH$}{:>COL_WIDTH$}", + "Opcode Cat.", "Count", "Count (%)", "Time (s)", "Time (%)", "Cost (ns)", + ); + + for (k, v) in self.merge_records.iter() { + if *k == "" { + continue + } + println!( + "{:COL_WIDTH$}{:>COL_WIDTH$.2}{:>COL_WIDTH$.1}{:>COL_WIDTH$.3}{:>COL_WIDTH$.3}", + *k, + v.count, + v.count_pct * 100.0, + cycles_as_secs(v.time), + v.time_pct * 100.0, + v.avg_cost, + ); + } + } +} + +trait SupportPrint { + fn stats(&self) -> OpcodeStats; + fn print_addition_count(&self); + fn print_sload_percentile(&self); +} + // Return (total_gas, static_gas, dyn_gas). fn caculate_gas(opcode: u8, count: u64, total_gas: i128) -> (f64, u64, f64) { let (base_gas, is_static) = match MERGE_MAP[opcode as usize] { @@ -361,29 +449,11 @@ fn category_name(opcode: u8) -> Option<&'static str> { Some(MERGE_MAP[opcode as usize]?.1.category) } -#[derive(Debug)] -struct OpcodeStats { - overall: OpcodeStat, - opcode: [Option; OPCODE_NUMBER], - merge_records: BTreeMap<&'static str, OpcodeMergeRecord>, -} - -const ARRAY_REPEAT_VALUE: std::option::Option = None; -impl Default for OpcodeStats { - fn default() -> Self { - Self { - overall: OpcodeStat::default(), - opcode: [ARRAY_REPEAT_VALUE; OPCODE_NUMBER], - merge_records: BTreeMap::new(), - } - } -} - -impl From<&OpcodeRecord> for OpcodeStats { - fn from(record: &OpcodeRecord) -> Self { +impl SupportPrint for OpcodeRecord { + fn stats(&self) -> OpcodeStats { let mut opcode_stats = OpcodeStats::default(); // induction - for (i, v) in record.opcode_record.iter().enumerate() { + for (i, v) in self.opcode_record.iter().enumerate() { // opcode let op = i as u8; let mut opcode_stat = OpcodeStat::default(); @@ -427,7 +497,7 @@ impl From<&OpcodeRecord> for OpcodeStats { } // calculate opcode pct - for (i, _v) in record.opcode_record.iter().enumerate() { + for (i, _v) in self.opcode_record.iter().enumerate() { opcode_stats.opcode[i].as_mut().expect("empty").count_pct = opcode_stats.opcode[i].as_mut().expect("empty").count as f64 / opcode_stats.overall.count as f64; @@ -453,76 +523,7 @@ impl From<&OpcodeRecord> for OpcodeStats { opcode_stats } -} - -impl OpcodeStats { - fn print_opcode_title(&self) { - println!("===========================================================================Metric of instruction======================================================================"); - println!( - "{: COL_WIDTH$}{:>COL_WIDTH$}{:>COL_WIDTH$}{:>COL_WIDTH$} \ - {:>COL_WIDTH$}{:>COL_WIDTH$}{:>COL_WIDTH$}{:>COL_WIDTH$}{:>COL_WIDTH$}{:>COL_WIDTH$}", - "Opcode", - "Count", - "Count (%)", - "Time (s)", - "Time (%)", - "Cost (ns)", - "Total Mgas", - "Gas (%)", - "Static gas", - "Dyn. gas", - "Category" - ); - } - - fn print_opcodes(&self) { - println!(); - self.print_opcode_title(); - self.overall.print("overall"); - for i in 0..OPCODE_NUMBER { - let name = OpCode::new(i as u8); - if name.is_none() { - continue - } - self.opcode[i] - .as_ref() - .expect("opcode record should not empty") - .print(name.unwrap().as_str()); - } - println!(); - } - - fn print_category(&self) { - println!("\n"); - println!("=========================================================================================="); - println!( - "{:COL_WIDTH$}{:>COL_WIDTH$}{:>COL_WIDTH$}{:>COL_WIDTH$}{:>COL_WIDTH$}", - "Opcode Cat.", "Count", "Count (%)", "Time (s)", "Time (%)", "Cost (ns)", - ); - - for (k, v) in self.merge_records.iter() { - if *k == "" { - continue - } - println!( - "{:COL_WIDTH$}{:>COL_WIDTH$.2}{:>COL_WIDTH$.1}{:>COL_WIDTH$.3}{:>COL_WIDTH$.3}", - *k, - v.count, - v.count_pct * 100.0, - cycles_as_secs(v.time), - v.time_pct * 100.0, - v.avg_cost, - ); - } - } -} - -trait ExtraPrint { - fn print_addition_count(&self); - fn print_sload_percentile(&self); -} -impl ExtraPrint for OpcodeRecord { fn print_addition_count(&self) { println!(); println!("call additional rdtsc count: {}", self.additional_count[0]); @@ -540,7 +541,7 @@ impl ExtraPrint for OpcodeRecord { impl Print for OpcodeRecord { fn print(&self, _block_number: u64) { - let opcode_stats: OpcodeStats = self.into(); + let opcode_stats = self.stats(); opcode_stats.print_opcodes(); opcode_stats.print_category(); self.print_addition_count(); diff --git a/crates/perf-metrics/src/dashboard/tps_gas.rs b/crates/perf-metrics/src/dashboard/tps_gas.rs index c6a2bc8751fcc..9e1b6bcadc2e0 100644 --- a/crates/perf-metrics/src/dashboard/tps_gas.rs +++ b/crates/perf-metrics/src/dashboard/tps_gas.rs @@ -1,10 +1,9 @@ -//! This module is used to support the display of tps and mgas/s. use crate::metrics::TpsAndGasMessage; use revm_utils::time_utils::instant::Instant; use std::ops::{Div, Mul}; #[derive(Debug, Default)] -pub(super) struct TpsAndGasDisplayer { +pub(crate) struct TpsAndGasDisplayer { pre_txs: u128, pre_gas: u128, last_txs: u128, @@ -51,7 +50,7 @@ impl TpsAndGasDisplayer { println!("block_number: {:?}, MGas: {:.3}\n", block_number, mgas_ps); } - pub(super) fn print(&mut self, block_number: u64, message: TpsAndGasMessage) { + pub fn print(&mut self, block_number: u64, message: TpsAndGasMessage) { match message { TpsAndGasMessage::Record(record) => { self.update_tps_and_gas(record.block_number, record.txs, record.gas) diff --git a/crates/perf-metrics/src/metrics/duration.rs b/crates/perf-metrics/src/metrics/duration.rs index c8172f5fb2f9b..3c1607d1a8345 100644 --- a/crates/perf-metrics/src/metrics/duration.rs +++ b/crates/perf-metrics/src/metrics/duration.rs @@ -6,19 +6,19 @@ use revm_utils::{metrics::types::TransactTime, time_utils::instant::Instant}; #[derive(Debug, Clone, Copy, Default)] pub struct ExecutionDurationRecord { // Total time recorder. - pub(crate) total_recorder: Instant, + pub total_recorder: Instant, // General time recorder. - pub(crate) time_recorder: Instant, + pub time_recorder: Instant, // Time of execute inner. - pub(crate) total: u64, + pub total: u64, // Time of get_block_td. - pub(crate) block_td: u64, + pub block_td: u64, // Time of block_with_senders. - pub(crate) block_with_senders: u64, + pub block_with_senders: u64, // Record of txs execution(execute_and_verify_receipt). - pub(crate) execution: ExecuteTxsRecord, + pub execution: ExecuteTxsRecord, // Record of write to db - pub(crate) write_to_db: WriteToDbRecord, + pub write_to_db: WriteToDbRecord, } // The following functions are used to record overhead. @@ -43,23 +43,23 @@ pub struct ExecuteTxsRecord { /// Record the start time of each subfunction. sub_record: Instant, /// Time of execute_and_verify_receipt. - pub(crate) total: u64, + pub total: u64, /// Time of transact. - pub(crate) transact: u64, + pub transact: u64, /// Time of revm's transact. - pub(crate) revm_transact: TransactTime, + pub revm_transact: TransactTime, /// Time of commit changes. - pub(crate) commit_changes: u64, + pub commit_changes: u64, /// Time of add receipt. - pub(crate) add_receipt: u64, + pub add_receipt: u64, /// Time of apply_post_execution_state_change. - pub(crate) apply_post_execution_state_change: u64, + pub apply_post_execution_state_change: u64, /// Time of merge_transactions. - pub(crate) merge_transactions: u64, + pub merge_transactions: u64, /// Time of verify_receipt. - pub(crate) verify_receipt: u64, + pub verify_receipt: u64, /// Time of save_receipts. - pub(crate) save_receipts: u64, + pub save_receipts: u64, } impl ExecuteTxsRecord { @@ -118,50 +118,50 @@ pub struct WriteToDbRecord { write_start_record: Instant, /// Time of write_to_db. - pub(crate) total: u64, + pub total: u64, /// Time of write storage changes in StateReverts. - pub(crate) revert_storage_time: u64, + pub revert_storage_time: u64, /// Data size of write storage changes in StateReverts. - pub(crate) revert_storage_size: usize, + pub revert_storage_size: usize, /// Time of append_dup when write storage changes in StateReverts. - pub(crate) revert_storage_append_time: u64, + pub revert_storage_append_time: u64, /// Time of write account changes in StateReverts. - pub(crate) revert_account_time: u64, + pub revert_account_time: u64, /// Data size of write account changes in StateReverts. - pub(crate) revert_account_size: usize, + pub revert_account_size: usize, /// Time of append_dup when write account changes in StateReverts. - pub(crate) revert_account_append_time: u64, + pub revert_account_append_time: u64, /// Time of write receipts. - pub(crate) write_receipts_time: u64, + pub write_receipts_time: u64, /// Data size of write receipts. - pub(crate) write_receipts_size: usize, + pub write_receipts_size: usize, /// Time of append when write receipts. - pub(crate) receipts_append_time: u64, + pub receipts_append_time: u64, /// Time of sort in StateChanges's write_to_db. - pub(crate) sort_time: u64, + pub sort_time: u64, /// Time of write account in StateChanges. - pub(crate) state_account_time: u64, + pub state_account_time: u64, /// Data size of write account in StateChanges. - pub(crate) state_account_size: usize, + pub state_account_size: usize, /// Time of upsert when write account changes in StateChanges. - pub(crate) state_account_upsert_time: u64, + pub state_account_upsert_time: u64, /// Time of write bytecode in StateChanges. - pub(crate) state_bytecode_time: u64, + pub state_bytecode_time: u64, /// Data size of write bytecode in StateChanges. - pub(crate) state_bytecode_size: usize, + pub state_bytecode_size: usize, /// Time of upsert when write bytecode in StateChanges. - pub(crate) state_bytecode_upsert_time: u64, + pub state_bytecode_upsert_time: u64, /// Time of write storage in StateChanges. - pub(crate) state_storage_time: u64, + pub state_storage_time: u64, /// Data size of write storage in StateChanges. - pub(crate) state_storage_size: usize, + pub state_storage_size: usize, /// Time of upsert when write storage in StateChanges. - pub(crate) state_storage_upsert_time: u64, + pub state_storage_upsert_time: u64, } impl WriteToDbRecord { diff --git a/crates/perf-metrics/src/metrics/metric.rs b/crates/perf-metrics/src/metrics/metric.rs index bb0e419fc270f..530d5052ebc86 100644 --- a/crates/perf-metrics/src/metrics/metric.rs +++ b/crates/perf-metrics/src/metrics/metric.rs @@ -1,23 +1,14 @@ //! This module provides a metric to measure reth. -// #[cfg(feature = "enable_execution_duration_record")] -// pub use super::duration::ExecuteTxsRecord; #[cfg(feature = "enable_execution_duration_record")] -use super::duration::ExecutionDurationRecord; +use super::duration::{ExecuteTxsRecord, ExecutionDurationRecord}; #[cfg(feature = "enable_tps_gas_record")] -pub use super::tps_gas::TpsAndGasMessage; -#[cfg(feature = "enable_tps_gas_record")] -use super::tps_gas::TpsGasRecord; +use super::tps_gas::{TpsAndGasMessage, TpsGasRecord}; #[cfg(feature = "enable_cache_record")] use revm_utils::metrics::types::CacheDbRecord; #[cfg(feature = "enable_opcode_metrics")] use revm_utils::metrics::types::OpcodeRecord; -use tokio::sync::mpsc::UnboundedSender; -pub use super::execute_measure::execute_inner::*; -#[cfg(feature = "enable_opcode_metrics")] -pub use super::execute_measure::revm_measure::*; -#[cfg(feature = "enable_execution_duration_record")] -pub use super::execute_measure::{execute_txs::*, write_to_db::*}; +use tokio::sync::mpsc::UnboundedSender; /// Alias type for metric producers to use. pub type MetricEventsSender = UnboundedSender; @@ -63,25 +54,25 @@ pub enum MetricEvent { /// This structure is used to facilitate all metric operations in reth's performance test. #[derive(Default)] -pub struct PerfMetric { +struct PerfMetric { /// Record the time consumption of each function in execution stage. #[cfg(feature = "enable_execution_duration_record")] - pub(crate) duration_record: ExecutionDurationRecord, + duration_record: ExecutionDurationRecord, /// Record tps and gas. #[cfg(feature = "enable_tps_gas_record")] - pub(crate) tps_gas_record: TpsGasRecord, + tps_gas_record: TpsGasRecord, /// Record cache hits, number of accesses, and memory usage. #[cfg(feature = "enable_cache_record")] - pub(crate) cachedb_record: CacheDbRecord, + cachedb_record: CacheDbRecord, /// Record information on instruction execution. #[cfg(feature = "enable_opcode_metrics")] - pub(crate) op_record: OpcodeRecord, + op_record: OpcodeRecord, /// A channel for sending recorded indicator information to the dashboard for display. - pub(crate) events_tx: Option, + events_tx: Option, /// Used to record the current block_number. - pub(crate) block_number: u64, + block_number: u64, } static mut METRIC_RECORDER: Option = None; @@ -100,6 +91,410 @@ pub fn set_metric_event_sender(events_tx: MetricEventsSender) { } } -pub(crate) fn recorder<'a>() -> &'a mut PerfMetric { +fn recorder<'a>() -> &'a mut PerfMetric { unsafe { METRIC_RECORDER.as_mut().expect("Metric recorder should not empty!") } } + +// ************************************************************************************************* +// +// The functions in the following range should be called in the execute_inner function of execution +// stage. +// +// ************************************************************************************************* +pub fn start_record() { + #[cfg(feature = "enable_execution_duration_record")] + recorder().duration_record.start_total_record(); +} + +pub fn record_before_loop() { + #[cfg(feature = "enable_tps_gas_record")] + let _ = recorder().events_tx.as_mut().expect("No sender").send(MetricEvent::BlockTpsAndGas { + block_number: recorder().block_number, + record: TpsAndGasMessage::Switch(true), + }); +} + +pub fn record_before_td(block_number: u64) { + #[cfg(feature = "enable_execution_duration_record")] + recorder().duration_record.start_time_record(); + + recorder().block_number = block_number; +} + +pub fn record_after_td() { + #[cfg(feature = "enable_execution_duration_record")] + { + recorder().duration_record.add_block_td_duration(); + recorder().duration_record.start_time_record(); + } +} + +pub fn record_after_block_with_senders() { + #[cfg(feature = "enable_execution_duration_record")] + { + recorder().duration_record.add_block_with_senders_duration(); + recorder().duration_record.start_time_record(); + } +} + +pub fn record_after_get_tps(_block_number: u64, _txs: u64, _gas: u64) { + #[cfg(feature = "enable_tps_gas_record")] + { + recorder().tps_gas_record.record(_block_number, _txs as u128, _gas as u128); + let _ = + recorder().events_tx.as_mut().expect("No sender").send(MetricEvent::BlockTpsAndGas { + block_number: recorder().block_number, + record: TpsAndGasMessage::Record(recorder().tps_gas_record), + }); + } +} + +pub fn record_after_take_output_state() { + #[cfg(feature = "enable_tps_gas_record")] + let _ = recorder().events_tx.as_mut().expect("No sender").send(MetricEvent::BlockTpsAndGas { + block_number: recorder().block_number, + record: TpsAndGasMessage::Switch(false), + }); + + #[cfg(feature = "enable_execution_duration_record")] + recorder().duration_record.start_time_record(); +} + +pub fn record_at_end(_cachedb_size: usize) { + #[cfg(feature = "enable_execution_duration_record")] + { + recorder().duration_record.add_total_duration(); + let _ = recorder().events_tx.as_mut().expect("No sender").send( + MetricEvent::ExecutionStageTime { + block_number: recorder().block_number, + record: recorder().duration_record, + }, + ); + } + + #[cfg(feature = "enable_cache_record")] + { + let cachedb_record = revm_utils::metrics::get_cache_record(); + recorder().cachedb_record.update(&cachedb_record); + let _ = recorder().events_tx.as_mut().expect("No sender").send(MetricEvent::CacheDbInfo { + block_number: recorder().block_number, + size: _cachedb_size, + record: recorder().cachedb_record, + }); + } + + #[cfg(feature = "enable_opcode_metrics")] + let _ = recorder().events_tx.as_mut().expect("No sender").send(MetricEvent::OpcodeInfo { + block_number: recorder().block_number, + record: recorder().op_record, + }); +} +// ************************************************************************************************* +// functions called by execute_inner end +// ************************************************************************************************* + +// ************************************************************************************************* +// +// The functions in the following range should be called in executor. +// +// ************************************************************************************************* + +/// After each transaction is executed, the execution status of instructions is counted and then +/// updated to the global metric recorder. This function will be called in executor. +#[cfg(feature = "enable_opcode_metrics")] +pub fn record_opcode() { + let mut op_record = revm_utils::metrics::get_op_record(); + if op_record.not_empty() { + recorder().op_record.update(&mut op_record); + } +} + +/// start execute_tx record. +#[cfg(feature = "enable_execution_duration_record")] +pub fn start_execute_tx_record() { + recorder().duration_record.execution.start_record(); +} + +/// start execute_tx sub record. +#[cfg(feature = "enable_execution_duration_record")] +pub fn start_execute_tx_sub_record() { + recorder().duration_record.execution.start_sub_record(); +} + +/// transact record +#[cfg(feature = "enable_execution_duration_record")] +pub fn transact_record() { + recorder().duration_record.execution.transact_record(); +} + +/// commit_changes_record +#[cfg(feature = "enable_execution_duration_record")] +pub fn commit_changes_record() { + recorder().duration_record.execution.commit_changes_record(); +} + +/// add_receipt_record +#[cfg(feature = "enable_execution_duration_record")] +pub fn add_receipt_record() { + recorder().duration_record.execution.add_receipt_record(); +} + +/// apply_post_execution_state_change_record +#[cfg(feature = "enable_execution_duration_record")] +pub fn apply_post_execution_state_change_record() { + recorder().duration_record.execution.apply_post_execution_state_change_record(); +} + +/// merge_transactions_record +#[cfg(feature = "enable_execution_duration_record")] +pub fn merge_transactions_record() { + recorder().duration_record.execution.merge_transactions_record(); +} + +/// verify_receipt_record +#[cfg(feature = "enable_execution_duration_record")] +pub fn verify_receipt_record() { + recorder().duration_record.execution.verify_receipt_record(); +} + +/// save_receipts_record +#[cfg(feature = "enable_execution_duration_record")] +pub fn save_receipts_record() { + recorder().duration_record.execution.save_receipts_record(); +} + +/// get_execute_tx_record +#[cfg(feature = "enable_execution_duration_record")] +pub fn get_execute_tx_record() -> ExecuteTxsRecord { + recorder().duration_record.execution +} + +/// Record for verfity_and_save_receipts +#[cfg(feature = "enable_execution_duration_record")] +pub struct VerifyAndSaveReceiptsRecord; + +#[cfg(feature = "enable_execution_duration_record")] +impl VerifyAndSaveReceiptsRecord { + /// Return VerifyAndSaveReceiptsRecord + pub fn new() -> Self { + verify_receipt_record(); + VerifyAndSaveReceiptsRecord + } +} + +#[cfg(feature = "enable_execution_duration_record")] +impl Drop for VerifyAndSaveReceiptsRecord { + fn drop(&mut self) { + save_receipts_record(); + } +} +// ************************************************************************************************* +// functions called by executor end +// ************************************************************************************************* + +// ************************************************************************************************* +// +// The function within this range will be used to measure write_to_db and will be called in +// write_to_db. +// +// ************************************************************************************************* +/// start write_to_db record. +#[cfg(feature = "enable_execution_duration_record")] +pub fn start_write_to_db_record() { + recorder().duration_record.write_to_db.start_record(); +} + +/// start write_to_db sub record. +#[cfg(feature = "enable_execution_duration_record")] +pub fn start_write_to_db_sub_record() { + recorder().duration_record.write_to_db.start_sub_record(); +} + +/// start write_to_db write record. +#[cfg(feature = "enable_execution_duration_record")] +fn start_write_to_db_write_record() { + recorder().duration_record.write_to_db.start_write_record(); +} + +/// Record data size of write storage changes in StateReverts's write_to_db. +#[cfg(feature = "enable_execution_duration_record")] +fn record_revert_storage_size(size: usize) { + recorder().duration_record.write_to_db.record_revert_storage_size(size); +} + +/// Record time of write storage append time in StateReverts's write_to_db. +#[cfg(feature = "enable_execution_duration_record")] +fn record_revert_storage_append_time() { + recorder().duration_record.write_to_db.record_revert_storage_append_time(); +} + +// Encapsulate this structure to record write_storage in revert state in a RAII manner. +#[cfg(feature = "enable_execution_duration_record")] +impl_write_macro!( + RevertsStorageWrite, + start_write_to_db_write_record, + record_revert_storage_append_time, + record_revert_storage_size, + record_receipts_append_time, + record_write_receipts_size +); + +/// Record time of write storage changes in StateReverts's write_to_db. +#[cfg(feature = "enable_execution_duration_record")] +pub fn record_revert_storage_time() { + recorder().duration_record.write_to_db.record_revert_storage_time(); +} + +/// Record data size of write account changes in StateReverts's write_to_db. +#[cfg(feature = "enable_execution_duration_record")] +fn record_revert_account_size(size: usize) { + recorder().duration_record.write_to_db.record_revert_account_size(size); +} + +/// Record time of write account append time in StateReverts's write_to_db. +#[cfg(feature = "enable_execution_duration_record")] +fn record_revert_account_append_time() { + recorder().duration_record.write_to_db.record_revert_account_append_time(); +} + +// Encapsulate this structure to record write_account in revert state in a RAII manner. +#[cfg(feature = "enable_execution_duration_record")] +impl_write_macro!( + RevertsAccountWrite, + start_write_to_db_write_record, + record_revert_account_append_time, + record_revert_account_size, + record_receipts_append_time, + record_write_receipts_size +); + +/// Record time of write account changes in StateReverts's write_to_db. +#[cfg(feature = "enable_execution_duration_record")] +pub fn record_revert_account_time() { + recorder().duration_record.write_to_db.record_revert_account_time(); +} + +/// Record data size of write receipts in BundleStateWithReceipts's write_to_db. +#[cfg(feature = "enable_execution_duration_record")] +fn record_write_receipts_size(size: usize) { + recorder().duration_record.write_to_db.record_write_receipts_size(size); +} + +/// Record time of write receipts append in BundleStateWithReceipts's write_to_db. +#[cfg(feature = "enable_execution_duration_record")] +fn record_receipts_append_time() { + recorder().duration_record.write_to_db.record_receipts_append_time(); +} + +// Encapsulate this structure to record write receipts in a RAII manner. +#[cfg(feature = "enable_execution_duration_record")] +impl_write_macro!( + ReceiptsWrite, + start_write_to_db_write_record, + record_receipts_append_time, + record_write_receipts_size, + record_receipts_append_time, + record_write_receipts_size +); + +/// Record time of write receipts in BundleStateWithReceipts's write_to_db. +#[cfg(feature = "enable_execution_duration_record")] +pub fn record_write_receipts_time() { + recorder().duration_record.write_to_db.record_write_receipts_time(); +} + +/// Record time of sort in StateChanges's write_to_db. +#[cfg(feature = "enable_execution_duration_record")] +pub fn record_sort_time() { + recorder().duration_record.write_to_db.record_sort_time(); +} + +/// Record data size of write account in StateChanges's write_to_db. +#[cfg(feature = "enable_execution_duration_record")] +fn record_state_account_size(size: usize) { + recorder().duration_record.write_to_db.record_state_account_size(size); +} + +/// Record time of write account upsert in StateChanges's write_to_db. +#[cfg(feature = "enable_execution_duration_record")] +fn record_state_account_upsert_time() { + recorder().duration_record.write_to_db.record_state_account_upsert_time(); +} + +// Encapsulate this structure to record write_account in state changes in a RAII manner. +#[cfg(feature = "enable_execution_duration_record")] +impl_write_macro!( + StateAccountWrite, + start_write_to_db_write_record, + record_state_account_upsert_time, + record_state_account_size, + record_receipts_append_time, + record_write_receipts_size +); + +/// Record time of write account in StateChanges's write_to_db. +#[cfg(feature = "enable_execution_duration_record")] +pub fn record_state_account_time() { + recorder().duration_record.write_to_db.record_state_account_time(); +} + +/// Record data size of write bytecode in StateChanges's write_to_db. +#[cfg(feature = "enable_execution_duration_record")] +fn record_state_bytecode_size(size: usize) { + recorder().duration_record.write_to_db.record_state_bytecode_size(size); +} + +/// Record time of write bytecode upsert in StateChanges's write_to_db. +#[cfg(feature = "enable_execution_duration_record")] +fn record_state_bytecode_upsert_time() { + recorder().duration_record.write_to_db.record_state_bytecode_upsert_time(); +} + +// Encapsulate this structure to record write_bytecode in state changes in a RAII manner. +#[cfg(feature = "enable_execution_duration_record")] +impl_write_macro!( + StateBytecodeWrite, + start_write_to_db_write_record, + record_state_bytecode_upsert_time, + record_state_bytecode_size, + record_receipts_append_time, + record_write_receipts_size +); + +/// Record time of write bytecode in StateChanges's write_to_db. +#[cfg(feature = "enable_execution_duration_record")] +pub fn record_state_bytecode_time() { + recorder().duration_record.write_to_db.record_state_bytecode_time(); +} + +/// Record data size of write storage in StateChanges's write_to_db. +#[cfg(feature = "enable_execution_duration_record")] +fn record_state_storage_size(size: usize) { + recorder().duration_record.write_to_db.record_state_storage_size(size); +} + +/// Record time of write storage upsert in StateChanges's write_to_db. +#[cfg(feature = "enable_execution_duration_record")] +fn record_state_storage_upsert_time() { + recorder().duration_record.write_to_db.record_state_storage_upsert_time(); +} + +// Encapsulate this structure to record write_storage in state changes in a RAII manner. +#[cfg(feature = "enable_execution_duration_record")] +impl_write_macro!( + StateStorageWrite, + start_write_to_db_write_record, + record_state_storage_upsert_time, + record_state_storage_size, + record_receipts_append_time, + record_write_receipts_size +); + +/// Record time of write storage in StateChanges's write_to_db. +#[cfg(feature = "enable_execution_duration_record")] +pub fn record_state_storage_time() { + recorder().duration_record.write_to_db.record_state_storage_time(); +} +// ************************************************************************************************* +// functions called by write_to_db end +// ************************************************************************************************* diff --git a/crates/perf-metrics/src/metrics/mod.rs b/crates/perf-metrics/src/metrics/mod.rs index 1320860d0b093..adec4f5e81173 100644 --- a/crates/perf-metrics/src/metrics/mod.rs +++ b/crates/perf-metrics/src/metrics/mod.rs @@ -2,14 +2,13 @@ mod macros; #[cfg(feature = "enable_execution_duration_record")] mod duration; -mod execute_measure; #[cfg(feature = "enable_tps_gas_record")] mod tps_gas; pub mod metric; #[cfg(feature = "enable_execution_duration_record")] -pub(crate) use duration::{ExecuteTxsRecord, ExecutionDurationRecord, WriteToDbRecord}; +pub use duration::{ExecuteTxsRecord, ExecutionDurationRecord, WriteToDbRecord}; #[cfg(feature = "enable_tps_gas_record")] pub use tps_gas::{TpsAndGasMessage, TpsGasRecord}; diff --git a/crates/perf-metrics/src/metrics/tps_gas.rs b/crates/perf-metrics/src/metrics/tps_gas.rs index 90d169e448716..e47fe0699d564 100644 --- a/crates/perf-metrics/src/metrics/tps_gas.rs +++ b/crates/perf-metrics/src/metrics/tps_gas.rs @@ -2,9 +2,9 @@ //! and total gas consumed so far. #[derive(Debug, Default, Copy, Clone)] pub struct TpsGasRecord { - pub(crate) block_number: u64, - pub(crate) txs: u128, - pub(crate) gas: u128, + pub block_number: u64, + pub txs: u128, + pub gas: u128, } impl TpsGasRecord { diff --git a/crates/storage/libmdbx-rs/Cargo.toml b/crates/storage/libmdbx-rs/Cargo.toml index e06eb089acc05..7ade3ae51a769 100644 --- a/crates/storage/libmdbx-rs/Cargo.toml +++ b/crates/storage/libmdbx-rs/Cargo.toml @@ -26,6 +26,7 @@ dashmap = { version = "5.5.3", features = ["inline"], optional = true } tracing = { workspace = true, optional = true } ffi = { package = "reth-mdbx-sys", path = "./mdbx-sys" } +perf-metrics = { workspace = true, optional = true } [target.'cfg(not(windows))'.dependencies] libffi = "3.2.0"