Skip to content

Commit

Permalink
prepare type to store fee data
Browse files Browse the repository at this point in the history
  • Loading branch information
allnil committed Nov 4, 2023
1 parent 0cde2a1 commit 912fd0f
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 28 deletions.
3 changes: 2 additions & 1 deletion crates/rpc/rpc-builder/src/auth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ use reth_provider::{
};
use reth_rpc::{
eth::{
cache::EthStateCache, gas_oracle::GasPriceOracle, FeeHistoryCache, FeeHistoryCacheConfig,
cache::EthStateCache, gas_oracle::GasPriceOracle, EthFilterConfig, FeeHistoryCache,
FeeHistoryCacheConfig,
},
AuthLayer, BlockingTaskPool, Claims, EngineEthApi, EthApi, EthFilter,
EthSubscriptionIdProvider, JwtAuthValidator, JwtSecret,
Expand Down
46 changes: 26 additions & 20 deletions crates/rpc/rpc/src/eth/api/fees.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ use crate::{
};

use reth_network_api::NetworkInfo;
use reth_primitives::{
basefee::calculate_next_block_base_fee, BlockNumberOrTag, SealedHeader, U256,
};
use reth_primitives::{basefee::calculate_next_block_base_fee, BlockNumberOrTag, U256};
use reth_provider::{BlockReaderIdExt, ChainSpecProvider, EvmEnvProvider, StateProviderFactory};
use reth_rpc_types::{FeeHistory, TxGasAndReward};
use reth_transaction_pool::TransactionPool;
use tracing::debug;

use super::FeeHistoryEntry;

impl<Provider, Pool, Network> EthApi<Provider, Pool, Network>
where
Pool: TransactionPool + Clone + 'static,
Expand Down Expand Up @@ -94,25 +94,29 @@ where

let start_block = end_block_plus - block_count;

let mut headers = self.fee_history_cache().get_history(start_block, end_block).await?;
if headers.is_empty() {
headers = self.provider().sealed_headers_range(start_block..=end_block)?;
let mut fee_entries = self.fee_history_cache().get_history(start_block, end_block).await?;
if fee_entries.is_empty() {
fee_entries = self
.provider()
.sealed_headers_range(start_block..=end_block)?
.into_iter()
.map(|header| FeeHistoryEntry::from(&header))
.collect();
}

if headers.len() != block_count as usize {
if fee_entries.len() != block_count as usize {
return Err(EthApiError::InvalidBlockRange)
}
// Collect base fees, gas usage ratios and (optionally) reward percentile data
let mut base_fee_per_gas: Vec<U256> = Vec::new();
let mut gas_used_ratio: Vec<f64> = Vec::new();
let mut rewards: Vec<Vec<U256>> = Vec::new();

for header in &headers {
base_fee_per_gas
.push(U256::try_from(header.base_fee_per_gas.unwrap_or_default()).unwrap());
gas_used_ratio.push(header.gas_used as f64 / header.gas_limit as f64);
for entry in &fee_entries {
base_fee_per_gas.push(U256::try_from(entry.base_fee_per_gas).unwrap());
gas_used_ratio.push(entry.gas_used_ratio);
if let Some(percentiles) = &reward_percentiles {
rewards.push(self.calculate_reward_percentiles(percentiles, header).await?);
rewards.push(self.calculate_reward_percentiles(percentiles, entry).await?);
}
}

Expand All @@ -121,14 +125,14 @@ where
//
// The unwrap is safe since we checked earlier that we got at least 1 header.

let last_header = headers.last().unwrap();
let last_entry = fee_entries.last().unwrap();

let chain_spec = self.provider().chain_spec();

base_fee_per_gas.push(U256::from(calculate_next_block_base_fee(
last_header.gas_used,
last_header.gas_limit,
last_header.base_fee_per_gas.unwrap_or_default(),
last_entry.gas_used,
last_entry.gas_limit,
last_entry.base_fee_per_gas,
chain_spec.base_fee_params,
)));

Expand All @@ -148,11 +152,11 @@ where
async fn calculate_reward_percentiles(
&self,
percentiles: &[f64],
header: &SealedHeader,
fee_entry: &FeeHistoryEntry,
) -> Result<Vec<U256>, EthApiError> {
let (transactions, receipts) = self
.cache()
.get_transactions_and_receipts(header.hash)
.get_transactions_and_receipts(fee_entry.header_hash)
.await?
.ok_or(EthApiError::InvalidBlockRange)?;

Expand All @@ -171,7 +175,9 @@ where

Some(TxGasAndReward {
gas_used,
reward: tx.effective_tip_per_gas(header.base_fee_per_gas).unwrap_or_default(),
reward: tx
.effective_tip_per_gas(Some(fee_entry.base_fee_per_gas))
.unwrap_or_default(),
})
})
.collect::<Vec<_>>();
Expand All @@ -194,7 +200,7 @@ where
continue
}

let threshold = (header.gas_used as f64 * percentile / 100.) as u64;
let threshold = (fee_entry.gas_used as f64 * percentile / 100.) as u64;
while cumulative_gas_used < threshold && tx_index < transactions.len() - 1 {
tx_index += 1;
cumulative_gas_used += transactions[tx_index].gas_used;
Expand Down
35 changes: 28 additions & 7 deletions crates/rpc/rpc/src/eth/api/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -479,7 +479,7 @@ pub struct FeeHistoryCache {
lower_bound: Arc<AtomicU64>,
upper_bound: Arc<AtomicU64>,
config: FeeHistoryCacheConfig,
entries: Arc<tokio::sync::RwLock<BTreeMap<u64, SealedHeader>>>,
entries: Arc<tokio::sync::RwLock<BTreeMap<u64, FeeHistoryEntry>>>,
}

impl FeeHistoryCache {
Expand All @@ -502,7 +502,7 @@ impl FeeHistoryCache {
{
let mut entries = self.entries.write().await;
for header in headers {
entries.insert(header.number, header.clone());
entries.insert(header.number, FeeHistoryEntry::from(header));
}
while entries.len() > self.config.max_blocks as usize {
entries.pop_first();
Expand Down Expand Up @@ -534,20 +534,20 @@ impl FeeHistoryCache {
&self,
start_block: u64,
end_block: u64,
) -> RethResult<Vec<SealedHeader>> {
let mut headers = Vec::new();
) -> RethResult<Vec<FeeHistoryEntry>> {
let mut result = Vec::new();

let lower_bound = self.lower_bound();
let upper_bound = self.upper_bound();
if start_block >= lower_bound && end_block <= upper_bound {
let entries = self.entries.read().await;
headers = entries
result = entries
.range(start_block..=end_block + 1)
.map(|(_, header)| header.clone())
.map(|(_, fee_entry)| fee_entry.clone())
.collect();
}

Ok(headers)
Ok(result)
}
}

Expand Down Expand Up @@ -588,3 +588,24 @@ pub async fn fee_history_cache_new_blocks_task<St, Provider>(
}
}
}

#[derive(Debug, Clone)]
pub struct FeeHistoryEntry {
base_fee_per_gas: u64,
gas_used_ratio: f64,
gas_used: u64,
gas_limit: u64,
header_hash: B256,
}

impl From<&SealedHeader> for FeeHistoryEntry {
fn from(header: &SealedHeader) -> Self {
FeeHistoryEntry {
base_fee_per_gas: header.base_fee_per_gas.unwrap_or_default(),
gas_used_ratio: header.gas_used as f64 / header.gas_limit as f64,
gas_used: header.gas_used,
header_hash: header.hash,
gas_limit: header.gas_limit,
}
}
}

0 comments on commit 912fd0f

Please sign in to comment.