Skip to content

Commit

Permalink
feat(blockifier): add cairo native cache rate metric
Browse files Browse the repository at this point in the history
  • Loading branch information
AvivYossef-starkware committed Feb 26, 2025
1 parent 2f2f2b2 commit f8ad409
Show file tree
Hide file tree
Showing 11 changed files with 105 additions and 4 deletions.
2 changes: 2 additions & 0 deletions Cargo.lock

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

6 changes: 6 additions & 0 deletions crates/blockifier/src/state/contract_class_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ pub use crate::state::native_class_manager::NativeClassManager as ContractClassM
pub mod trivial_class_manager {
#[cfg(any(feature = "testing", test))]
use cached::Cached;
use num_rational::Ratio;
use starknet_api::core::ClassHash;

use crate::blockifier::config::ContractClassManagerConfig;
Expand Down Expand Up @@ -44,6 +45,11 @@ pub mod trivial_class_manager {
pub fn get_cache_size(&self) -> usize {
self.cache.lock().cache_size()
}

pub fn get_cache_miss_rate(&self) -> Ratio<usize> {
// TODO(Aviv): consider support cache miss metrics.
Ratio::ZERO
}
}
}

Expand Down
60 changes: 58 additions & 2 deletions crates/blockifier/src/state/native_class_manager.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::mpsc::{sync_channel, Receiver, SyncSender, TrySendError};
use std::sync::Arc;

#[cfg(any(feature = "testing", test))]
use cached::Cached;
use log;
use num_rational::Ratio;
use starknet_api::core::ClassHash;
use starknet_api::state::SierraContractClass;
use starknet_sierra_multicompile::command_line_compiler::CommandLineCompiler;
Expand Down Expand Up @@ -49,6 +51,39 @@ pub struct NativeClassManager {
sender: Option<SyncSender<CompilationRequest>>,
/// The sierra-to-native compiler.
compiler: Option<Arc<dyn SierraToNativeCompiler>>,
/// cache_miss_rate
cache_metrics: CacheMetrics,
}

#[derive(Default, Clone)]

pub struct CacheMetrics {
cache_misses: Arc<AtomicUsize>,
total_cache_calls: Arc<AtomicUsize>,
}

impl CacheMetrics {
pub fn new() -> Self {
Self {
cache_misses: Arc::new(AtomicUsize::new(0)),
total_cache_calls: Arc::new(AtomicUsize::new(0)),
}
}

pub fn record_miss(&self) {
self.cache_misses.fetch_add(1, Ordering::Relaxed);
self.total_cache_calls.fetch_add(1, Ordering::Relaxed);
}

pub fn record_hit(&self) {
self.total_cache_calls.fetch_add(1, Ordering::Relaxed);
}

pub fn miss_rate(&self) -> Ratio<usize> {
let misses = self.cache_misses.load(Ordering::Relaxed);
let total = self.total_cache_calls.load(Ordering::Relaxed);
if total == 0 { Ratio::ZERO } else { Ratio::new(misses, total) }
}
}

impl NativeClassManager {
Expand All @@ -70,6 +105,7 @@ impl NativeClassManager {
cache,
sender: None,
compiler: None,
cache_metrics: CacheMetrics::new(),
};
}

Expand All @@ -82,6 +118,7 @@ impl NativeClassManager {
cache,
sender: None,
compiler: Some(compiler),
cache_metrics: CacheMetrics::new(),
};
}

Expand All @@ -92,12 +129,27 @@ impl NativeClassManager {
move || run_compilation_worker(cache, receiver, compiler)
});

NativeClassManager { cairo_native_run_config, cache, sender: Some(sender), compiler: None }
NativeClassManager {
cairo_native_run_config,
cache,
sender: Some(sender),
compiler: None,
cache_metrics: CacheMetrics::new(),
}
}

