Skip to content

Commit aac8ed3

Browse files
georgehaogreged93
andauthored
feat: add gaslimit check for execute_sequencer_transactions (#333)
* add gaslimit check for execute_sequencer_transactions * fix lint * rename the error name * address comment * fix * feat: complete PR and improve error Signed-off-by: Gregory Edison <[email protected]> * fix: renaming Signed-off-by: Gregory Edison <[email protected]> * feat: answer comments Signed-off-by: Gregory Edison <[email protected]> --------- Signed-off-by: Gregory Edison <[email protected]> Co-authored-by: Gregory Edison <[email protected]>
1 parent 501e5c6 commit aac8ed3

File tree

2 files changed

+31
-19
lines changed

2 files changed

+31
-19
lines changed

crates/scroll/payload/src/builder.rs

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use super::ScrollPayloadBuilderError;
44
use crate::config::{PayloadBuildingBreaker, ScrollBuilderConfig};
55

66
use alloy_consensus::{Transaction, Typed2718};
7-
use alloy_primitives::{B256, U256};
7+
use alloy_primitives::U256;
88
use alloy_rlp::Encodable;
99
use core::fmt::Debug;
1010
use reth_basic_payload_builder::{
@@ -22,9 +22,7 @@ use reth_execution_types::ExecutionOutcome;
2222
use reth_payload_builder::PayloadId;
2323
use reth_payload_primitives::{PayloadBuilderAttributes, PayloadBuilderError};
2424
use reth_payload_util::{BestPayloadTransactions, NoopPayloadTransactions, PayloadTransactions};
25-
use reth_primitives_traits::{
26-
NodePrimitives, RecoveredBlock, SealedHeader, SignedTransaction, TxTy,
27-
};
25+
use reth_primitives_traits::{RecoveredBlock, SealedHeader, SignedTransaction, TxTy};
2826
use reth_revm::{cancelled::CancelOnDrop, database::StateProviderDatabase, db::State};
2927
use reth_scroll_chainspec::{ChainConfig, ScrollChainConfig};
3028
use reth_scroll_engine_primitives::{ScrollBuiltPayload, ScrollPayloadBuilderAttributes};
@@ -437,6 +435,8 @@ where
437435
builder: &mut impl BlockBuilder<Primitives = Evm::Primitives>,
438436
) -> Result<ExecutionInfo, PayloadBuilderError> {
439437
let mut info = ExecutionInfo::new();
438+
let block_gas_limit = builder.evm().block().gas_limit;
439+
let mut gas_spent_by_transactions = Vec::new();
440440

441441
for sequencer_tx in &self.attributes().transactions {
442442
// A sequencer's block should never contain blob transactions.
@@ -445,7 +445,6 @@ where
445445
ScrollPayloadBuilderError::BlobTransactionRejected,
446446
))
447447
}
448-
449448
// Convert the transaction to a [RecoveredTx]. This is
450449
// purely for the purposes of utilizing the `evm_config.tx_env`` function.
451450
// Deposit transactions do not have signatures, so if the tx is a deposit, this
@@ -454,6 +453,18 @@ where
454453
PayloadBuilderError::other(ScrollPayloadBuilderError::TransactionEcRecoverFailed)
455454
})?;
456455

456+
let tx_gas = sequencer_tx.gas_limit();
457+
// check we don't go over the block gas limit
458+
if info.cumulative_gas_used + tx_gas > block_gas_limit {
459+
gas_spent_by_transactions.push(tx_gas);
460+
return Err(PayloadBuilderError::other(
461+
ScrollPayloadBuilderError::BlockGasLimitExceededBySequencerTransactions {
462+
gas_spent_by_tx: gas_spent_by_transactions,
463+
gas: block_gas_limit,
464+
},
465+
));
466+
}
467+
457468
let gas_used = match builder.execute_transaction(sequencer_tx.clone()) {
458469
Ok(gas_used) => gas_used,
459470
Err(BlockExecutionError::Validation(BlockValidationError::InvalidTx {
@@ -469,8 +480,14 @@ where
469480
}
470481
};
471482

472-
// add gas used by the transaction to cumulative gas used, before creating the receipt
483+
// unspent gas is not refunded and not reallocated to other transactions for L1
484+
// messages.
485+
let gas_used =
486+
if sequencer_tx.is_l1_message() { sequencer_tx.gas_limit() } else { gas_used };
487+
488+
// add gas used by the transaction to cumulative gas used
473489
info.cumulative_gas_used += gas_used;
490+
gas_spent_by_transactions.push(gas_used);
474491
}
475492

476493
Ok(info)
@@ -559,19 +576,6 @@ where
559576
}
560577
}
561578

562-
/// Holds the state after execution
563-
#[derive(Debug)]
564-
pub struct ExecutedPayload<N: NodePrimitives> {
565-
/// Tracked execution info
566-
pub info: ExecutionInfo,
567-
/// Withdrawal hash.
568-
pub withdrawals_root: Option<B256>,
569-
/// The transaction receipts.
570-
pub receipts: Vec<N::Receipt>,
571-
/// The block env used during execution.
572-
pub block_env: BlockEnv,
573-
}
574-
575579
/// This acts as the container for executed transactions and its byproducts (receipts, gas used)
576580
#[derive(Default, Debug)]
577581
pub struct ExecutionInfo {

crates/scroll/payload/src/error.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,12 @@ pub enum ScrollPayloadBuilderError {
88
/// Thrown when a blob transaction is included in a sequencer's block.
99
#[error("blob transaction included in sequencer block")]
1010
BlobTransactionRejected,
11+
/// Thrown when sequencer transaction gas limit exceeds remaining block gas.
12+
#[error("Sequencer transactions over gas limit: {gas}; gas spent by each transaction: {gas_spent_by_tx:?}")]
13+
BlockGasLimitExceededBySequencerTransactions {
14+
/// The gas used by each transaction in the block.
15+
gas_spent_by_tx: Vec<u64>,
16+
/// The block gas limit.
17+
gas: u64,
18+
},
1119
}

0 commit comments

Comments
 (0)