From 3e11202e418eaafa31ae6e5183877cd3c67d7f4e Mon Sep 17 00:00:00 2001 From: Ishika Choudhury <117741714+Rimeeeeee@users.noreply.github.com> Date: Mon, 6 Apr 2026 18:31:13 +0530 Subject: [PATCH 1/2] chore: check for gas used at boundary --- crates/evm/src/block/error.rs | 5 +++++ crates/evm/src/eth/block.rs | 15 +++++++++++++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/crates/evm/src/block/error.rs b/crates/evm/src/block/error.rs index d65f2bd1..bee76c24 100644 --- a/crates/evm/src/block/error.rs +++ b/crates/evm/src/block/error.rs @@ -79,6 +79,11 @@ pub enum BlockValidationError { /// [EIP-6110]: https://eips.ethereum.org/EIPS/eip-6110 #[error("failed to decode deposit requests from receipts: {_0}")] DepositRequestDecode(String), + /// Error when block's total gas used exceeds the block gas limit + /// + /// [EIP-8037]: https://eips.ethereum.org/EIPS/eip-8037 + #[error("block gas used exceeds block gas limit")] + BlockGasExceeded, /// Arbitrary Block validation errors. #[error(transparent)] Other(Box), diff --git a/crates/evm/src/eth/block.rs b/crates/evm/src/eth/block.rs index 09b80bd1..fb214509 100644 --- a/crates/evm/src/eth/block.rs +++ b/crates/evm/src/eth/block.rs @@ -165,13 +165,13 @@ where // Pre-Amsterdam: use tx_gas_used (gas after refunds) as cumulative gas, matching // the original behavior where gas_used = spent - refunded. // - // Amsterdam+: use max(block_regular_gas_used, block_state_gas_used) which tracks + // Amsterdam+: use block_regular_gas_used which tracks // gas without refunds, as required by EIP-8037 dual-limit accounting. let block_gas_used = if self .spec .is_amsterdam_active_at_timestamp(self.evm.block().timestamp().saturating_to()) { - self.max_block_gas_used() + self.block_regular_gas_used } else { self.cumulative_tx_gas_used }; @@ -206,6 +206,11 @@ where self.system_caller.on_state(StateChangeSource::Transaction(self.receipts.len()), &state); + //check whether amsterdam is active + let amsterdam_active = self + .spec + .is_amsterdam_active_at_timestamp(self.evm.block().timestamp().saturating_to()); + // gas_used returned by revm is AFTER refunds //let gas_after_refund = result.gas_used(); let tx_gas_used = result.gas().tx_gas_used(); @@ -217,6 +222,12 @@ where self.block_state_gas_used += state_gas_used; self.cumulative_tx_gas_used += tx_gas_used; + // Check block gas limit after each transaction if Amsterdam is active, as required by + // EIP-8037. + if amsterdam_active && self.max_block_gas_used() > self.evm.block().gas_limit() { + return Err(BlockValidationError::BlockGasExceeded.into()); + } + // only determine cancun fields when active if self.spec.is_cancun_active_at_timestamp(self.evm.block().timestamp().saturating_to()) { self.blob_gas_used = self.blob_gas_used.saturating_add(blob_gas_used); From 150e035b0d64e5596f2eeb78c2c1e1676e8b3d42 Mon Sep 17 00:00:00 2001 From: Ishika Choudhury <117741714+Rimeeeeee@users.noreply.github.com> Date: Mon, 6 Apr 2026 19:02:41 +0530 Subject: [PATCH 2/2] fixes --- crates/evm/src/eth/block.rs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/crates/evm/src/eth/block.rs b/crates/evm/src/eth/block.rs index fb214509..23804fe1 100644 --- a/crates/evm/src/eth/block.rs +++ b/crates/evm/src/eth/block.rs @@ -21,10 +21,14 @@ use alloy_eips::{eip4895::Withdrawal, eip7685::Requests, Encodable2718}; use alloy_hardforks::EthereumHardfork; use alloy_primitives::{Bytes, Log, B256}; use revm::{ - context::Block, context_interface::result::ResultAndState, database::DatabaseCommitExt, + context::{result::min, Block}, + context_interface::result::ResultAndState, + database::DatabaseCommitExt, DatabaseCommit, Inspector, }; +use revm::primitives::eip7825::TX_GAS_LIMIT_CAP; + /// Context for Ethereum block execution. #[derive(Debug, Clone)] pub struct EthBlockExecutionCtx<'a> { @@ -176,8 +180,8 @@ where self.cumulative_tx_gas_used }; let block_available_gas = self.evm.block().gas_limit() - block_gas_used; - - if tx.tx().gas_limit() > block_available_gas { + let tx_min_gas_limit = min(tx.tx().gas_limit(), TX_GAS_LIMIT_CAP); + if tx_min_gas_limit > block_available_gas { return Err(BlockValidationError::TransactionGasLimitMoreThanAvailableBlockGas { transaction_gas_limit: tx.tx().gas_limit(), block_available_gas,