From 57c4f7e570c7fac06929c7bc035ae3e3df87ea81 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Sat, 29 Jun 2024 10:32:58 +0200 Subject: [PATCH] chore: rm leftover mods (#9188) --- .../rpc/rpc/src/eth/helpers/blocking_task.rs | 55 --- crates/rpc/rpc/src/eth/helpers/fee.rs | 346 ------------------ 2 files changed, 401 deletions(-) delete mode 100644 crates/rpc/rpc/src/eth/helpers/blocking_task.rs delete mode 100644 crates/rpc/rpc/src/eth/helpers/fee.rs diff --git a/crates/rpc/rpc/src/eth/helpers/blocking_task.rs b/crates/rpc/rpc/src/eth/helpers/blocking_task.rs deleted file mode 100644 index 1dae8dc6bb..0000000000 --- a/crates/rpc/rpc/src/eth/helpers/blocking_task.rs +++ /dev/null @@ -1,55 +0,0 @@ -//! Spawns a blocking task. CPU heavy tasks are executed with the `rayon` library. IO heavy tasks -//! are executed on the `tokio` runtime. - -use futures::Future; -use reth_tasks::{pool::BlockingTaskPool, TaskSpawner}; -use tokio::sync::oneshot; - -use crate::{EthApiError, EthResult}; - -/// Executes code on a blocking thread. -pub trait SpawnBlocking: Clone + Send + Sync + 'static { - /// Returns a handle for spawning IO heavy blocking tasks. - /// - /// Runtime access in default trait method implementations. - fn io_task_spawner(&self) -> impl TaskSpawner; - - /// Returns a handle for spawning CPU heavy blocking tasks. - /// - /// Thread pool access in default trait method implementations. - fn tracing_task_pool(&self) -> &BlockingTaskPool; - - /// Executes the future on a new blocking task. - /// - /// Note: This is expected for futures that are dominated by blocking IO operations, for tracing - /// or CPU bound operations in general use [`spawn_tracing`](Self::spawn_tracing). - fn spawn_blocking_io(&self, f: F) -> impl Future> + Send - where - F: FnOnce(Self) -> EthResult + Send + 'static, - R: Send + 'static, - { - let (tx, rx) = oneshot::channel(); - let this = self.clone(); - self.io_task_spawner().spawn_blocking(Box::pin(async move { - let res = async move { f(this) }.await; - let _ = tx.send(res); - })); - - async move { rx.await.map_err(|_| EthApiError::InternalEthError)? } - } - - /// Executes a blocking task on the tracing pool. - /// - /// Note: This is expected for futures that are predominantly CPU bound, as it uses `rayon` - /// under the hood, for blocking IO futures use [`spawn_blocking`](Self::spawn_blocking_io). See - /// . - fn spawn_tracing(&self, f: F) -> impl Future> + Send - where - F: FnOnce(Self) -> EthResult + Send + 'static, - R: Send + 'static, - { - let this = self.clone(); - let fut = self.tracing_task_pool().spawn(move || f(this)); - async move { fut.await.map_err(|_| EthApiError::InternalBlockingTaskError)? } - } -} diff --git a/crates/rpc/rpc/src/eth/helpers/fee.rs b/crates/rpc/rpc/src/eth/helpers/fee.rs deleted file mode 100644 index 7d795e52f3..0000000000 --- a/crates/rpc/rpc/src/eth/helpers/fee.rs +++ /dev/null @@ -1,346 +0,0 @@ -//! Loads fee history from database. Helper trait for `eth_` fee and transaction RPC methods. - -use futures::Future; -use reth_primitives::U256; -use reth_provider::{BlockIdReader, BlockReaderIdExt, ChainSpecProvider, HeaderProvider}; -use reth_rpc_types::{BlockNumberOrTag, FeeHistory}; -use tracing::debug; - -use crate::{ - fee_history::calculate_reward_percentiles_for_block, api::LoadBlock, EthApiError, - EthResult, EthStateCache, FeeHistoryCache, FeeHistoryEntry, GasPriceOracle, - RpcInvalidTransactionError, -}; - -/// Fee related functions for the [`EthApiServer`](crate::EthApiServer) trait in the -/// `eth_` namespace. -pub trait EthFees: LoadFee { - /// Returns a suggestion for a gas price for legacy transactions. - /// - /// See also: - fn gas_price(&self) -> impl Future> + Send - where - Self: LoadBlock, - { - LoadFee::gas_price(self) - } - - /// Returns a suggestion for a base fee for blob transactions. - fn blob_base_fee(&self) -> impl Future> + Send - where - Self: LoadBlock, - { - LoadFee::blob_base_fee(self) - } - - /// Returns a suggestion for the priority fee (the tip) - fn suggested_priority_fee(&self) -> impl Future> + Send - where - Self: 'static, - { - LoadFee::suggested_priority_fee(self) - } - - /// Reports the fee history, for the given amount of blocks, up until the given newest block. - /// - /// If `reward_percentiles` are provided the [`FeeHistory`] will include the _approximated_ - /// rewards for the requested range. - fn fee_history( - &self, - mut block_count: u64, - newest_block: BlockNumberOrTag, - reward_percentiles: Option>, - ) -> impl Future> + Send { - async move { - if block_count == 0 { - return Ok(FeeHistory::default()) - } - - // See https://github.com/ethereum/go-ethereum/blob/2754b197c935ee63101cbbca2752338246384fec/eth/gasprice/feehistory.go#L218C8-L225 - let max_fee_history = if reward_percentiles.is_none() { - self.gas_oracle().config().max_header_history - } else { - self.gas_oracle().config().max_block_history - }; - - if block_count > max_fee_history { - debug!( - requested = block_count, - truncated = max_fee_history, - "Sanitizing fee history block count" - ); - block_count = max_fee_history - } - - let Some(end_block) = - LoadFee::provider(self).block_number_for_id(newest_block.into())? - else { - return Err(EthApiError::UnknownBlockNumber) - }; - - // need to add 1 to the end block to get the correct (inclusive) range - let end_block_plus = end_block + 1; - // Ensure that we would not be querying outside of genesis - if end_block_plus < block_count { - block_count = end_block_plus; - } - - // If reward percentiles were specified, we - // need to validate that they are monotonically - // increasing and 0 <= p <= 100 - // Note: The types used ensure that the percentiles are never < 0 - if let Some(percentiles) = &reward_percentiles { - if percentiles.windows(2).any(|w| w[0] > w[1] || w[0] > 100.) { - return Err(EthApiError::InvalidRewardPercentiles) - } - } - - // Fetch the headers and ensure we got all of them - // - // Treat a request for 1 block as a request for `newest_block..=newest_block`, - // otherwise `newest_block - 2 - // NOTE: We ensured that block count is capped - let start_block = end_block_plus - block_count; - - // Collect base fees, gas usage ratios and (optionally) reward percentile data - let mut base_fee_per_gas: Vec = Vec::new(); - let mut gas_used_ratio: Vec = Vec::new(); - - let mut base_fee_per_blob_gas: Vec = Vec::new(); - let mut blob_gas_used_ratio: Vec = Vec::new(); - - let mut rewards: Vec> = Vec::new(); - - // Check if the requested range is within the cache bounds - let fee_entries = self.fee_history_cache().get_history(start_block, end_block).await; - - if let Some(fee_entries) = fee_entries { - if fee_entries.len() != block_count as usize { - return Err(EthApiError::InvalidBlockRange) - } - - for entry in &fee_entries { - base_fee_per_gas.push(entry.base_fee_per_gas as u128); - gas_used_ratio.push(entry.gas_used_ratio); - base_fee_per_blob_gas.push(entry.base_fee_per_blob_gas.unwrap_or_default()); - blob_gas_used_ratio.push(entry.blob_gas_used_ratio); - - if let Some(percentiles) = &reward_percentiles { - let mut block_rewards = Vec::with_capacity(percentiles.len()); - for &percentile in percentiles { - block_rewards.push(self.approximate_percentile(entry, percentile)); - } - rewards.push(block_rewards); - } - } - let last_entry = fee_entries.last().expect("is not empty"); - - // Also need to include the `base_fee_per_gas` and `base_fee_per_blob_gas` for the - // next block - base_fee_per_gas - .push(last_entry.next_block_base_fee(&LoadFee::provider(self).chain_spec()) - as u128); - - base_fee_per_blob_gas.push(last_entry.next_block_blob_fee().unwrap_or_default()); - } else { - // read the requested header range - let headers = LoadFee::provider(self).sealed_headers_range(start_block..=end_block)?; - if headers.len() != block_count as usize { - return Err(EthApiError::InvalidBlockRange) - } - - for header in &headers { - base_fee_per_gas.push(header.base_fee_per_gas.unwrap_or_default() as u128); - gas_used_ratio.push(header.gas_used as f64 / header.gas_limit as f64); - base_fee_per_blob_gas.push(header.blob_fee().unwrap_or_default()); - blob_gas_used_ratio.push( - header.blob_gas_used.unwrap_or_default() as f64 / - reth_primitives::constants::eip4844::MAX_DATA_GAS_PER_BLOCK as f64, - ); - - // Percentiles were specified, so we need to collect reward percentile ino - if let Some(percentiles) = &reward_percentiles { - let (transactions, receipts) = LoadFee::cache(self) - .get_transactions_and_receipts(header.hash()) - .await? - .ok_or(EthApiError::InvalidBlockRange)?; - rewards.push( - calculate_reward_percentiles_for_block( - percentiles, - header.gas_used, - header.base_fee_per_gas.unwrap_or_default(), - &transactions, - &receipts, - ) - .unwrap_or_default(), - ); - } - } - - // 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" - // - // The unwrap is safe since we checked earlier that we got at least 1 header. - let last_header = headers.last().expect("is present"); - base_fee_per_gas.push( - LoadFee::provider(self).chain_spec().base_fee_params_at_timestamp(last_header.timestamp).next_block_base_fee( - last_header.gas_used as u128, - last_header.gas_limit as u128, - last_header.base_fee_per_gas.unwrap_or_default() as u128, - )); - - // Same goes for the `base_fee_per_blob_gas`: - // > "[..] includes the next block after the newest of the returned range, because this value can be derived from the newest block. - base_fee_per_blob_gas - .push(last_header.next_block_blob_fee().unwrap_or_default()); - }; - - Ok(FeeHistory { - base_fee_per_gas, - gas_used_ratio, - base_fee_per_blob_gas, - blob_gas_used_ratio, - oldest_block: start_block, - reward: reward_percentiles.map(|_| rewards), - }) - } - } - - /// Approximates reward at a given percentile for a specific block - /// Based on the configured resolution - fn approximate_percentile(&self, entry: &FeeHistoryEntry, requested_percentile: f64) -> u128 { - let resolution = self.fee_history_cache().resolution(); - let rounded_percentile = - (requested_percentile * resolution as f64).round() / resolution as f64; - let clamped_percentile = rounded_percentile.clamp(0.0, 100.0); - - // Calculate the index in the precomputed rewards array - let index = (clamped_percentile / (1.0 / resolution as f64)).round() as usize; - // Fetch the reward from the FeeHistoryEntry - entry.rewards.get(index).cloned().unwrap_or_default() - } -} - -/// Loads fee from database. -/// -/// Behaviour shared by several `eth_` RPC methods, not exclusive to `eth_` fees RPC methods. -pub trait LoadFee: LoadBlock { - // Returns a handle for reading data from disk. - /// - /// Data access in default (L1) trait method implementations. - fn provider(&self) -> impl BlockIdReader + HeaderProvider + ChainSpecProvider; - - /// Returns a handle for reading data from memory. - /// - /// Data access in default (L1) trait method implementations. - fn cache(&self) -> &EthStateCache; - - /// Returns a handle for reading gas price. - /// - /// Data access in default (L1) trait method implementations. - fn gas_oracle(&self) -> &GasPriceOracle; - - /// Returns a handle for reading fee history data from memory. - /// - /// Data access in default (L1) trait method implementations. - fn fee_history_cache(&self) -> &FeeHistoryCache; - - /// Returns the gas price if it is set, otherwise fetches a suggested gas price for legacy - /// transactions. - fn legacy_gas_price( - &self, - gas_price: Option, - ) -> impl Future> + Send { - async move { - match gas_price { - Some(gas_price) => Ok(gas_price), - None => { - // fetch a suggested gas price - self.gas_price().await - } - } - } - } - - /// Returns the EIP-1559 fees if they are set, otherwise fetches a suggested gas price for - /// EIP-1559 transactions. - /// - /// Returns (`max_fee`, `priority_fee`) - fn eip1559_fees( - &self, - max_fee_per_gas: Option, - max_priority_fee_per_gas: Option, - ) -> impl Future> + Send { - async move { - let max_fee_per_gas = match max_fee_per_gas { - Some(max_fee_per_gas) => max_fee_per_gas, - None => { - // fetch pending base fee - let base_fee = self - .block(BlockNumberOrTag::Pending) - .await? - .ok_or(EthApiError::UnknownBlockNumber)? - .base_fee_per_gas - .ok_or_else(|| { - EthApiError::InvalidTransaction( - RpcInvalidTransactionError::TxTypeNotSupported, - ) - })?; - U256::from(base_fee) - } - }; - - let max_priority_fee_per_gas = match max_priority_fee_per_gas { - Some(max_priority_fee_per_gas) => max_priority_fee_per_gas, - None => self.suggested_priority_fee().await?, - }; - Ok((max_fee_per_gas, max_priority_fee_per_gas)) - } - } - - /// Returns the EIP-4844 blob fee if it is set, otherwise fetches a blob fee. - fn eip4844_blob_fee( - &self, - blob_fee: Option, - ) -> impl Future> + Send { - async move { - match blob_fee { - Some(blob_fee) => Ok(blob_fee), - None => self.blob_base_fee().await, - } - } - } - - /// Returns a suggestion for a gas price for legacy transactions. - /// - /// See also: - fn gas_price(&self) -> impl Future> + Send { - let header = self.block(BlockNumberOrTag::Latest); - let suggested_tip = self.suggested_priority_fee(); - async move { - let (header, suggested_tip) = futures::try_join!(header, suggested_tip)?; - let base_fee = header.and_then(|h| h.base_fee_per_gas).unwrap_or_default(); - Ok(suggested_tip + U256::from(base_fee)) - } - } - - /// Returns a suggestion for a base fee for blob transactions. - fn blob_base_fee(&self) -> impl Future> + Send { - async move { - self.block(BlockNumberOrTag::Latest) - .await? - .and_then(|h: reth_primitives::SealedBlock| h.next_block_blob_fee()) - .ok_or(EthApiError::ExcessBlobGasNotSet) - .map(U256::from) - } - } - - /// Returns a suggestion for the priority fee (the tip) - fn suggested_priority_fee(&self) -> impl Future> + Send - where - Self: 'static, - { - self.gas_oracle().suggest_tip_cap() - } -}