@@ -21,10 +21,14 @@ use alloy_eips::{eip4895::Withdrawal, eip7685::Requests, Encodable2718};
2121use alloy_hardforks:: EthereumHardfork ;
2222use alloy_primitives:: { Bytes , Log , B256 } ;
2323use revm:: {
24- context:: Block , context_interface:: result:: ResultAndState , database:: DatabaseCommitExt ,
24+ context:: { result:: min, Block } ,
25+ context_interface:: result:: ResultAndState ,
26+ database:: DatabaseCommitExt ,
2527 DatabaseCommit , Inspector ,
2628} ;
2729
30+ use revm:: primitives:: eip7825:: TX_GAS_LIMIT_CAP ;
31+
2832/// Context for Ethereum block execution.
2933#[ derive( Debug , Clone ) ]
3034pub struct EthBlockExecutionCtx < ' a > {
@@ -165,19 +169,19 @@ where
165169 // Pre-Amsterdam: use tx_gas_used (gas after refunds) as cumulative gas, matching
166170 // the original behavior where gas_used = spent - refunded.
167171 //
168- // Amsterdam+: use max( block_regular_gas_used, block_state_gas_used) which tracks
172+ // Amsterdam+: use block_regular_gas_used which tracks
169173 // gas without refunds, as required by EIP-8037 dual-limit accounting.
170174 let block_gas_used = if self
171175 . spec
172176 . is_amsterdam_active_at_timestamp ( self . evm . block ( ) . timestamp ( ) . saturating_to ( ) )
173177 {
174- self . max_block_gas_used ( )
178+ self . block_regular_gas_used
175179 } else {
176180 self . cumulative_tx_gas_used
177181 } ;
178182 let block_available_gas = self . evm . block ( ) . gas_limit ( ) - block_gas_used;
179-
180- if tx . tx ( ) . gas_limit ( ) > block_available_gas {
183+ let tx_min_gas_limit = min ( tx . tx ( ) . gas_limit ( ) , TX_GAS_LIMIT_CAP ) ;
184+ if tx_min_gas_limit > block_available_gas {
181185 return Err ( BlockValidationError :: TransactionGasLimitMoreThanAvailableBlockGas {
182186 transaction_gas_limit : tx. tx ( ) . gas_limit ( ) ,
183187 block_available_gas,
@@ -206,6 +210,11 @@ where
206210
207211 self . system_caller . on_state ( StateChangeSource :: Transaction ( self . receipts . len ( ) ) , & state) ;
208212
213+ //check whether amsterdam is active
214+ let amsterdam_active = self
215+ . spec
216+ . is_amsterdam_active_at_timestamp ( self . evm . block ( ) . timestamp ( ) . saturating_to ( ) ) ;
217+
209218 // gas_used returned by revm is AFTER refunds
210219 //let gas_after_refund = result.gas_used();
211220 let tx_gas_used = result. gas ( ) . tx_gas_used ( ) ;
@@ -217,6 +226,12 @@ where
217226 self . block_state_gas_used += state_gas_used;
218227 self . cumulative_tx_gas_used += tx_gas_used;
219228
229+ // Check block gas limit after each transaction if Amsterdam is active, as required by
230+ // EIP-8037.
231+ if amsterdam_active && self . max_block_gas_used ( ) > self . evm . block ( ) . gas_limit ( ) {
232+ return Err ( BlockValidationError :: BlockGasExceeded . into ( ) ) ;
233+ }
234+
220235 // only determine cancun fields when active
221236 if self . spec . is_cancun_active_at_timestamp ( self . evm . block ( ) . timestamp ( ) . saturating_to ( ) ) {
222237 self . blob_gas_used = self . blob_gas_used . saturating_add ( blob_gas_used) ;
0 commit comments