mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
add minimum check in check_gas_limit with unit test (#6157)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
This commit is contained in:
@ -5,6 +5,7 @@ use reth_primitives::{
|
||||
constants::{
|
||||
self,
|
||||
eip4844::{DATA_GAS_PER_BLOB, MAX_DATA_GAS_PER_BLOCK},
|
||||
MINIMUM_GAS_LIMIT,
|
||||
},
|
||||
eip4844::calculate_excess_blob_gas,
|
||||
BlockNumber, ChainSpec, GotExpected, Hardfork, Header, InvalidTransactionError, SealedBlock,
|
||||
@ -257,36 +258,45 @@ pub fn validate_block_standalone(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// Check gas limit, max diff between child/parent gas_limit should be max_diff=parent_gas/1024
|
||||
// On Optimism, the gas limit can adjust instantly, so we skip this check if the optimism
|
||||
// flag is enabled in the chain spec.
|
||||
/// Checks the gas limit for consistency between parent and child headers.
|
||||
///
|
||||
/// The maximum allowable difference between child and parent gas limits is determined by the
|
||||
/// parent's gas limit divided by the elasticity multiplier (1024).
|
||||
///
|
||||
/// This check is skipped if the Optimism flag is enabled in the chain spec, as gas limits on
|
||||
/// Optimism can adjust instantly.
|
||||
#[inline(always)]
|
||||
fn check_gas_limit(
|
||||
parent: &SealedHeader,
|
||||
child: &SealedHeader,
|
||||
chain_spec: &ChainSpec,
|
||||
) -> Result<(), ConsensusError> {
|
||||
// Determine the parent gas limit, considering elasticity multiplier on the London fork.
|
||||
let mut parent_gas_limit = parent.gas_limit;
|
||||
|
||||
// By consensus, gas_limit is multiplied by elasticity (*2) on
|
||||
// on exact block that hardfork happens.
|
||||
if chain_spec.fork(Hardfork::London).transitions_at_block(child.number) {
|
||||
parent_gas_limit =
|
||||
parent.gas_limit * chain_spec.base_fee_params(child.timestamp).elasticity_multiplier;
|
||||
}
|
||||
|
||||
// Check for an increase in gas limit beyond the allowed threshold.
|
||||
if child.gas_limit > parent_gas_limit {
|
||||
if child.gas_limit - parent_gas_limit >= parent_gas_limit / 1024 {
|
||||
return Err(ConsensusError::GasLimitInvalidIncrease {
|
||||
parent_gas_limit,
|
||||
child_gas_limit: child.gas_limit,
|
||||
})
|
||||
});
|
||||
}
|
||||
} else if parent_gas_limit - child.gas_limit >= parent_gas_limit / 1024 {
|
||||
}
|
||||
// Check for a decrease in gas limit beyond the allowed threshold.
|
||||
else if parent_gas_limit - child.gas_limit >= parent_gas_limit / 1024 {
|
||||
return Err(ConsensusError::GasLimitInvalidDecrease {
|
||||
parent_gas_limit,
|
||||
child_gas_limit: child.gas_limit,
|
||||
})
|
||||
});
|
||||
}
|
||||
// Check if the child gas limit is below the minimum required limit.
|
||||
else if child.gas_limit < MINIMUM_GAS_LIMIT {
|
||||
return Err(ConsensusError::GasLimitInvalidMinimum { child_gas_limit: child.gas_limit });
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@ -880,6 +890,24 @@ mod tests {
|
||||
assert_eq!(check_gas_limit(&parent, &child, &chain_spec), Ok(()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_gas_limit_below_minimum() {
|
||||
let parent = SealedHeader {
|
||||
header: Header { gas_limit: MINIMUM_GAS_LIMIT, ..Default::default() },
|
||||
..Default::default()
|
||||
};
|
||||
let child = SealedHeader {
|
||||
header: Header { gas_limit: MINIMUM_GAS_LIMIT - 1, ..Default::default() },
|
||||
..Default::default()
|
||||
};
|
||||
let chain_spec = ChainSpec::default();
|
||||
|
||||
assert_eq!(
|
||||
check_gas_limit(&parent, &child, &chain_spec),
|
||||
Err(ConsensusError::GasLimitInvalidMinimum { child_gas_limit: child.gas_limit })
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_invalid_gas_limit_increase_exceeding_limit() {
|
||||
let gas_limit = 1024 * 10;
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
use reth_primitives::{
|
||||
BlockHash, BlockNumber, GotExpected, GotExpectedBoxed, Header, InvalidTransactionError,
|
||||
SealedBlock, SealedHeader, B256, U256,
|
||||
constants::MINIMUM_GAS_LIMIT, BlockHash, BlockNumber, GotExpected, GotExpectedBoxed, Header,
|
||||
InvalidTransactionError, SealedBlock, SealedHeader, B256, U256,
|
||||
};
|
||||
use std::fmt::Debug;
|
||||
|
||||
@ -170,6 +170,15 @@ pub enum ConsensusError {
|
||||
child_gas_limit: u64,
|
||||
},
|
||||
|
||||
/// Error indicating that the child gas limit is below the minimum allowed limit.
|
||||
///
|
||||
/// This error occurs when the child gas limit is less than the specified minimum gas limit.
|
||||
#[error("child gas limit {child_gas_limit} is below the minimum allowed limit ({MINIMUM_GAS_LIMIT})")]
|
||||
GasLimitInvalidMinimum {
|
||||
/// The child gas limit.
|
||||
child_gas_limit: u64,
|
||||
},
|
||||
|
||||
/// Error when the base fee is missing.
|
||||
#[error("base fee missing")]
|
||||
BaseFeeMissing,
|
||||
|
||||
@ -61,6 +61,9 @@ pub const EIP1559_DEFAULT_BASE_FEE_MAX_CHANGE_DENOMINATOR: u64 = 8;
|
||||
/// Elasticity multiplier as defined in [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559)
|
||||
pub const EIP1559_DEFAULT_ELASTICITY_MULTIPLIER: u64 = 2;
|
||||
|
||||
/// Minimum gas limit allowed for transactions.
|
||||
pub const MINIMUM_GAS_LIMIT: u64 = 5000;
|
||||
|
||||
/// Base fee max change denominator for Optimism Mainnet as defined in the Optimism
|
||||
/// [transaction costs](https://community.optimism.io/docs/developers/build/differences/#transaction-costs) doc.
|
||||
#[cfg(feature = "optimism")]
|
||||
|
||||
Reference in New Issue
Block a user