Skip to content

Commit a4de13d

Browse files
authored
feat: expose l1 data fee buffer evm config (#378)
* expose l1 data fee buffer check config * use chain config for l1 data fee buffer * add l1 data fee buffer check parser * purge old pool configuration pattern * update bytes dependency for deny lint
1 parent 4fd69a4 commit a4de13d

7 files changed

Lines changed: 43 additions & 46 deletions

File tree

Cargo.lock

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

crates/scroll/alloy/evm/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ revm = { workspace = true, default-features = false, features = ["optional_no_ba
2323

2424
# scroll
2525
revm-scroll = { workspace = true, default-features = false }
26+
reth-scroll-chainspec = { workspace = true, default-features = false }
2627

2728
# scroll
2829
scroll-alloy-consensus = { workspace = true, default-features = false }

crates/scroll/alloy/evm/src/block/mod.rs

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ use alloy_evm::{
2727
Database, Evm, EvmFactory, FromRecoveredTx, FromTxWithEncoded,
2828
};
2929
use alloy_primitives::{B256, U256};
30+
use reth_scroll_chainspec::{ChainConfig, ScrollChainConfig};
3031
use revm::{
3132
context::{
3233
result::{InvalidTransaction, ResultAndState},
@@ -84,7 +85,7 @@ impl<E, R, Spec> ScrollBlockExecutor<E, R, Spec>
8485
where
8586
E: EvmExt,
8687
R: ScrollReceiptBuilder,
87-
Spec: ScrollHardforks + Clone,
88+
Spec: ScrollHardforks + ChainConfig<Config = ScrollChainConfig> + Clone,
8889
{
8990
/// Creates a new [`ScrollBlockExecutor`].
9091
pub fn new(evm: E, ctx: ScrollBlockExecutionCtx, spec: Spec, receipt_builder: R) -> Self {
@@ -110,7 +111,7 @@ where
110111
+ FromTxWithCompressionInfo<R::Transaction>,
111112
>,
112113
R: ScrollReceiptBuilder<Transaction: Transaction + Encodable2718, Receipt: TxReceipt>,
113-
Spec: ScrollHardforks,
114+
Spec: ScrollHardforks + ChainConfig<Config = ScrollChainConfig>,
114115
{
115116
/// Executes all transactions in a block, applying pre and post execution changes. The provided
116117
/// transaction compression infos are expected to be in the same order as the
@@ -147,7 +148,7 @@ where
147148
Tx: FromRecoveredTx<R::Transaction> + FromTxWithEncoded<R::Transaction>,
148149
>,
149150
R: ScrollReceiptBuilder<Transaction: Transaction + Encodable2718, Receipt: TxReceipt>,
150-
Spec: ScrollHardforks,
151+
Spec: ScrollHardforks + ChainConfig<Config = ScrollChainConfig>,
151152
{
152153
type Transaction = R::Transaction;
153154
type Receipt = R::Receipt;
@@ -269,6 +270,7 @@ where
269270
// disable the base fee and nonce checks for l1 messages.
270271
self.evm.with_base_fee_check(!is_l1_message);
271272
self.evm.with_nonce_check(!is_l1_message);
273+
self.evm.with_l1_data_fee_buffer_check(chain_spec.chain_config().l1_data_fee_buffer_check);
272274

273275
// execute and return the result.
274276
self.evm.transact(&tx).map_err(move |err| BlockExecutionError::evm(err, hash))
@@ -334,6 +336,8 @@ pub trait EvmExt: Evm {
334336
fn with_base_fee_check(&mut self, enabled: bool);
335337
/// Sets whether the evm should enable or disable the nonce checks.
336338
fn with_nonce_check(&mut self, enabled: bool);
339+
/// Sets whether the evm should enable or disable the l1 data fee buffer checks.
340+
fn with_l1_data_fee_buffer_check(&mut self, enabled: bool);
337341
/// Returns the l1 fee for the transaction.
338342
fn l1_fee(&self) -> Option<U256>;
339343
}
@@ -352,6 +356,10 @@ where
352356
self.ctx_mut().cfg.disable_nonce_check = !enabled;
353357
}
354358

359+
fn with_l1_data_fee_buffer_check(&mut self, enabled: bool) {
360+
self.ctx_mut().cfg.require_l1_data_fee_buffer = enabled;
361+
}
362+
355363
fn l1_fee(&self) -> Option<U256> {
356364
let l1_block_info = &self.ctx().chain;
357365
let transaction_rlp_bytes = self.ctx().tx.rlp_bytes.as_ref()?;
@@ -368,8 +376,7 @@ where
368376

369377
/// Scroll block executor factory.
370378
#[derive(Debug, Clone, Default, Copy)]
371-
pub struct ScrollBlockExecutorFactory<R, Spec = ScrollHardfork, P = ScrollDefaultPrecompilesFactory>
372-
{
379+
pub struct ScrollBlockExecutorFactory<R, Spec, P = ScrollDefaultPrecompilesFactory> {
373380
/// Receipt builder.
374381
receipt_builder: R,
375382
/// Chain specification.
@@ -404,7 +411,7 @@ impl<R, Spec, P> ScrollBlockExecutorFactory<R, Spec, P> {
404411
impl<R, Spec, P> BlockExecutorFactory for ScrollBlockExecutorFactory<R, Spec, P>
405412
where
406413
R: ScrollReceiptBuilder<Transaction: Transaction + Encodable2718, Receipt: TxReceipt>,
407-
Spec: ScrollHardforks,
414+
Spec: ScrollHardforks + ChainConfig<Config = ScrollChainConfig> + Clone,
408415
P: ScrollPrecompilesFactory,
409416
ScrollTransactionIntoTxEnv<TxEnv>:
410417
FromRecoveredTx<R::Transaction> + FromTxWithEncoded<R::Transaction>,
@@ -428,6 +435,6 @@ where
428435
DB: Database + 'a,
429436
I: Inspector<<Self::EvmFactory as EvmFactory>::Context<&'a mut State<DB>>> + 'a,
430437
{
431-
ScrollBlockExecutor::new(evm, ctx, &self.spec, &self.receipt_builder)
438+
ScrollBlockExecutor::new(evm, ctx, self.spec.clone(), &self.receipt_builder)
432439
}
433440
}

crates/scroll/chainspec/src/genesis.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,8 @@ pub struct ScrollChainConfig {
126126
/// The L1 configuration.
127127
/// This field encapsulates specific settings and parameters required for L1
128128
pub l1_config: L1Config,
129+
/// Whether the buffer check for L1 data fee is enabled.
130+
pub l1_data_fee_buffer_check: bool,
129131
}
130132

131133
impl ScrollChainConfig {
@@ -141,6 +143,7 @@ impl ScrollChainConfig {
141143
fee_vault_address: Some(SCROLL_FEE_VAULT_ADDRESS),
142144
max_tx_payload_bytes_per_block: MAX_TX_PAYLOAD_BYTES_PER_BLOCK,
143145
l1_config: SCROLL_MAINNET_L1_CONFIG,
146+
l1_data_fee_buffer_check: false,
144147
}
145148
}
146149

@@ -150,6 +153,7 @@ impl ScrollChainConfig {
150153
fee_vault_address: Some(SCROLL_FEE_VAULT_ADDRESS),
151154
max_tx_payload_bytes_per_block: MAX_TX_PAYLOAD_BYTES_PER_BLOCK,
152155
l1_config: SCROLL_SEPOLIA_L1_CONFIG,
156+
l1_data_fee_buffer_check: false,
153157
}
154158
}
155159

@@ -159,6 +163,7 @@ impl ScrollChainConfig {
159163
fee_vault_address: Some(SCROLL_FEE_VAULT_ADDRESS),
160164
max_tx_payload_bytes_per_block: MAX_TX_PAYLOAD_BYTES_PER_BLOCK,
161165
l1_config: SCROLL_DEV_L1_CONFIG,
166+
l1_data_fee_buffer_check: false,
162167
}
163168
}
164169
}
@@ -232,6 +237,7 @@ mod tests {
232237
"scroll": {
233238
"feeVaultAddress": "0x5300000000000000000000000000000000000005",
234239
"maxTxPayloadBytesPerBlock": 122880,
240+
"l1DataFeeBufferCheck": false,
235241
"l1Config": {
236242
"l1ChainId": 1,
237243
"l1MessageQueueAddress": "0x0d7E906BD9cAFa154b048cFa766Cc1E54E39AF9B",
@@ -273,6 +279,7 @@ mod tests {
273279
scroll_chain_address: address!("a13BAF47339d63B743e7Da8741db5456DAc1E556"),
274280
num_l1_messages_per_block: 10,
275281
},
282+
l1_data_fee_buffer_check: false,
276283
},
277284
};
278285
assert_eq!(chain_info, expected);

crates/scroll/chainspec/src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -760,6 +760,7 @@ mod tests {
760760
"scroll": {
761761
"feeVaultAddress": "0x5300000000000000000000000000000000000005",
762762
"maxTxPayloadBytesPerBlock": 122880,
763+
"l1DataFeeBufferCheck": false,
763764
"l1Config": {
764765
"l1ChainId": 1,
765766
"l1MessageQueueAddress": "0x0d7E906BD9cAFa154b048cFa766Cc1E54E39AF9B",
@@ -798,6 +799,7 @@ mod tests {
798799
&serde_json::json!({
799800
"feeVaultAddress": "0x5300000000000000000000000000000000000005",
800801
"maxTxPayloadBytesPerBlock": 122880,
802+
"l1DataFeeBufferCheck": false,
801803
"l1Config": {
802804
"l1ChainId": 1,
803805
"l1MessageQueueAddress": "0x0d7E906BD9cAFa154b048cFa766Cc1E54E39AF9B",
@@ -864,6 +866,7 @@ mod tests {
864866
serde_json::json!({
865867
"feeVaultAddress": "0x5300000000000000000000000000000000000005",
866868
"maxTxPayloadBytesPerBlock": 122880,
869+
"l1DataFeeBufferCheck": false,
867870
"l1Config": {
868871
"l1ChainId": 1,
869872
"l1MessageQueueAddress": "0x0d7E906BD9cAFa154b048cFa766Cc1E54E39AF9B",

crates/scroll/evm/src/lib.rs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ use alloc::sync::Arc;
3131

3232
use alloy_primitives::{Address, BlockNumber, BlockTimestamp};
3333
use reth_primitives_traits::NodePrimitives;
34-
use reth_scroll_chainspec::ScrollChainSpec;
34+
use reth_scroll_chainspec::{ChainConfig, ScrollChainConfig, ScrollChainSpec};
3535
use reth_scroll_primitives::ScrollPrimitives;
3636
use revm_scroll::ScrollSpecId;
3737
pub use scroll_alloy_evm::{
@@ -56,7 +56,9 @@ pub struct ScrollEvmConfig<
5656
_pd: core::marker::PhantomData<N>,
5757
}
5858

59-
impl<ChainSpec: ScrollHardforks> ScrollEvmConfig<ChainSpec> {
59+
impl<ChainSpec: ScrollHardforks + ChainConfig<Config = ScrollChainConfig>>
60+
ScrollEvmConfig<ChainSpec>
61+
{
6062
/// Creates a new [`ScrollEvmConfig`] with the given chain spec for Scroll chains.
6163
pub fn scroll(chain_spec: Arc<ChainSpec>) -> Self {
6264
Self::new(chain_spec, ScrollRethReceiptBuilder::default())
@@ -75,8 +77,12 @@ impl<ChainSpec, N: NodePrimitives, R: Clone, P: Clone> Clone
7577
}
7678
}
7779

78-
impl<ChainSpec: ScrollHardforks, N: NodePrimitives, R, P: Default>
79-
ScrollEvmConfig<ChainSpec, N, R, P>
80+
impl<
81+
ChainSpec: ScrollHardforks + ChainConfig<Config = ScrollChainConfig>,
82+
N: NodePrimitives,
83+
R,
84+
P: Default,
85+
> ScrollEvmConfig<ChainSpec, N, R, P>
8086
{
8187
/// Creates a new [`ScrollEvmConfig`] with the given chain spec.
8288
pub fn new(chain_spec: Arc<ChainSpec>, receipt_builder: R) -> Self {

crates/scroll/node/src/builder/pool.rs

Lines changed: 5 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -24,21 +24,13 @@ use scroll_alloy_hardforks::ScrollHardforks;
2424
pub struct ScrollPoolBuilder<T = reth_scroll_txpool::ScrollPooledTransaction> {
2525
/// Enforced overrides that are applied to the pool config.
2626
pub pool_config_overrides: PoolBuilderConfigOverrides,
27-
/// Require L1 data fee buffer in balance check.
28-
/// When enabled, validates balance >= `L2_cost` + 2*`L1_cost` but only charges `L2_cost` +
29-
/// 1*`L1_cost`.
30-
pub require_l1_data_fee_buffer: bool,
3127
/// Marker for the pooled transaction type.
3228
_pd: core::marker::PhantomData<T>,
3329
}
3430

3531
impl<T> Default for ScrollPoolBuilder<T> {
3632
fn default() -> Self {
37-
Self {
38-
pool_config_overrides: Default::default(),
39-
require_l1_data_fee_buffer: false,
40-
_pd: Default::default(),
41-
}
33+
Self { pool_config_overrides: Default::default(), _pd: Default::default() }
4234
}
4335
}
4436

@@ -51,14 +43,6 @@ impl<T> ScrollPoolBuilder<T> {
5143
self.pool_config_overrides = pool_config_overrides;
5244
self
5345
}
54-
55-
/// Sets the require L1 data fee buffer flag.
56-
/// When enabled, validates balance >= `L2_cost` + 2*`L1_cost` but only charges `L2_cost` +
57-
/// 1*`L1_cost`. This matches geth's block validation behavior.
58-
pub const fn with_require_l1_data_fee_buffer(mut self, require: bool) -> Self {
59-
self.require_l1_data_fee_buffer = require;
60-
self
61-
}
6246
}
6347

6448
impl<Node, T> PoolBuilder<Node> for ScrollPoolBuilder<T>
@@ -73,7 +57,7 @@ where
7357
type Pool = ScrollTransactionPool<Node::Provider, DiskFileBlobStore, T>;
7458

7559
async fn build_pool(self, ctx: &BuilderContext<Node>) -> eyre::Result<Self::Pool> {
76-
let Self { pool_config_overrides, require_l1_data_fee_buffer, .. } = self;
60+
let Self { pool_config_overrides, .. } = self;
7761
let data_dir = ctx.config().datadir();
7862
let blob_store = DiskFileBlobStore::open(data_dir.blobstore(), Default::default())?;
7963

@@ -96,7 +80,9 @@ where
9680
// In --dev mode we can't require gas fees because we're unable to decode
9781
// the L1 block info
9882
.require_l1_data_gas_fee(!ctx.config().dev.dev)
99-
.require_l1_data_fee_buffer(require_l1_data_fee_buffer)
83+
.require_l1_data_fee_buffer(
84+
ctx.chain_spec().chain_config().l1_data_fee_buffer_check,
85+
)
10086
});
10187

10288
let transaction_pool = reth_transaction_pool::Pool::new(
@@ -396,19 +382,6 @@ mod tests {
396382
drop(manager);
397383
}
398384

399-
#[test]
400-
fn test_pool_builder_with_require_l1_data_fee_buffer() {
401-
// Test that the builder method correctly sets the flag
402-
let pool_builder = ScrollPoolBuilder::<ScrollPooledTransaction>::default();
403-
assert!(!pool_builder.require_l1_data_fee_buffer);
404-
405-
let pool_builder = pool_builder.with_require_l1_data_fee_buffer(true);
406-
assert!(pool_builder.require_l1_data_fee_buffer);
407-
408-
let pool_builder = pool_builder.with_require_l1_data_fee_buffer(false);
409-
assert!(!pool_builder.require_l1_data_fee_buffer);
410-
}
411-
412385
#[tokio::test]
413386
async fn test_l1_data_fee_buffer_validation() {
414387
// Test that the L1 data fee buffer feature correctly validates transactions:

0 commit comments

Comments
 (0)