diff --git a/crates/blockchain/blockchain.rs b/crates/blockchain/blockchain.rs index d697424b0..70f509819 100644 --- a/crates/blockchain/blockchain.rs +++ b/crates/blockchain/blockchain.rs @@ -258,11 +258,11 @@ pub fn validate_block( validate_block_header(&block.header, parent_header).map_err(InvalidBlockError::from)?; if chain_config.is_prague_activated(block.header.timestamp) { - validate_prague_header_fields(&block.header, parent_header) + validate_prague_header_fields(&block.header, parent_header, chain_config) .map_err(InvalidBlockError::from)?; verify_blob_gas_usage(block, chain_config)?; } else if chain_config.is_cancun_activated(block.header.timestamp) { - validate_cancun_header_fields(&block.header, parent_header) + validate_cancun_header_fields(&block.header, parent_header, chain_config) .map_err(InvalidBlockError::from)?; verify_blob_gas_usage(block, chain_config)?; } else { diff --git a/crates/blockchain/payload.rs b/crates/blockchain/payload.rs index 6eb3e9df7..1faf70d38 100644 --- a/crates/blockchain/payload.rs +++ b/crates/blockchain/payload.rs @@ -8,8 +8,8 @@ use std::{ use ethrex_common::{ constants::GAS_PER_BLOB, types::{ - calculate_base_fee_per_blob_gas, calculate_base_fee_per_gas, compute_receipts_root, - compute_transactions_root, compute_withdrawals_root, + calc_excess_blob_gas, calculate_base_fee_per_blob_gas, calculate_base_fee_per_gas, + compute_receipts_root, compute_transactions_root, compute_withdrawals_root, requests::{compute_requests_hash, EncodedRequests, Requests}, BlobsBundle, Block, BlockBody, BlockHash, BlockHeader, BlockNumber, ChainConfig, MempoolTransaction, Receipt, Transaction, Withdrawal, DEFAULT_OMMERS_HASH, @@ -161,20 +161,6 @@ pub fn calc_gas_limit(parent_gas_limit: u64) -> u64 { limit } -pub fn calc_excess_blob_gas( - parent_excess_blob_gas: u64, - parent_blob_gas_used: u64, - target: u64, -) -> u64 { - let excess_blob_gas = parent_excess_blob_gas + parent_blob_gas_used; - let target_blob_gas_per_block = target * GAS_PER_BLOB; - if excess_blob_gas < target_blob_gas_per_block { - 0 - } else { - excess_blob_gas - target_blob_gas_per_block - } -} - pub struct PayloadBuildContext<'a> { pub payload: &'a mut Block, pub evm_state: &'a mut EvmState, diff --git a/crates/common/types/block.rs b/crates/common/types/block.rs index e27edd2af..5fb9efb04 100644 --- a/crates/common/types/block.rs +++ b/crates/common/types/block.rs @@ -1,9 +1,9 @@ use super::{ - BASE_FEE_MAX_CHANGE_DENOMINATOR, ELASTICITY_MULTIPLIER, GAS_LIMIT_ADJUSTMENT_FACTOR, - GAS_LIMIT_MINIMUM, INITIAL_BASE_FEE, + ChainConfig, BASE_FEE_MAX_CHANGE_DENOMINATOR, ELASTICITY_MULTIPLIER, + GAS_LIMIT_ADJUSTMENT_FACTOR, GAS_LIMIT_MINIMUM, INITIAL_BASE_FEE, }; use crate::{ - constants::MIN_BASE_FEE_PER_BLOB_GAS, + constants::{GAS_PER_BLOB, MIN_BASE_FEE_PER_BLOB_GAS}, types::{Receipt, Transaction}, Address, H256, U256, }; @@ -559,6 +559,7 @@ pub fn validate_block_header( pub fn validate_prague_header_fields( header: &BlockHeader, parent_header: &BlockHeader, + chain_config: &ChainConfig, ) -> Result<(), InvalidBlockHeaderError> { if header.excess_blob_gas.is_none() { return Err(InvalidBlockHeaderError::ExcessBlobGasNotPresent); @@ -566,9 +567,8 @@ pub fn validate_prague_header_fields( if header.blob_gas_used.is_none() { return Err(InvalidBlockHeaderError::BlobGasUsedNotPresent); } - if header.excess_blob_gas.unwrap() != calc_excess_blob_gas(parent_header) { - return Err(InvalidBlockHeaderError::ExcessBlobGasIncorrect); - } + validate_excess_blob_gas(header, parent_header, chain_config)?; + if header.parent_beacon_block_root.is_none() { return Err(InvalidBlockHeaderError::ParentBeaconBlockRootNotPresent); } @@ -583,6 +583,7 @@ pub fn validate_prague_header_fields( pub fn validate_cancun_header_fields( header: &BlockHeader, parent_header: &BlockHeader, + chain_config: &ChainConfig, ) -> Result<(), InvalidBlockHeaderError> { if header.excess_blob_gas.is_none() { return Err(InvalidBlockHeaderError::ExcessBlobGasNotPresent); @@ -590,9 +591,7 @@ pub fn validate_cancun_header_fields( if header.blob_gas_used.is_none() { return Err(InvalidBlockHeaderError::BlobGasUsedNotPresent); } - if header.excess_blob_gas.unwrap() != calc_excess_blob_gas(parent_header) { - return Err(InvalidBlockHeaderError::ExcessBlobGasIncorrect); - } + validate_excess_blob_gas(header, parent_header, chain_config)?; if header.parent_beacon_block_root.is_none() { return Err(InvalidBlockHeaderError::ParentBeaconBlockRootNotPresent); } @@ -622,15 +621,38 @@ pub fn validate_pre_cancun_header_fields( Ok(()) } -fn calc_excess_blob_gas(parent_header: &BlockHeader) -> u64 { - let parent_excess_blob_gas = parent_header.excess_blob_gas.unwrap_or_default(); - let parent_blob_gas_used = parent_header.blob_gas_used.unwrap_or_default(); - let parent_blob_gas = parent_excess_blob_gas + parent_blob_gas_used; +fn validate_excess_blob_gas( + header: &BlockHeader, + parent_header: &BlockHeader, + chain_config: &ChainConfig, +) -> Result<(), InvalidBlockHeaderError> { + let expected_excess_blob_gas = chain_config + .get_fork_blob_schedule(header.timestamp) + .map(|schedule| { + calc_excess_blob_gas( + parent_header.excess_blob_gas.unwrap_or_default(), + parent_header.blob_gas_used.unwrap_or_default(), + schedule.target, + ) + }) + .unwrap_or_default(); + if header.excess_blob_gas.unwrap() != expected_excess_blob_gas { + return Err(InvalidBlockHeaderError::ExcessBlobGasIncorrect); + } + Ok(()) +} - if parent_blob_gas < 393216_u64 { - 0u64 +pub fn calc_excess_blob_gas( + parent_excess_blob_gas: u64, + parent_blob_gas_used: u64, + target: u64, +) -> u64 { + let excess_blob_gas = parent_excess_blob_gas + parent_blob_gas_used; + let target_blob_gas_per_block = target * GAS_PER_BLOB; + if excess_blob_gas < target_blob_gas_per_block { + 0 } else { - parent_blob_gas - 393216_u64 + excess_blob_gas - target_blob_gas_per_block } } diff --git a/crates/networking/rpc/eth/fee_market.rs b/crates/networking/rpc/eth/fee_market.rs index 3043f4322..3cb58bbc2 100644 --- a/crates/networking/rpc/eth/fee_market.rs +++ b/crates/networking/rpc/eth/fee_market.rs @@ -1,9 +1,9 @@ -use ethrex_blockchain::payload::{calc_excess_blob_gas, calc_gas_limit}; +use ethrex_blockchain::payload::calc_gas_limit; use ethrex_common::{ constants::GAS_PER_BLOB, types::{ - calculate_base_fee_per_blob_gas, calculate_base_fee_per_gas, Block, BlockHeader, - Transaction, + calc_excess_blob_gas, calculate_base_fee_per_blob_gas, calculate_base_fee_per_gas, Block, + BlockHeader, Transaction, }, }; use serde::Serialize;