From 746321ae9f231c108b9aa0bcde669b35cd46b24a Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Tue, 20 Feb 2024 14:46:22 +0100 Subject: [PATCH] fix: include base fee per gas for next block (#7188) --- crates/anvil/src/eth/api.rs | 53 ++++++++++++++++++++---------------- crates/anvil/src/eth/fees.rs | 17 ++++++------ crates/anvil/src/lib.rs | 6 ++++ 3 files changed, 44 insertions(+), 32 deletions(-) diff --git a/crates/anvil/src/eth/api.rs b/crates/anvil/src/eth/api.rs index b7ed87e3c4f1..93d705f0bbf2 100644 --- a/crates/anvil/src/eth/api.rs +++ b/crates/anvil/src/eth/api.rs @@ -1304,8 +1304,6 @@ impl EthApi { return Err(FeeHistoryError::InvalidBlockRange.into()); } - let fee_history = self.fee_history_cache.lock(); - let mut response = FeeHistory { oldest_block: U256::from(lowest), base_fee_per_gas: Vec::new(), @@ -1314,30 +1312,34 @@ impl EthApi { base_fee_per_blob_gas: Default::default(), blob_gas_used_ratio: Default::default(), }; - let mut rewards = Vec::new(); - // iter over the requested block range - for n in lowest..=highest { - // - if let Some(block) = fee_history.get(&n) { - response.base_fee_per_gas.push(U256::from(block.base_fee)); - response.gas_used_ratio.push(block.gas_used_ratio); - - // requested percentiles - if !reward_percentiles.is_empty() { - let mut block_rewards = Vec::new(); - let resolution_per_percentile: f64 = 2.0; - for p in &reward_percentiles { - let p = p.clamp(0.0, 100.0); - let index = ((p.round() / 2f64) * 2f64) * resolution_per_percentile; - let reward = if let Some(r) = block.rewards.get(index as usize) { - U256::from(*r) - } else { - U256::ZERO - }; - block_rewards.push(reward); + + { + let fee_history = self.fee_history_cache.lock(); + + // iter over the requested block range + for n in lowest..=highest { + // + if let Some(block) = fee_history.get(&n) { + response.base_fee_per_gas.push(U256::from(block.base_fee)); + response.gas_used_ratio.push(block.gas_used_ratio); + + // requested percentiles + if !reward_percentiles.is_empty() { + let mut block_rewards = Vec::new(); + let resolution_per_percentile: f64 = 2.0; + for p in &reward_percentiles { + let p = p.clamp(0.0, 100.0); + let index = ((p.round() / 2f64) * 2f64) * resolution_per_percentile; + let reward = if let Some(r) = block.rewards.get(index as usize) { + U256::from(*r) + } else { + U256::ZERO + }; + block_rewards.push(reward); + } + rewards.push(block_rewards); } - rewards.push(block_rewards); } } } @@ -1345,6 +1347,9 @@ impl EthApi { response.reward = Some(rewards); // calculate next base fee + // The spec states that `base_fee_per_gas` "[..] includes the next block after the + // newest of the returned range, because this value can be derived from the + // newest block" if let (Some(last_gas_used), Some(last_fee_per_gas)) = (response.gas_used_ratio.last(), response.base_fee_per_gas.last()) { diff --git a/crates/anvil/src/eth/fees.rs b/crates/anvil/src/eth/fees.rs index d71f8463c4ca..4f341858b5e3 100644 --- a/crates/anvil/src/eth/fees.rs +++ b/crates/anvil/src/eth/fees.rs @@ -198,12 +198,15 @@ impl FeeHistoryService { self.fee_history_limit } + /// Inserts a new cache entry for the given block + pub(crate) fn insert_cache_entry_for_block(&self, hash: B256) { + let (result, block_number) = self.create_cache_entry(hash); + self.insert_cache_entry(result, block_number); + } + /// Create a new history entry for the block - fn create_cache_entry( - &self, - hash: B256, - elasticity: f64, - ) -> (FeeHistoryCacheItem, Option) { + fn create_cache_entry(&self, hash: B256) -> (FeeHistoryCacheItem, Option) { + let elasticity = self.fees.elasticity(); // percentile list from 0.0 to 100.0 with a 0.5 resolution. // this will create 200 percentile points let reward_percentiles: Vec = { @@ -315,11 +318,9 @@ impl Future for FeeHistoryService { while let Poll::Ready(Some(notification)) = pin.new_blocks.poll_next_unpin(cx) { let hash = notification.hash; - let elasticity = default_elasticity(); // add the imported block. - let (result, block_number) = pin.create_cache_entry(hash, elasticity); - pin.insert_cache_entry(result, block_number) + pin.insert_cache_entry_for_block(hash); } Poll::Pending diff --git a/crates/anvil/src/lib.rs b/crates/anvil/src/lib.rs index d2503410f0e6..23a328d7a8b9 100644 --- a/crates/anvil/src/lib.rs +++ b/crates/anvil/src/lib.rs @@ -145,6 +145,12 @@ pub async fn spawn(mut config: NodeConfig) -> (EthApi, NodeHandle) { fees, StorageInfo::new(Arc::clone(&backend)), ); + // create an entry for the best block + if let Some(best_block) = + backend.get_block(backend.best_number()).map(|block| block.header.hash_slow()) + { + fee_history_service.insert_cache_entry_for_block(best_block); + } let filters = Filters::default();