Skip to content

Commit c45bf2c

Browse files
authored
chore: check for gas used at boundary (#331)
* chore: check for gas used at boundary * fixes
1 parent 3cd42e7 commit c45bf2c

2 files changed

Lines changed: 25 additions & 5 deletions

File tree

crates/evm/src/block/error.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,11 @@ pub enum BlockValidationError {
7979
/// [EIP-6110]: https://eips.ethereum.org/EIPS/eip-6110
8080
#[error("failed to decode deposit requests from receipts: {_0}")]
8181
DepositRequestDecode(String),
82+
/// Error when block's total gas used exceeds the block gas limit
83+
///
84+
/// [EIP-8037]: https://eips.ethereum.org/EIPS/eip-8037
85+
#[error("block gas used exceeds block gas limit")]
86+
BlockGasExceeded,
8287
/// Arbitrary Block validation errors.
8388
#[error(transparent)]
8489
Other(Box<dyn core::error::Error + Send + Sync + 'static>),

crates/evm/src/eth/block.rs

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,14 @@ use alloy_eips::{eip4895::Withdrawal, eip7685::Requests, Encodable2718};
2121
use alloy_hardforks::EthereumHardfork;
2222
use alloy_primitives::{Bytes, Log, B256};
2323
use 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)]
3034
pub 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

Comments
 (0)