/// Returns the runnable compiled class for the given class hash, if it exists in cache.
pub fn get_runnable(&self, class_hash: &ClassHash) -> Option<RunnableCompiledClass> {
let cached_class = self.cache.get(class_hash)?;
let cached_class = match self.cache.get(class_hash) {
Some(class) => {
self.cache_metrics.record_hit();
class
}
None => {
self.cache_metrics.record_miss();
return None;
}
};
if let CachedClass::V1(_, _) = cached_class {
// TODO(Yoni): make sure `wait_on_native_compilation` cannot be set to true while
// `run_cairo_native` is false.
Expand Down Expand Up @@ -195,6 +247,10 @@ impl NativeClassManager {
pub fn get_cache_size(&self) -> usize {
self.cache.lock().cache_size()
}

pub fn get_cache_miss_rate(&self) -> Ratio<usize> {
self.cache_metrics.miss_rate()
}
}

/// Handles compilation requests from the channel, holding the receiver end of the channel.
Expand Down
2 changes: 2 additions & 0 deletions crates/blockifier/src/state/native_class_manager_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ use crate::state::global_cache::{
};
use crate::state::native_class_manager::{
process_compilation_request,
CacheMetrics,
CompilationRequest,
ContractClassManagerError,
NativeClassManager,
Expand Down Expand Up @@ -157,6 +158,7 @@ fn test_send_compilation_request_channel_disconnected() {
cache: RawClassCache::new(GLOBAL_CONTRACT_CACHE_SIZE_FOR_TEST),
sender: Some(sender),
compiler: None,
cache_metrics: CacheMetrics::new(),
};
// Disconnect the channel by dropping the receiver.
drop(receiver);
Expand Down
2 changes: 2 additions & 0 deletions crates/starknet_batcher/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ async-trait.workspace = true
blockifier.workspace = true
chrono.workspace = true
indexmap.workspace = true
num-rational.workspace = true
num-traits.workspace = true
papyrus_config.workspace = true
papyrus_state_reader.workspace = true
papyrus_storage.workspace = true
Expand Down
8 changes: 8 additions & 0 deletions crates/starknet_batcher/src/batcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use async_trait::async_trait;
use blockifier::state::contract_class_manager::ContractClassManager;
#[cfg(test)]
use mockall::automock;
use num_traits::cast::ToPrimitive;
use papyrus_storage::state::{StateStorageReader, StateStorageWriter};
use starknet_api::block::{BlockHeaderWithoutHash, BlockNumber};
use starknet_api::consensus_transaction::InternalConsensusTransaction;
Expand Down Expand Up @@ -44,6 +45,7 @@ use starknet_sequencer_infra::component_definitions::{
};
use starknet_sequencer_metrics::metric_definitions::{
BATCHED_TRANSACTIONS,
CAIRO_NATIVE_CACHE_MISS_RATIO,
REJECTED_TRANSACTIONS,
STORAGE_HEIGHT,
};
Expand Down Expand Up @@ -489,6 +491,12 @@ impl Batcher {
let execution_infos: Vec<_> =
block_execution_artifacts.execution_infos.into_iter().map(|(_, info)| info).collect();

CAIRO_NATIVE_CACHE_MISS_RATIO.set(
self.block_builder_factory
.get_contract_class_manager_cache_miss_rate()
.to_f64()
.unwrap_or(0.0),
);
BATCHED_TRANSACTIONS.increment(n_txs);
REJECTED_TRANSACTIONS.increment(n_rejected_txs);

Expand Down
7 changes: 6 additions & 1 deletion crates/starknet_batcher/src/batcher_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use blockifier::transaction::objects::TransactionExecutionInfo;
use indexmap::indexmap;
use metrics_exporter_prometheus::PrometheusBuilder;
use mockall::predicate::eq;
use num_rational::Ratio;
use rstest::rstest;
use starknet_api::block::{BlockHeaderWithoutHash, BlockInfo, BlockNumber};
use starknet_api::consensus_transaction::InternalConsensusTransaction;
Expand Down Expand Up @@ -117,12 +118,16 @@ impl Default for MockDependencies {
let expected_gas_price =
propose_block_input(PROPOSAL_ID).block_info.gas_prices.strk_gas_prices.l2_gas_price;
mempool_client.expect_update_gas_price().with(eq(expected_gas_price)).returning(|_| Ok(()));
let mut block_builder_factory = MockBlockBuilderFactoryTrait::new();
block_builder_factory
.expect_get_contract_class_manager_cache_miss_rate()
.return_const(Ratio::new(1, 2));
Self {
storage_reader,
storage_writer: MockBatcherStorageWriterTrait::new(),
l1_provider_client: MockL1ProviderClient::new(),
mempool_client,
block_builder_factory: MockBlockBuilderFactoryTrait::new(),
block_builder_factory,
// TODO(noamsp): use MockClassManagerClient
class_manager_client: Arc::new(EmptyClassManagerClient),
}
Expand Down
7 changes: 7 additions & 0 deletions crates/starknet_batcher/src/block_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use blockifier::transaction::transaction_execution::Transaction as BlockifierTra
use indexmap::{IndexMap, IndexSet};
#[cfg(test)]
use mockall::automock;
use num_rational::Ratio;
use papyrus_config::dumping::{append_sub_config_name, ser_param, SerializeConfig};
use papyrus_config::{ParamPath, ParamPrivacyInput, SerializedParam};
use papyrus_state_reader::papyrus_state::{ClassReader, PapyrusReader};
Expand Down Expand Up @@ -349,6 +350,8 @@ pub trait BlockBuilderFactoryTrait: Send + Sync {
>,
runtime: tokio::runtime::Handle,
) -> BlockBuilderResult<(Box<dyn BlockBuilderTrait>, AbortSignalSender)>;

fn get_contract_class_manager_cache_miss_rate(&self) -> Ratio<usize>;
}

#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
Expand Down Expand Up @@ -466,6 +469,10 @@ impl BlockBuilderFactoryTrait for BlockBuilderFactory {
));
Ok((block_builder, abort_signal_sender))
}

fn get_contract_class_manager_cache_miss_rate(&self) -> Ratio<usize> {
self.contract_class_manager.get_cache_miss_rate()
}
}

/// Supplementary information for use by downstream services.
Expand Down
4 changes: 4 additions & 0 deletions crates/starknet_batcher/src/metrics.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use starknet_api::block::BlockNumber;
use starknet_sequencer_metrics::metric_definitions::{
BATCHED_TRANSACTIONS,
CAIRO_NATIVE_CACHE_MISS_RATIO,
PROPOSAL_ABORTED,
PROPOSAL_FAILED,
PROPOSAL_STARTED,
Expand All @@ -14,6 +15,9 @@ pub fn register_metrics(storage_height: BlockNumber) {
#[allow(clippy::as_conversions)]
STORAGE_HEIGHT.set(storage_height.0 as f64);

CAIRO_NATIVE_CACHE_MISS_RATIO.register();
CAIRO_NATIVE_CACHE_MISS_RATIO.set(0.0);

PROPOSAL_STARTED.register();
PROPOSAL_SUCCEEDED.register();
PROPOSAL_FAILED.register();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,13 @@ const PANEL_BATCHED_TRANSACTIONS: Panel = Panel::new(
PanelType::Stat,
);

const PANEL_CAIRO_NATIVE_CACHE_MISS_RATIO: Panel = Panel::new(
"cairo_native_cache_miss_ratio",
"The ratio of cache misses in the Cairo native cache",
"cairo_native_cache_miss_ratio",
PanelType::Graph,
);

const PANEL_MEMPOOL_P2P_NUM_CONNECTED_PEERS: Panel = Panel::new(
MEMPOOL_P2P_NUM_CONNECTED_PEERS.get_name(),
MEMPOOL_P2P_NUM_CONNECTED_PEERS.get_description(),
Expand Down Expand Up @@ -155,6 +162,7 @@ const BATCHER_ROW: Row<'_> = Row::new(
PANEL_PROPOSAL_SUCCEEDED,
PANEL_PROPOSAL_FAILED,
PANEL_BATCHED_TRANSACTIONS,
PANEL_CAIRO_NATIVE_CACHE_MISS_RATIO,
],
);
const HTTP_SERVER_ROW: Row<'_> = Row::new(
Expand Down
3 changes: 2 additions & 1 deletion crates/starknet_sequencer_metrics/src/metric_definitions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,8 @@ macro_rules! define_gauge_metrics {

define_gauge_metrics!(
MetricScope::Batcher => {
{ STORAGE_HEIGHT, "batcher_storage_height", "The height of the batcher's storage" }
{ STORAGE_HEIGHT, "batcher_storage_height", "The height of the batcher's storage" },
{ CAIRO_NATIVE_CACHE_MISS_RATIO, "cairo_native_cache_miss_ratio","The cache miss of cairo native"}
},
MetricScope::Infra => {
{ BATCHER_LOCAL_QUEUE_DEPTH, "batcher_local_queue_depth", "The depth of the batcher's local message queue" },
Expand Down

0 comments on commit f8ad409

Please sign in to comment.