feat: base fee param fetching at a specific block (#7783)

This commit is contained in:
Darshan Kathiriya
2024-04-22 11:46:56 -04:00
committed by GitHub
parent 24a8202481
commit 9a1d6ea9ca
9 changed files with 69 additions and 33 deletions

View File

@ -277,10 +277,9 @@ impl StorageInner {
let timestamp = SystemTime::now().duration_since(UNIX_EPOCH).unwrap_or_default().as_secs();
// check previous block for base fee
let base_fee_per_gas = self
.headers
.get(&self.best_block)
.and_then(|parent| parent.next_block_base_fee(chain_spec.base_fee_params(timestamp)));
let base_fee_per_gas = self.headers.get(&self.best_block).and_then(|parent| {
parent.next_block_base_fee(chain_spec.base_fee_params_at_timestamp(timestamp))
});
let mut header = Header {
parent_hash: self.best_hash,

View File

@ -245,7 +245,8 @@ impl PayloadBuilderAttributes for EthPayloadBuilderAttributes {
})
.map(BlobExcessGasAndPrice::new);
let mut basefee = parent.next_block_base_fee(chain_spec.base_fee_params(self.timestamp()));
let mut basefee =
parent.next_block_base_fee(chain_spec.base_fee_params_at_timestamp(self.timestamp()));
let mut gas_limit = U256::from(parent.gas_limit);
@ -253,7 +254,7 @@ impl PayloadBuilderAttributes for EthPayloadBuilderAttributes {
// elasticity multiplier to get the new gas limit.
if chain_spec.fork(Hardfork::London).transitions_at_block(parent.number + 1) {
let elasticity_multiplier =
chain_spec.base_fee_params(self.timestamp()).elasticity_multiplier;
chain_spec.base_fee_params_at_timestamp(self.timestamp()).elasticity_multiplier;
// multiply the gas limit by the elasticity multiplier
gas_limit *= U256::from(elasticity_multiplier);

View File

@ -142,7 +142,7 @@ impl PayloadBuilderAttributes for OptimismPayloadBuilderAttributes {
// calculate basefee based on parent block's gas usage
basefee: U256::from(
parent
.next_block_base_fee(chain_spec.base_fee_params(self.timestamp()))
.next_block_base_fee(chain_spec.base_fee_params_at_timestamp(self.timestamp()))
.unwrap_or_default(),
),
// calculate excess gas based on parent block's blob gas usage

View File

@ -661,10 +661,10 @@ impl ChainSpec {
}
/// Get the [BaseFeeParams] for the chain at the given timestamp.
pub fn base_fee_params(&self, timestamp: u64) -> BaseFeeParams {
pub fn base_fee_params_at_timestamp(&self, timestamp: u64) -> BaseFeeParams {
match self.base_fee_params {
BaseFeeParamsKind::Constant(bf_params) => bf_params,
BaseFeeParamsKind::Variable(ForkBaseFeeParams { 0: ref bf_params }) => {
BaseFeeParamsKind::Variable(ForkBaseFeeParams(ref bf_params)) => {
// Walk through the base fee params configuration in reverse order, and return the
// first one that corresponds to a hardfork that is active at the
// given timestamp.
@ -679,6 +679,25 @@ impl ChainSpec {
}
}
/// Get the [BaseFeeParams] for the chain at the given block number
pub fn base_fee_params_at_block(&self, block_number: u64) -> BaseFeeParams {
match self.base_fee_params {
BaseFeeParamsKind::Constant(bf_params) => bf_params,
BaseFeeParamsKind::Variable(ForkBaseFeeParams(ref bf_params)) => {
// Walk through the base fee params configuration in reverse order, and return the
// first one that corresponds to a hardfork that is active at the
// given timestamp.
for (fork, params) in bf_params.iter().rev() {
if self.is_fork_active_at_block(*fork, block_number) {
return *params
}
}
bf_params.first().map(|(_, params)| *params).unwrap_or(BaseFeeParams::ethereum())
}
}
}
/// Get the hash of the genesis block.
pub fn genesis_hash(&self) -> B256 {
self.genesis_hash.unwrap_or_else(|| self.genesis_header().hash_slow())
@ -770,6 +789,12 @@ impl ChainSpec {
self.fork(fork).active_at_timestamp(timestamp)
}
/// Convenience method to check if a fork is active at a given block number
#[inline]
pub fn is_fork_active_at_block(&self, fork: Hardfork, block_number: u64) -> bool {
self.fork(fork).active_at_block(block_number)
}
/// Convenience method to check if [Hardfork::Shanghai] is active at a given timestamp.
#[inline]
pub fn is_shanghai_active_at_timestamp(&self, timestamp: u64) -> bool {
@ -3168,8 +3193,9 @@ Post-merge hard forks (timestamp based):
genesis.hash_slow(),
b256!("f712aa9241cc24369b143cf6dce85f0902a9731e70d66818a3a5845b296c73dd")
);
let base_fee =
genesis.next_block_base_fee(BASE_MAINNET.base_fee_params(genesis.timestamp)).unwrap();
let base_fee = genesis
.next_block_base_fee(BASE_MAINNET.base_fee_params_at_timestamp(genesis.timestamp))
.unwrap();
// <https://base.blockscout.com/block/1>
assert_eq!(base_fee, 980000000);
}
@ -3182,8 +3208,9 @@ Post-merge hard forks (timestamp based):
genesis.hash_slow(),
b256!("0dcc9e089e30b90ddfc55be9a37dd15bc551aeee999d2e2b51414c54eaf934e4")
);
let base_fee =
genesis.next_block_base_fee(BASE_SEPOLIA.base_fee_params(genesis.timestamp)).unwrap();
let base_fee = genesis
.next_block_base_fee(BASE_SEPOLIA.base_fee_params_at_timestamp(genesis.timestamp))
.unwrap();
// <https://base-sepolia.blockscout.com/block/1>
assert_eq!(base_fee, 980000000);
}
@ -3196,8 +3223,9 @@ Post-merge hard forks (timestamp based):
genesis.hash_slow(),
b256!("102de6ffb001480cc9b8b548fd05c34cd4f46ae4aa91759393db90ea0409887d")
);
let base_fee =
genesis.next_block_base_fee(OP_SEPOLIA.base_fee_params(genesis.timestamp)).unwrap();
let base_fee = genesis
.next_block_base_fee(OP_SEPOLIA.base_fee_params_at_timestamp(genesis.timestamp))
.unwrap();
// <https://optimism-sepolia.blockscout.com/block/1>
assert_eq!(base_fee, 980000000);
}

View File

@ -700,7 +700,8 @@ impl SealedHeader {
let parent_gas_limit =
if chain_spec.fork(Hardfork::London).transitions_at_block(self.number) {
parent.gas_limit *
chain_spec.base_fee_params(self.timestamp).elasticity_multiplier as u64
chain_spec.base_fee_params_at_timestamp(self.timestamp).elasticity_multiplier
as u64
} else {
parent.gas_limit
};
@ -801,14 +802,16 @@ impl SealedHeader {
if chain_spec.fork(Hardfork::London).active_at_block(self.number) {
let base_fee = self.base_fee_per_gas.ok_or(HeaderValidationError::BaseFeeMissing)?;
let expected_base_fee =
if chain_spec.fork(Hardfork::London).transitions_at_block(self.number) {
let expected_base_fee = if chain_spec
.fork(Hardfork::London)
.transitions_at_block(self.number)
{
constants::EIP1559_INITIAL_BASE_FEE
} else {
// This BaseFeeMissing will not happen as previous blocks are checked to have
// them.
parent
.next_block_base_fee(chain_spec.base_fee_params(self.timestamp))
.next_block_base_fee(chain_spec.base_fee_params_at_timestamp(self.timestamp))
.ok_or(HeaderValidationError::BaseFeeMissing)?
};
if expected_base_fee != base_fee {

View File

@ -374,7 +374,7 @@ impl FeeHistoryEntry {
self.gas_used as u128,
self.gas_limit as u128,
self.base_fee_per_gas as u128,
chain_spec.base_fee_params(self.timestamp),
chain_spec.base_fee_params_at_timestamp(self.timestamp),
) as u64
}

View File

@ -188,7 +188,7 @@ where
// 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(
self.provider().chain_spec().base_fee_params(last_header.timestamp).next_block_base_fee(
self.provider().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,

View File

@ -292,8 +292,9 @@ where
// base fee of the child block
let chain_spec = self.provider().chain_spec();
latest_header.base_fee_per_gas = latest_header
.next_block_base_fee(chain_spec.base_fee_params(latest_header.timestamp));
latest_header.base_fee_per_gas = latest_header.next_block_base_fee(
chain_spec.base_fee_params_at_timestamp(latest_header.timestamp),
);
// update excess blob gas consumed above target
latest_header.excess_blob_gas = latest_header.next_block_excess_blob_gas();

View File

@ -109,7 +109,7 @@ pub async fn maintain_transaction_pool<Client, P, St, Tasks>(
last_seen_block_hash: latest.hash(),
last_seen_block_number: latest.number,
pending_basefee: latest
.next_block_base_fee(chain_spec.base_fee_params(latest.timestamp + 12))
.next_block_base_fee(chain_spec.base_fee_params_at_timestamp(latest.timestamp + 12))
.unwrap_or_default(),
pending_blob_fee: latest.next_block_blob_fee(),
};
@ -265,7 +265,9 @@ pub async fn maintain_transaction_pool<Client, P, St, Tasks>(
// fees for the next block: `new_tip+1`
let pending_block_base_fee = new_tip
.next_block_base_fee(chain_spec.base_fee_params(new_tip.timestamp + 12))
.next_block_base_fee(
chain_spec.base_fee_params_at_timestamp(new_tip.timestamp + 12),
)
.unwrap_or_default();
let pending_block_blob_fee = new_tip.next_block_blob_fee();
@ -370,7 +372,9 @@ pub async fn maintain_transaction_pool<Client, P, St, Tasks>(
// fees for the next block: `tip+1`
let pending_block_base_fee = tip
.next_block_base_fee(chain_spec.base_fee_params(tip.timestamp + 12))
.next_block_base_fee(
chain_spec.base_fee_params_at_timestamp(tip.timestamp + 12),
)
.unwrap_or_default();
let pending_block_blob_fee = tip.next_block_blob_fee();