mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 19:09:54 +00:00
refactor: replace ``calculate_next_block_base_fee`` with alloy's builtin function (#7641)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
This commit is contained in:
@ -1,168 +1,111 @@
|
|||||||
//! Helpers for working with EIP-1559 base fee
|
//! Helpers for working with EIP-1559 base fee
|
||||||
|
|
||||||
/// Calculate the base fee for the next block based on the EIP-1559 specification.
|
// re-export
|
||||||
///
|
#[doc(inline)]
|
||||||
/// This function calculates the base fee for the next block according to the rules defined in the
|
pub use alloy_eips::eip1559::calc_next_block_base_fee;
|
||||||
/// EIP-1559. EIP-1559 introduces a new transaction pricing mechanism that includes a
|
|
||||||
/// fixed-per-block network fee that is burned and dynamically adjusts block sizes to handle
|
#[cfg(test)]
|
||||||
/// transient congestion.
|
mod tests {
|
||||||
///
|
use super::*;
|
||||||
/// For each block, the base fee per gas is determined by the gas used in the parent block and the
|
|
||||||
/// target gas (the block gas limit divided by the elasticity multiplier). The algorithm increases
|
#[cfg(feature = "optimism")]
|
||||||
/// the base fee when blocks are congested and decreases it when they are under the target gas
|
use crate::chain::{OP_BASE_FEE_PARAMS, OP_SEPOLIA_BASE_FEE_PARAMS};
|
||||||
/// usage. The base fee per gas is always burned.
|
|
||||||
///
|
#[test]
|
||||||
/// Parameters:
|
fn calculate_base_fee_success() {
|
||||||
/// - `gas_used`: The gas used in the current block.
|
let base_fee = [
|
||||||
/// - `gas_limit`: The gas limit of the current block.
|
1000000000, 1000000000, 1000000000, 1072671875, 1059263476, 1049238967, 1049238967, 0,
|
||||||
/// - `base_fee`: The current base fee per gas.
|
1, 2,
|
||||||
/// - `base_fee_params`: Base fee parameters such as elasticity multiplier and max change
|
];
|
||||||
/// denominator.
|
let gas_used = [
|
||||||
///
|
10000000, 10000000, 10000000, 9000000, 10001000, 0, 10000000, 10000000, 10000000,
|
||||||
/// Returns:
|
10000000,
|
||||||
/// The calculated base fee for the next block as a `u64`.
|
];
|
||||||
///
|
let gas_limit = [
|
||||||
/// For more information, refer to the [EIP-1559 spec](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1559.md).
|
10000000, 12000000, 14000000, 10000000, 14000000, 2000000, 18000000, 18000000,
|
||||||
pub fn calculate_next_block_base_fee(
|
18000000, 18000000,
|
||||||
gas_used: u64,
|
];
|
||||||
gas_limit: u64,
|
let next_base_fee = [
|
||||||
base_fee: u64,
|
1125000000, 1083333333, 1053571428, 1179939062, 1116028649, 918084097, 1063811730, 1,
|
||||||
base_fee_params: crate::BaseFeeParams,
|
2, 3,
|
||||||
) -> u64 {
|
];
|
||||||
// Calculate the target gas by dividing the gas limit by the elasticity multiplier.
|
|
||||||
let gas_target = gas_limit / base_fee_params.elasticity_multiplier as u64;
|
for i in 0..base_fee.len() {
|
||||||
|
assert_eq!(
|
||||||
match gas_used.cmp(&gas_target) {
|
next_base_fee[i],
|
||||||
// If the gas used in the current block is equal to the gas target, the base fee remains the
|
calc_next_block_base_fee(
|
||||||
// same (no increase).
|
gas_used[i] as u128,
|
||||||
std::cmp::Ordering::Equal => base_fee,
|
gas_limit[i] as u128,
|
||||||
// If the gas used in the current block is greater than the gas target, calculate a new
|
base_fee[i] as u128,
|
||||||
// increased base fee.
|
crate::BaseFeeParams::ethereum(),
|
||||||
std::cmp::Ordering::Greater => {
|
) as u64
|
||||||
// Calculate the increase in base fee based on the formula defined by EIP-1559.
|
);
|
||||||
base_fee +
|
}
|
||||||
(std::cmp::max(
|
}
|
||||||
// Ensure a minimum increase of 1.
|
|
||||||
1,
|
#[cfg(feature = "optimism")]
|
||||||
base_fee as u128 * (gas_used - gas_target) as u128 /
|
#[test]
|
||||||
(gas_target as u128 * base_fee_params.max_change_denominator),
|
fn calculate_optimism_base_fee_success() {
|
||||||
) as u64)
|
let base_fee = [
|
||||||
}
|
1000000000, 1000000000, 1000000000, 1072671875, 1059263476, 1049238967, 1049238967, 0,
|
||||||
// If the gas used in the current block is less than the gas target, calculate a new
|
1, 2,
|
||||||
// decreased base fee.
|
];
|
||||||
std::cmp::Ordering::Less => {
|
let gas_used = [
|
||||||
// Calculate the decrease in base fee based on the formula defined by EIP-1559.
|
10000000, 10000000, 10000000, 9000000, 10001000, 0, 10000000, 10000000, 10000000,
|
||||||
base_fee.saturating_sub(
|
10000000,
|
||||||
(base_fee as u128 * (gas_target - gas_used) as u128 /
|
];
|
||||||
(gas_target as u128 * base_fee_params.max_change_denominator))
|
let gas_limit = [
|
||||||
as u64,
|
10000000, 12000000, 14000000, 10000000, 14000000, 2000000, 18000000, 18000000,
|
||||||
)
|
18000000, 18000000,
|
||||||
}
|
];
|
||||||
}
|
let next_base_fee = [
|
||||||
}
|
1100000048, 1080000000, 1065714297, 1167067046, 1128881311, 1028254188, 1098203452, 1,
|
||||||
|
2, 3,
|
||||||
#[cfg(test)]
|
];
|
||||||
mod tests {
|
|
||||||
use super::*;
|
for i in 0..base_fee.len() {
|
||||||
|
assert_eq!(
|
||||||
#[cfg(feature = "optimism")]
|
next_base_fee[i],
|
||||||
use crate::chain::{OP_BASE_FEE_PARAMS, OP_SEPOLIA_BASE_FEE_PARAMS};
|
calc_next_block_base_fee(
|
||||||
|
gas_used[i] as u128,
|
||||||
#[test]
|
gas_limit[i] as u128,
|
||||||
fn calculate_base_fee_success() {
|
base_fee[i] as u128,
|
||||||
let base_fee = [
|
OP_BASE_FEE_PARAMS,
|
||||||
1000000000, 1000000000, 1000000000, 1072671875, 1059263476, 1049238967, 1049238967, 0,
|
) as u64
|
||||||
1, 2,
|
);
|
||||||
];
|
}
|
||||||
let gas_used = [
|
}
|
||||||
10000000, 10000000, 10000000, 9000000, 10001000, 0, 10000000, 10000000, 10000000,
|
|
||||||
10000000,
|
#[cfg(feature = "optimism")]
|
||||||
];
|
#[test]
|
||||||
let gas_limit = [
|
fn calculate_optimism_sepolia_base_fee_success() {
|
||||||
10000000, 12000000, 14000000, 10000000, 14000000, 2000000, 18000000, 18000000,
|
let base_fee = [
|
||||||
18000000, 18000000,
|
1000000000, 1000000000, 1000000000, 1072671875, 1059263476, 1049238967, 1049238967, 0,
|
||||||
];
|
1, 2,
|
||||||
let next_base_fee = [
|
];
|
||||||
1125000000, 1083333333, 1053571428, 1179939062, 1116028649, 918084097, 1063811730, 1,
|
let gas_used = [
|
||||||
2, 3,
|
10000000, 10000000, 10000000, 9000000, 10001000, 0, 10000000, 10000000, 10000000,
|
||||||
];
|
10000000,
|
||||||
|
];
|
||||||
for i in 0..base_fee.len() {
|
let gas_limit = [
|
||||||
assert_eq!(
|
10000000, 12000000, 14000000, 10000000, 14000000, 2000000, 18000000, 18000000,
|
||||||
next_base_fee[i],
|
18000000, 18000000,
|
||||||
calculate_next_block_base_fee(
|
];
|
||||||
gas_used[i],
|
let next_base_fee = [
|
||||||
gas_limit[i],
|
1180000000, 1146666666, 1122857142, 1244299375, 1189416692, 1028254188, 1144836295, 1,
|
||||||
base_fee[i],
|
2, 3,
|
||||||
crate::BaseFeeParams::ethereum(),
|
];
|
||||||
)
|
|
||||||
);
|
for i in 0..base_fee.len() {
|
||||||
}
|
assert_eq!(
|
||||||
}
|
next_base_fee[i],
|
||||||
|
calc_next_block_base_fee(
|
||||||
#[cfg(feature = "optimism")]
|
gas_used[i] as u128,
|
||||||
#[test]
|
gas_limit[i] as u128,
|
||||||
fn calculate_optimism_base_fee_success() {
|
base_fee[i] as u128,
|
||||||
let base_fee = [
|
OP_SEPOLIA_BASE_FEE_PARAMS,
|
||||||
1000000000, 1000000000, 1000000000, 1072671875, 1059263476, 1049238967, 1049238967, 0,
|
) as u64
|
||||||
1, 2,
|
);
|
||||||
];
|
}
|
||||||
let gas_used = [
|
}
|
||||||
10000000, 10000000, 10000000, 9000000, 10001000, 0, 10000000, 10000000, 10000000,
|
}
|
||||||
10000000,
|
|
||||||
];
|
|
||||||
let gas_limit = [
|
|
||||||
10000000, 12000000, 14000000, 10000000, 14000000, 2000000, 18000000, 18000000,
|
|
||||||
18000000, 18000000,
|
|
||||||
];
|
|
||||||
let next_base_fee = [
|
|
||||||
1100000048, 1080000000, 1065714297, 1167067046, 1128881311, 1028254188, 1098203452, 1,
|
|
||||||
2, 3,
|
|
||||||
];
|
|
||||||
|
|
||||||
for i in 0..base_fee.len() {
|
|
||||||
assert_eq!(
|
|
||||||
next_base_fee[i],
|
|
||||||
calculate_next_block_base_fee(
|
|
||||||
gas_used[i],
|
|
||||||
gas_limit[i],
|
|
||||||
base_fee[i],
|
|
||||||
OP_BASE_FEE_PARAMS,
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "optimism")]
|
|
||||||
#[test]
|
|
||||||
fn calculate_optimism_sepolia_base_fee_success() {
|
|
||||||
let base_fee = [
|
|
||||||
1000000000, 1000000000, 1000000000, 1072671875, 1059263476, 1049238967, 1049238967, 0,
|
|
||||||
1, 2,
|
|
||||||
];
|
|
||||||
let gas_used = [
|
|
||||||
10000000, 10000000, 10000000, 9000000, 10001000, 0, 10000000, 10000000, 10000000,
|
|
||||||
10000000,
|
|
||||||
];
|
|
||||||
let gas_limit = [
|
|
||||||
10000000, 12000000, 14000000, 10000000, 14000000, 2000000, 18000000, 18000000,
|
|
||||||
18000000, 18000000,
|
|
||||||
];
|
|
||||||
let next_base_fee = [
|
|
||||||
1180000000, 1146666666, 1122857142, 1244299375, 1189416692, 1028254188, 1144836295, 1,
|
|
||||||
2, 3,
|
|
||||||
];
|
|
||||||
|
|
||||||
for i in 0..base_fee.len() {
|
|
||||||
assert_eq!(
|
|
||||||
next_base_fee[i],
|
|
||||||
calculate_next_block_base_fee(
|
|
||||||
gas_used[i],
|
|
||||||
gas_limit[i],
|
|
||||||
base_fee[i],
|
|
||||||
OP_SEPOLIA_BASE_FEE_PARAMS,
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
#[cfg(any(test, feature = "arbitrary"))]
|
#[cfg(any(test, feature = "arbitrary"))]
|
||||||
use crate::block::{generate_valid_header, valid_header_strategy};
|
use crate::block::{generate_valid_header, valid_header_strategy};
|
||||||
use crate::{
|
use crate::{
|
||||||
basefee::calculate_next_block_base_fee,
|
basefee::calc_next_block_base_fee,
|
||||||
constants,
|
constants,
|
||||||
constants::{
|
constants::{
|
||||||
ALLOWED_FUTURE_BLOCK_TIME_SECONDS, EMPTY_OMMER_ROOT_HASH, EMPTY_ROOT_HASH,
|
ALLOWED_FUTURE_BLOCK_TIME_SECONDS, EMPTY_OMMER_ROOT_HASH, EMPTY_ROOT_HASH,
|
||||||
@ -247,12 +247,12 @@ impl Header {
|
|||||||
///
|
///
|
||||||
/// Returns a `None` if no base fee is set, no EIP-1559 support
|
/// Returns a `None` if no base fee is set, no EIP-1559 support
|
||||||
pub fn next_block_base_fee(&self, base_fee_params: BaseFeeParams) -> Option<u64> {
|
pub fn next_block_base_fee(&self, base_fee_params: BaseFeeParams) -> Option<u64> {
|
||||||
Some(calculate_next_block_base_fee(
|
Some(calc_next_block_base_fee(
|
||||||
self.gas_used,
|
self.gas_used as u128,
|
||||||
self.gas_limit,
|
self.gas_limit as u128,
|
||||||
self.base_fee_per_gas?,
|
self.base_fee_per_gas? as u128,
|
||||||
base_fee_params,
|
base_fee_params,
|
||||||
))
|
) as u64)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Calculate excess blob gas for the next block according to the EIP-4844 spec.
|
/// Calculate excess blob gas for the next block according to the EIP-4844 spec.
|
||||||
|
|||||||
@ -7,7 +7,7 @@ use futures::{
|
|||||||
};
|
};
|
||||||
use metrics::atomics::AtomicU64;
|
use metrics::atomics::AtomicU64;
|
||||||
use reth_primitives::{
|
use reth_primitives::{
|
||||||
basefee::calculate_next_block_base_fee,
|
basefee::calc_next_block_base_fee,
|
||||||
eip4844::{calc_blob_gasprice, calculate_excess_blob_gas},
|
eip4844::{calc_blob_gasprice, calculate_excess_blob_gas},
|
||||||
ChainSpec, Receipt, SealedBlock, TransactionSigned, B256,
|
ChainSpec, Receipt, SealedBlock, TransactionSigned, B256,
|
||||||
};
|
};
|
||||||
@ -370,12 +370,12 @@ impl FeeHistoryEntry {
|
|||||||
|
|
||||||
/// Returns the base fee for the next block according to the EIP-1559 spec.
|
/// Returns the base fee for the next block according to the EIP-1559 spec.
|
||||||
pub fn next_block_base_fee(&self, chain_spec: &ChainSpec) -> u64 {
|
pub fn next_block_base_fee(&self, chain_spec: &ChainSpec) -> u64 {
|
||||||
calculate_next_block_base_fee(
|
calc_next_block_base_fee(
|
||||||
self.gas_used,
|
self.gas_used as u128,
|
||||||
self.gas_limit,
|
self.gas_limit as u128,
|
||||||
self.base_fee_per_gas,
|
self.base_fee_per_gas as u128,
|
||||||
chain_spec.base_fee_params(self.timestamp),
|
chain_spec.base_fee_params(self.timestamp),
|
||||||
)
|
) as u64
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the blob fee for the next block according to the EIP-4844 spec.
|
/// Returns the blob fee for the next block according to the EIP-4844 spec.
|
||||||
|
|||||||
@ -9,7 +9,7 @@ use crate::{
|
|||||||
};
|
};
|
||||||
use reth_evm::ConfigureEvm;
|
use reth_evm::ConfigureEvm;
|
||||||
use reth_network_api::NetworkInfo;
|
use reth_network_api::NetworkInfo;
|
||||||
use reth_primitives::{basefee::calculate_next_block_base_fee, BlockNumberOrTag, U256};
|
use reth_primitives::{BlockNumberOrTag, U256};
|
||||||
use reth_provider::{BlockReaderIdExt, ChainSpecProvider, EvmEnvProvider, StateProviderFactory};
|
use reth_provider::{BlockReaderIdExt, ChainSpecProvider, EvmEnvProvider, StateProviderFactory};
|
||||||
use reth_rpc_types::FeeHistory;
|
use reth_rpc_types::FeeHistory;
|
||||||
use reth_transaction_pool::TransactionPool;
|
use reth_transaction_pool::TransactionPool;
|
||||||
@ -187,12 +187,12 @@ where
|
|||||||
//
|
//
|
||||||
// The unwrap is safe since we checked earlier that we got at least 1 header.
|
// The unwrap is safe since we checked earlier that we got at least 1 header.
|
||||||
let last_header = headers.last().expect("is present");
|
let last_header = headers.last().expect("is present");
|
||||||
base_fee_per_gas.push(calculate_next_block_base_fee(
|
base_fee_per_gas.push(
|
||||||
last_header.gas_used,
|
self.provider().chain_spec().base_fee_params(last_header.timestamp).next_block_base_fee(
|
||||||
last_header.gas_limit,
|
last_header.gas_used as u128,
|
||||||
last_header.base_fee_per_gas.unwrap_or_default(),
|
last_header.gas_limit as u128,
|
||||||
self.provider().chain_spec().base_fee_params(last_header.timestamp),
|
last_header.base_fee_per_gas.unwrap_or_default() as u128,
|
||||||
) as u128);
|
));
|
||||||
|
|
||||||
// Same goes for the `base_fee_per_blob_gas`:
|
// 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.
|
// > "[..] includes the next block after the newest of the returned range, because this value can be derived from the newest block.
|
||||||
|
|||||||
@ -1,16 +1,10 @@
|
|||||||
//! Implementation of the [`jsonrpsee`] generated [`reth_rpc_api::EthApiServer`] trait
|
//! Implementation of the [`jsonrpsee`] generated [`reth_rpc_api::EthApiServer`] trait
|
||||||
//! Handles RPC requests for the `eth_` namespace.
|
//! Handles RPC requests for the `eth_` namespace.
|
||||||
|
|
||||||
use super::EthApiSpec;
|
|
||||||
use crate::{
|
|
||||||
eth::{
|
|
||||||
api::{EthApi, EthTransactions},
|
|
||||||
error::EthApiError,
|
|
||||||
revm_utils::EvmOverrides,
|
|
||||||
},
|
|
||||||
result::{internal_rpc_err, ToRpcResult},
|
|
||||||
};
|
|
||||||
use jsonrpsee::core::RpcResult as Result;
|
use jsonrpsee::core::RpcResult as Result;
|
||||||
|
use serde_json::Value;
|
||||||
|
use tracing::trace;
|
||||||
|
|
||||||
use reth_evm::ConfigureEvm;
|
use reth_evm::ConfigureEvm;
|
||||||
use reth_network_api::NetworkInfo;
|
use reth_network_api::NetworkInfo;
|
||||||
use reth_primitives::{
|
use reth_primitives::{
|
||||||
@ -28,8 +22,17 @@ use reth_rpc_types::{
|
|||||||
StateContext, SyncStatus, TransactionRequest, Work,
|
StateContext, SyncStatus, TransactionRequest, Work,
|
||||||
};
|
};
|
||||||
use reth_transaction_pool::TransactionPool;
|
use reth_transaction_pool::TransactionPool;
|
||||||
use serde_json::Value;
|
|
||||||
use tracing::trace;
|
use crate::{
|
||||||
|
eth::{
|
||||||
|
api::{EthApi, EthTransactions},
|
||||||
|
error::EthApiError,
|
||||||
|
revm_utils::EvmOverrides,
|
||||||
|
},
|
||||||
|
result::{internal_rpc_err, ToRpcResult},
|
||||||
|
};
|
||||||
|
|
||||||
|
use super::EthApiSpec;
|
||||||
|
|
||||||
#[async_trait::async_trait]
|
#[async_trait::async_trait]
|
||||||
impl<Provider, Pool, Network, EvmConfig> EthApiServer for EthApi<Provider, Pool, Network, EvmConfig>
|
impl<Provider, Pool, Network, EvmConfig> EthApiServer for EthApi<Provider, Pool, Network, EvmConfig>
|
||||||
@ -435,6 +438,8 @@ where
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
use jsonrpsee::types::error::INVALID_PARAMS_CODE;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
eth::{
|
eth::{
|
||||||
cache::EthStateCache, gas_oracle::GasPriceOracle, FeeHistoryCache,
|
cache::EthStateCache, gas_oracle::GasPriceOracle, FeeHistoryCache,
|
||||||
@ -442,13 +447,12 @@ mod tests {
|
|||||||
},
|
},
|
||||||
EthApi,
|
EthApi,
|
||||||
};
|
};
|
||||||
use jsonrpsee::types::error::INVALID_PARAMS_CODE;
|
|
||||||
use reth_evm_ethereum::EthEvmConfig;
|
use reth_evm_ethereum::EthEvmConfig;
|
||||||
use reth_interfaces::test_utils::{generators, generators::Rng};
|
use reth_interfaces::test_utils::{generators, generators::Rng};
|
||||||
use reth_network_api::noop::NoopNetwork;
|
use reth_network_api::noop::NoopNetwork;
|
||||||
use reth_primitives::{
|
use reth_primitives::{
|
||||||
basefee::calculate_next_block_base_fee, constants::ETHEREUM_BLOCK_GAS_LIMIT, BaseFeeParams,
|
constants::ETHEREUM_BLOCK_GAS_LIMIT, BaseFeeParams, Block, BlockNumberOrTag, Header,
|
||||||
Block, BlockNumberOrTag, Header, TransactionSigned, B256,
|
TransactionSigned, B256,
|
||||||
};
|
};
|
||||||
use reth_provider::{
|
use reth_provider::{
|
||||||
test_utils::{MockEthProvider, NoopProvider},
|
test_utils::{MockEthProvider, NoopProvider},
|
||||||
@ -565,12 +569,11 @@ mod tests {
|
|||||||
|
|
||||||
// Add final base fee (for the next block outside of the request)
|
// Add final base fee (for the next block outside of the request)
|
||||||
let last_header = last_header.unwrap();
|
let last_header = last_header.unwrap();
|
||||||
base_fees_per_gas.push(calculate_next_block_base_fee(
|
base_fees_per_gas.push(BaseFeeParams::ethereum().next_block_base_fee(
|
||||||
last_header.gas_used,
|
last_header.gas_used as u128,
|
||||||
last_header.gas_limit,
|
last_header.gas_limit as u128,
|
||||||
last_header.base_fee_per_gas.unwrap_or_default(),
|
last_header.base_fee_per_gas.unwrap_or_default() as u128,
|
||||||
BaseFeeParams::ethereum(),
|
));
|
||||||
) as u128);
|
|
||||||
|
|
||||||
let eth_api = build_test_eth_api(mock_provider);
|
let eth_api = build_test_eth_api(mock_provider);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user