mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
chore: move next base fee to header impl (#2400)
This commit is contained in:
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -5086,7 +5086,6 @@ dependencies = [
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
"metrics",
|
||||
"reth-consensus-common",
|
||||
"reth-interfaces",
|
||||
"reth-metrics-derive",
|
||||
"reth-primitives",
|
||||
|
||||
@ -234,32 +234,6 @@ pub fn validate_block_standalone(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Calculate base fee for next block. EIP-1559 spec
|
||||
pub fn calculate_next_block_base_fee(gas_used: u64, gas_limit: u64, base_fee: u64) -> u64 {
|
||||
let gas_target = gas_limit / constants::EIP1559_ELASTICITY_MULTIPLIER;
|
||||
|
||||
if gas_used == gas_target {
|
||||
return base_fee
|
||||
}
|
||||
if gas_used > gas_target {
|
||||
let gas_used_delta = gas_used - gas_target;
|
||||
let base_fee_delta = std::cmp::max(
|
||||
1,
|
||||
base_fee as u128 * gas_used_delta as u128 /
|
||||
gas_target as u128 /
|
||||
constants::EIP1559_BASE_FEE_MAX_CHANGE_DENOMINATOR as u128,
|
||||
);
|
||||
base_fee + (base_fee_delta as u64)
|
||||
} else {
|
||||
let gas_used_delta = gas_target - gas_used;
|
||||
let base_fee_per_gas_delta = base_fee as u128 * gas_used_delta as u128 /
|
||||
gas_target as u128 /
|
||||
constants::EIP1559_BASE_FEE_MAX_CHANGE_DENOMINATOR as u128;
|
||||
|
||||
base_fee.saturating_sub(base_fee_per_gas_delta as u64)
|
||||
}
|
||||
}
|
||||
|
||||
/// Validate block in regards to parent
|
||||
pub fn validate_header_regarding_parent(
|
||||
parent: &SealedHeader,
|
||||
@ -320,11 +294,7 @@ pub fn validate_header_regarding_parent(
|
||||
constants::EIP1559_INITIAL_BASE_FEE
|
||||
} else {
|
||||
// This BaseFeeMissing will not happen as previous blocks are checked to have them.
|
||||
calculate_next_block_base_fee(
|
||||
parent.gas_used,
|
||||
parent.gas_limit,
|
||||
parent.base_fee_per_gas.ok_or(ConsensusError::BaseFeeMissing)?,
|
||||
)
|
||||
parent.next_block_base_fee().ok_or(ConsensusError::BaseFeeMissing)?
|
||||
};
|
||||
if expected_base_fee != base_fee {
|
||||
return Err(ConsensusError::BaseFeeDiff { expected: expected_base_fee, got: base_fee })
|
||||
@ -428,33 +398,6 @@ mod tests {
|
||||
};
|
||||
use std::ops::RangeBounds;
|
||||
|
||||
#[test]
|
||||
fn calculate_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 = [
|
||||
1125000000, 1083333333, 1053571428, 1179939062, 1116028649, 918084097, 1063811730, 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])
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
mock! {
|
||||
WithdrawalsProvider {}
|
||||
|
||||
|
||||
@ -13,7 +13,6 @@ reth-primitives = { path = "../../primitives" }
|
||||
reth-rpc-types = { path = "../../rpc/rpc-types" }
|
||||
reth-rlp = { path = "../../rlp" }
|
||||
reth-interfaces = { path = "../../interfaces" }
|
||||
reth-consensus-common = { path = "../../consensus/common" }
|
||||
reth-revm-primitives = { path = "../../revm/revm-primitives" }
|
||||
|
||||
## ethereum
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
//! Contains types required for building a payload.
|
||||
|
||||
use reth_consensus_common::validation::calculate_next_block_base_fee;
|
||||
use reth_primitives::{Address, ChainSpec, Header, SealedBlock, Withdrawal, H256, U256};
|
||||
use reth_revm_primitives::config::revm_spec_by_timestamp_after_merge;
|
||||
use reth_rlp::Encodable;
|
||||
@ -135,11 +134,7 @@ impl PayloadBuilderAttributes {
|
||||
prevrandao: Some(self.prev_randao),
|
||||
gas_limit: U256::from(parent.gas_limit),
|
||||
// calculate basefee based on parent block's gas usage
|
||||
basefee: U256::from(calculate_next_block_base_fee(
|
||||
parent.gas_used,
|
||||
parent.gas_limit,
|
||||
parent.base_fee_per_gas.unwrap_or_default(),
|
||||
)),
|
||||
basefee: U256::from(parent.next_block_base_fee().unwrap_or_default()),
|
||||
};
|
||||
|
||||
(cfg, block_env)
|
||||
|
||||
61
crates/primitives/src/basefee.rs
Normal file
61
crates/primitives/src/basefee.rs
Normal file
@ -0,0 +1,61 @@
|
||||
//! Helpers for working with EIP-1559 base fee
|
||||
|
||||
use crate::constants;
|
||||
|
||||
/// Calculate base fee for next block. [EIP-1559](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1559.md) spec
|
||||
pub fn calculate_next_block_base_fee(gas_used: u64, gas_limit: u64, base_fee: u64) -> u64 {
|
||||
let gas_target = gas_limit / constants::EIP1559_ELASTICITY_MULTIPLIER;
|
||||
|
||||
if gas_used == gas_target {
|
||||
return base_fee
|
||||
}
|
||||
if gas_used > gas_target {
|
||||
let gas_used_delta = gas_used - gas_target;
|
||||
let base_fee_delta = std::cmp::max(
|
||||
1,
|
||||
base_fee as u128 * gas_used_delta as u128 /
|
||||
gas_target as u128 /
|
||||
constants::EIP1559_BASE_FEE_MAX_CHANGE_DENOMINATOR as u128,
|
||||
);
|
||||
base_fee + (base_fee_delta as u64)
|
||||
} else {
|
||||
let gas_used_delta = gas_target - gas_used;
|
||||
let base_fee_per_gas_delta = base_fee as u128 * gas_used_delta as u128 /
|
||||
gas_target as u128 /
|
||||
constants::EIP1559_BASE_FEE_MAX_CHANGE_DENOMINATOR as u128;
|
||||
|
||||
base_fee.saturating_sub(base_fee_per_gas_delta as u64)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn calculate_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 = [
|
||||
1125000000, 1083333333, 1053571428, 1179939062, 1116028649, 918084097, 1063811730, 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])
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,5 @@
|
||||
use crate::{
|
||||
basefee::calculate_next_block_base_fee,
|
||||
keccak256,
|
||||
proofs::{EMPTY_LIST_HASH, EMPTY_ROOT},
|
||||
BlockHash, BlockNumber, Bloom, Bytes, H160, H256, U256,
|
||||
@ -145,6 +146,13 @@ impl Header {
|
||||
self.transactions_root == EMPTY_ROOT
|
||||
}
|
||||
|
||||
/// Calculate base fee for next block according to the EIP-1559 spec.
|
||||
///
|
||||
/// Returns a `None` if no base fee is set, no EIP-1559 support
|
||||
pub fn next_block_base_fee(&self) -> Option<u64> {
|
||||
Some(calculate_next_block_base_fee(self.gas_used, self.gas_limit, self.base_fee_per_gas?))
|
||||
}
|
||||
|
||||
/// Seal the header with a known hash.
|
||||
///
|
||||
/// WARNING: This method does not perform validation whether the hash is correct.
|
||||
|
||||
@ -10,6 +10,7 @@
|
||||
//! This crate contains Ethereum primitive types and helper functions.
|
||||
|
||||
mod account;
|
||||
pub mod basefee;
|
||||
mod bits;
|
||||
mod block;
|
||||
pub mod bloom;
|
||||
|
||||
@ -5,7 +5,6 @@ use crate::{
|
||||
Pool, TransactionOrdering, TransactionPool, TransactionValidator,
|
||||
};
|
||||
use futures_util::{Stream, StreamExt};
|
||||
use reth_consensus_common::validation::calculate_next_block_base_fee;
|
||||
use reth_primitives::{Address, BlockHash, FromRecoveredTransaction};
|
||||
use reth_provider::{BlockProvider, CanonStateNotification, PostState, StateProviderFactory};
|
||||
use std::{
|
||||
@ -46,11 +45,8 @@ pub async fn maintain_transaction_pool<Client, V, T, St>(
|
||||
let new_tip = new_blocks.tip();
|
||||
|
||||
// base fee for the next block: `new_tip+1`
|
||||
let pending_block_base_fee = calculate_next_block_base_fee(
|
||||
new_tip.gas_used,
|
||||
new_tip.gas_limit,
|
||||
new_tip.base_fee_per_gas.unwrap_or_default(),
|
||||
) as u128;
|
||||
let pending_block_base_fee =
|
||||
new_tip.next_block_base_fee().unwrap_or_default() as u128;
|
||||
|
||||
// we know all changed account in the new chain
|
||||
let new_changed_accounts: HashSet<_> =
|
||||
@ -133,11 +129,8 @@ pub async fn maintain_transaction_pool<Client, V, T, St>(
|
||||
}
|
||||
|
||||
// base fee for the next block: `first_block+1`
|
||||
let pending_block_base_fee = calculate_next_block_base_fee(
|
||||
first_block.gas_used,
|
||||
first_block.gas_limit,
|
||||
first_block.base_fee_per_gas.unwrap_or_default(),
|
||||
) as u128;
|
||||
let pending_block_base_fee =
|
||||
first_block.next_block_base_fee().unwrap_or_default() as u128;
|
||||
let changed_accounts = changed_accounts_iter(state).collect();
|
||||
let update = CanonicalStateUpdate {
|
||||
hash: first_block.hash,
|
||||
@ -169,11 +162,7 @@ pub async fn maintain_transaction_pool<Client, V, T, St>(
|
||||
let (blocks, state) = new.inner();
|
||||
let tip = blocks.tip();
|
||||
// base fee for the next block: `tip+1`
|
||||
let pending_block_base_fee = calculate_next_block_base_fee(
|
||||
tip.gas_used,
|
||||
tip.gas_limit,
|
||||
tip.base_fee_per_gas.unwrap_or_default(),
|
||||
) as u128;
|
||||
let pending_block_base_fee = tip.next_block_base_fee().unwrap_or_default() as u128;
|
||||
|
||||
let first_block = blocks.first();
|
||||
// check if the range of the commit is canonical
|
||||
|
||||
Reference in New Issue
Block a user