mirror of
https://github.com/paradigmxyz/reth.git
synced 2026-01-26 15:48:13 -05:00
perf: Reuse CachedPrecompileMetrics across block executions (#16944)
This commit is contained in:
@@ -18,7 +18,7 @@ use error::{InsertBlockError, InsertBlockErrorKind, InsertBlockFatalError};
|
||||
use instrumented_state::InstrumentedStateProvider;
|
||||
use payload_processor::sparse_trie::StateRootComputeOutcome;
|
||||
use persistence_state::CurrentPersistenceAction;
|
||||
use precompile_cache::{CachedPrecompile, PrecompileCacheMap};
|
||||
use precompile_cache::{CachedPrecompile, CachedPrecompileMetrics, PrecompileCacheMap};
|
||||
use reth_chain_state::{
|
||||
CanonicalInMemoryState, ExecutedBlock, ExecutedBlockWithTrieUpdates, ExecutedTrieUpdates,
|
||||
MemoryOverlayStateProvider, NewCanonicalChain,
|
||||
@@ -276,6 +276,9 @@ where
|
||||
evm_config: C,
|
||||
/// Precompile cache map.
|
||||
precompile_cache_map: PrecompileCacheMap<SpecFor<C>>,
|
||||
/// Metrics for precompile cache, saved between block executions so we don't re-allocate for
|
||||
/// every block.
|
||||
precompile_cache_metrics: CachedPrecompileMetrics,
|
||||
}
|
||||
|
||||
impl<N, P: Debug, T: PayloadTypes + Debug, V: Debug, C> std::fmt::Debug
|
||||
@@ -370,6 +373,7 @@ where
|
||||
payload_processor,
|
||||
evm_config,
|
||||
precompile_cache_map,
|
||||
precompile_cache_metrics: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2443,6 +2447,7 @@ where
|
||||
precompile,
|
||||
self.precompile_cache_map.cache_for_address(*address),
|
||||
*self.evm_config.evm_env(block.header()).spec_id(),
|
||||
Some(self.precompile_cache_metrics.clone()),
|
||||
)
|
||||
});
|
||||
}
|
||||
|
||||
@@ -275,6 +275,7 @@ where
|
||||
precompile,
|
||||
precompile_cache_map.cache_for_address(*address),
|
||||
spec_id,
|
||||
None, // CachedPrecompileMetrics
|
||||
)
|
||||
});
|
||||
}
|
||||
|
||||
@@ -123,7 +123,7 @@ where
|
||||
/// The precompile.
|
||||
precompile: DynPrecompile,
|
||||
/// Cache metrics.
|
||||
metrics: CachedPrecompileMetrics,
|
||||
metrics: Option<CachedPrecompileMetrics>,
|
||||
/// Spec id associated to the EVM from which this cached precompile was created.
|
||||
spec_id: S,
|
||||
}
|
||||
@@ -133,30 +133,48 @@ where
|
||||
S: Eq + Hash + std::fmt::Debug + Send + Sync + Clone + 'static,
|
||||
{
|
||||
/// `CachedPrecompile` constructor.
|
||||
pub(crate) fn new(precompile: DynPrecompile, cache: PrecompileCache<S>, spec_id: S) -> Self {
|
||||
Self { precompile, cache, spec_id, metrics: Default::default() }
|
||||
pub(crate) const fn new(
|
||||
precompile: DynPrecompile,
|
||||
cache: PrecompileCache<S>,
|
||||
spec_id: S,
|
||||
metrics: Option<CachedPrecompileMetrics>,
|
||||
) -> Self {
|
||||
Self { precompile, cache, spec_id, metrics }
|
||||
}
|
||||
|
||||
pub(crate) fn wrap(
|
||||
precompile: DynPrecompile,
|
||||
cache: PrecompileCache<S>,
|
||||
spec_id: S,
|
||||
metrics: Option<CachedPrecompileMetrics>,
|
||||
) -> DynPrecompile {
|
||||
let wrapped = Self::new(precompile, cache, spec_id);
|
||||
let wrapped = Self::new(precompile, cache, spec_id, metrics);
|
||||
move |data: &[u8], gas_limit: u64| -> PrecompileResult { wrapped.call(data, gas_limit) }
|
||||
.into()
|
||||
}
|
||||
|
||||
fn increment_by_one_precompile_cache_hits(&self) {
|
||||
self.metrics.precompile_cache_hits.increment(1);
|
||||
if let Some(metrics) = &self.metrics {
|
||||
metrics.precompile_cache_hits.increment(1);
|
||||
}
|
||||
}
|
||||
|
||||
fn increment_by_one_precompile_cache_misses(&self) {
|
||||
self.metrics.precompile_cache_misses.increment(1);
|
||||
if let Some(metrics) = &self.metrics {
|
||||
metrics.precompile_cache_misses.increment(1);
|
||||
}
|
||||
}
|
||||
|
||||
fn set_precompile_cache_size_metric(&self, to: f64) {
|
||||
if let Some(metrics) = &self.metrics {
|
||||
metrics.precompile_cache_size.set(to);
|
||||
}
|
||||
}
|
||||
|
||||
fn increment_by_one_precompile_errors(&self) {
|
||||
self.metrics.precompile_errors.increment(1);
|
||||
if let Some(metrics) = &self.metrics {
|
||||
metrics.precompile_errors.increment(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -180,7 +198,7 @@ where
|
||||
Ok(output) => {
|
||||
let key = CacheKey::new(self.spec_id.clone(), Bytes::copy_from_slice(data));
|
||||
let size = self.cache.insert(key, CacheEntry(output.clone()));
|
||||
self.metrics.precompile_cache_size.set(size as f64);
|
||||
self.set_precompile_cache_size_metric(size as f64);
|
||||
self.increment_by_one_precompile_cache_misses();
|
||||
}
|
||||
_ => {
|
||||
@@ -241,7 +259,7 @@ mod tests {
|
||||
.into();
|
||||
|
||||
let cache =
|
||||
CachedPrecompile::new(dyn_precompile, PrecompileCache::default(), SpecId::PRAGUE);
|
||||
CachedPrecompile::new(dyn_precompile, PrecompileCache::default(), SpecId::PRAGUE, None);
|
||||
|
||||
let output = PrecompileOutput {
|
||||
gas_used: 50,
|
||||
@@ -298,11 +316,13 @@ mod tests {
|
||||
precompile1,
|
||||
cache_map.cache_for_address(address1),
|
||||
SpecId::PRAGUE,
|
||||
None,
|
||||
);
|
||||
let wrapped_precompile2 = CachedPrecompile::wrap(
|
||||
precompile2,
|
||||
cache_map.cache_for_address(address2),
|
||||
SpecId::PRAGUE,
|
||||
None,
|
||||
);
|
||||
|
||||
// first invocation of precompile1 (cache miss)
|
||||
|
||||
Reference in New Issue
Block a user