Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: include base fee per gas for next block #7188

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 29 additions & 24 deletions crates/anvil/src/eth/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
Expand All @@ -1314,37 +1312,44 @@ 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 {
// <https://eips.ethereum.org/EIPS/eip-1559>
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 {
// <https://eips.ethereum.org/EIPS/eip-1559>
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);
}
}
}

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())
{
Expand Down
17 changes: 9 additions & 8 deletions crates/anvil/src/eth/fees.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<u64>) {
fn create_cache_entry(&self, hash: B256) -> (FeeHistoryCacheItem, Option<u64>) {
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<f64> = {
Expand Down Expand Up @@ -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
Expand Down
6 changes: 6 additions & 0 deletions crates/anvil/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down
Loading