diff --git a/src/handler.rs b/src/handler.rs index 1d37c44..71aadb0 100644 --- a/src/handler.rs +++ b/src/handler.rs @@ -217,13 +217,17 @@ where let beneficiary = block.beneficiary(); // calculate the L1 cost of the transaction. - let l1_block_info = ctx.chain().clone(); - let Some(rlp_bytes) = &ctx.tx().rlp_bytes() else { - return Err(ERROR::from_string( - "[SCROLL] Failed to load transaction rlp_bytes.".to_string(), - )); + let l1_cost = if !ctx.tx().is_system_tx() { + let l1_block_info = ctx.chain().clone(); + let Some(rlp_bytes) = &ctx.tx().rlp_bytes() else { + return Err(ERROR::from_string( + "[SCROLL] Failed to load transaction rlp_bytes.".to_string(), + )); + }; + l1_block_info.calculate_tx_l1_cost(rlp_bytes, ctx.cfg().spec()) + } else { + U256::from(0) }; - let l1_cost = l1_block_info.calculate_tx_l1_cost(rlp_bytes, ctx.cfg().spec()); // reward the beneficiary with the gas fee including the L1 cost of the transaction and mark // the account as touched. diff --git a/src/tests/fees.rs b/src/tests/fees.rs index f7aa83b..2ac5829 100644 --- a/src/tests/fees.rs +++ b/src/tests/fees.rs @@ -1,17 +1,17 @@ use crate::{ builder::ScrollBuilder, handler::ScrollHandler, - test_utils::{context_with_funds, CALLER}, + test_utils::{context, context_with_funds, BENEFICIARY, CALLER}, transaction::SYSTEM_ADDRESS, ScrollSpecId, }; -use std::boxed::Box; - use revm::{ context::{result::EVMError, ContextTr, JournalTr}, - handler::{EthFrame, EvmTr, Handler}, + handler::{EthFrame, EvmTr, FrameResult, Handler}, + interpreter::{CallOutcome, Gas, InstructionResult, InterpreterResult}, }; use revm_primitives::U256; +use std::boxed::Box; #[test] fn test_should_deduct_correct_fees_bernoulli() -> Result<(), Box> { @@ -68,3 +68,26 @@ fn test_no_rollup_fee_for_system_tx() -> Result<(), Box> Ok(()) } + +#[test] +fn test_reward_beneficiary_system_tx() -> Result<(), Box> { + let ctx = context() + .modify_cfg_chained(|cfg| cfg.spec = ScrollSpecId::CURIE) + .modify_tx_chained(|tx| tx.base.caller = SYSTEM_ADDRESS); + + let mut evm = ctx.build_scroll(); + let handler = ScrollHandler::<_, EVMError<_>, EthFrame<_, _, _>>::new(); + let gas = Gas::new_spent(21000); + let mut result = FrameResult::Call(CallOutcome::new( + InterpreterResult { result: InstructionResult::Return, output: Default::default(), gas }, + 0..0, + )); + handler.load_accounts(&mut evm)?; + handler.reward_beneficiary(&mut evm, &mut result)?; + + // beneficiary receives gas (if any), but not rollup fee + let beneficiary = evm.ctx().journal().load_account(BENEFICIARY)?; + assert_eq!(beneficiary.info.balance, U256::from(21000)); + + Ok(()) +}