Skip to content

Commit 9c2a419

Browse files
authored
l1 data fee buffer (#70)
1 parent a1ac004 commit 9c2a419

3 files changed

Lines changed: 63 additions & 17 deletions

File tree

Cargo.lock

Lines changed: 12 additions & 12 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ license = "MIT OR Apache-2.0"
66

77
[dependencies]
88
# revm
9-
revm = { git = "https://github.com/scroll-tech/revm", tag = "scroll-v91", default-features = false, features = ["enable_eip7702", "enable_eip7623"] }
10-
revm-primitives = { git = "https://github.com/scroll-tech/revm", tag = "scroll-v91", default-features = false }
11-
revm-inspector = { git = "https://github.com/scroll-tech/revm", tag = "scroll-v91", default-features = false }
9+
revm = { git = "https://github.com/scroll-tech/revm", tag = "scroll-v91.1", default-features = false, features = ["enable_eip7702", "enable_eip7623", "require_l1_data_fee_buffer"] }
10+
revm-primitives = { git = "https://github.com/scroll-tech/revm", tag = "scroll-v91.1", default-features = false }
11+
revm-inspector = { git = "https://github.com/scroll-tech/revm", tag = "scroll-v91.1", default-features = false }
1212

1313
# misc
1414
auto_impl = "1.2.0"

src/handler.rs

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,14 +110,26 @@ where
110110
ctx.tx().compression_ratio(),
111111
ctx.tx().compressed_size(),
112112
);
113+
114+
// Optionally check balance covers 2x L1 cost (1 unit charged + 1 unit buffer)
115+
let l1_cost_with_optional_buffer = if ctx.cfg().is_l1_data_fee_buffer_required() {
116+
tx_l1_cost.saturating_add(tx_l1_cost)
117+
} else {
118+
tx_l1_cost
119+
};
120+
113121
let caller_account = ctx.journal_mut().load_account(caller)?;
114-
if tx_l1_cost.gt(&caller_account.info.balance) {
122+
123+
// Ensure caller has enough balance to cover L1 cost + optional buffer
124+
if l1_cost_with_optional_buffer.gt(&caller_account.info.balance) {
115125
return Err(InvalidTransaction::LackOfFundForMaxFee {
116-
fee: tx_l1_cost.into(),
126+
fee: l1_cost_with_optional_buffer.into(),
117127
balance: caller_account.info.balance.into(),
118128
}
119129
.into());
120130
}
131+
132+
// Deduct only actual L1 cost (buffer is NOT deducted)
121133
caller_account.data.info.balance =
122134
caller_account.data.info.balance.saturating_sub(tx_l1_cost);
123135
}
@@ -440,4 +452,38 @@ mod tests {
440452

441453
Ok(())
442454
}
455+
456+
#[test]
457+
fn test_validate_l1_cost_buffer_required() -> Result<(), Box<dyn core::error::Error>> {
458+
// With buffer enabled via CfgEnv: 1x L1_cost should fail
459+
let ctx = context()
460+
.with_funds(MIN_TRANSACTION_COST + L1_DATA_COST)
461+
.modify_cfg_chained(|cfg| cfg.require_l1_data_fee_buffer = true);
462+
let mut evm = ctx.build_scroll();
463+
let handler = ScrollHandler::<_, EVMError<_>, EthFrame<_>>::new();
464+
assert!(matches!(
465+
handler.pre_execution(&mut evm),
466+
Err(EVMError::Transaction(InvalidTransaction::LackOfFundForMaxFee { .. }))
467+
));
468+
469+
// With buffer enabled: 2x L1_cost should pass
470+
let ctx = context()
471+
.with_funds(MIN_TRANSACTION_COST + L1_DATA_COST + L1_DATA_COST)
472+
.modify_cfg_chained(|cfg| cfg.require_l1_data_fee_buffer = true);
473+
let mut evm = ctx.build_scroll();
474+
assert!(handler.pre_execution(&mut evm).is_ok());
475+
476+
Ok(())
477+
}
478+
479+
#[test]
480+
fn test_validate_l1_cost_no_buffer_by_default() -> Result<(), Box<dyn core::error::Error>> {
481+
// Without buffer: 1x L1_cost should pass
482+
let ctx = context().with_funds(MIN_TRANSACTION_COST + L1_DATA_COST);
483+
let mut evm = ctx.build_scroll();
484+
let handler = ScrollHandler::<_, EVMError<_>, EthFrame<_>>::new();
485+
assert!(handler.pre_execution(&mut evm).is_ok());
486+
487+
Ok(())
488+
}
443489
}

0 commit comments

Comments
 (0)