diff --git a/Cargo.lock b/Cargo.lock index 59d91b9bc01..45d6bd3d22c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1944,9 +1944,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.10.1" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" +checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" dependencies = [ "serde", ] @@ -2800,7 +2800,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8d162beedaa69905488a8da94f5ac3edb4dd4788b732fadb7bd120b2625c1976" dependencies = [ "data-encoding", - "syn 2.0.106", + "syn 1.0.109", ] [[package]] diff --git a/crates/scroll/alloy/evm/Cargo.toml b/crates/scroll/alloy/evm/Cargo.toml index 2c61be72148..d3f440fea81 100644 --- a/crates/scroll/alloy/evm/Cargo.toml +++ b/crates/scroll/alloy/evm/Cargo.toml @@ -23,6 +23,7 @@ revm = { workspace = true, default-features = false, features = ["optional_no_ba # scroll revm-scroll = { workspace = true, default-features = false } +reth-scroll-chainspec = { workspace = true, default-features = false } # scroll scroll-alloy-consensus = { workspace = true, default-features = false } diff --git a/crates/scroll/alloy/evm/src/block/mod.rs b/crates/scroll/alloy/evm/src/block/mod.rs index 0c7315c9a97..20f40be0396 100644 --- a/crates/scroll/alloy/evm/src/block/mod.rs +++ b/crates/scroll/alloy/evm/src/block/mod.rs @@ -27,6 +27,7 @@ use alloy_evm::{ Database, Evm, EvmFactory, FromRecoveredTx, FromTxWithEncoded, }; use alloy_primitives::{B256, U256}; +use reth_scroll_chainspec::{ChainConfig, ScrollChainConfig}; use revm::{ context::{ result::{InvalidTransaction, ResultAndState}, @@ -84,7 +85,7 @@ impl ScrollBlockExecutor where E: EvmExt, R: ScrollReceiptBuilder, - Spec: ScrollHardforks + Clone, + Spec: ScrollHardforks + ChainConfig + Clone, { /// Creates a new [`ScrollBlockExecutor`]. pub fn new(evm: E, ctx: ScrollBlockExecutionCtx, spec: Spec, receipt_builder: R) -> Self { @@ -110,7 +111,7 @@ where + FromTxWithCompressionInfo, >, R: ScrollReceiptBuilder, - Spec: ScrollHardforks, + Spec: ScrollHardforks + ChainConfig, { /// Executes all transactions in a block, applying pre and post execution changes. The provided /// transaction compression infos are expected to be in the same order as the @@ -147,7 +148,7 @@ where Tx: FromRecoveredTx + FromTxWithEncoded, >, R: ScrollReceiptBuilder, - Spec: ScrollHardforks, + Spec: ScrollHardforks + ChainConfig, { type Transaction = R::Transaction; type Receipt = R::Receipt; @@ -269,6 +270,7 @@ where // disable the base fee and nonce checks for l1 messages. self.evm.with_base_fee_check(!is_l1_message); self.evm.with_nonce_check(!is_l1_message); + self.evm.with_l1_data_fee_buffer_check(chain_spec.chain_config().l1_data_fee_buffer_check); // execute and return the result. self.evm.transact(&tx).map_err(move |err| BlockExecutionError::evm(err, hash)) @@ -334,6 +336,8 @@ pub trait EvmExt: Evm { fn with_base_fee_check(&mut self, enabled: bool); /// Sets whether the evm should enable or disable the nonce checks. fn with_nonce_check(&mut self, enabled: bool); + /// Sets whether the evm should enable or disable the l1 data fee buffer checks. + fn with_l1_data_fee_buffer_check(&mut self, enabled: bool); /// Returns the l1 fee for the transaction. fn l1_fee(&self) -> Option; } @@ -352,6 +356,10 @@ where self.ctx_mut().cfg.disable_nonce_check = !enabled; } + fn with_l1_data_fee_buffer_check(&mut self, enabled: bool) { + self.ctx_mut().cfg.require_l1_data_fee_buffer = enabled; + } + fn l1_fee(&self) -> Option { let l1_block_info = &self.ctx().chain; let transaction_rlp_bytes = self.ctx().tx.rlp_bytes.as_ref()?; @@ -368,8 +376,7 @@ where /// Scroll block executor factory. #[derive(Debug, Clone, Default, Copy)] -pub struct ScrollBlockExecutorFactory -{ +pub struct ScrollBlockExecutorFactory { /// Receipt builder. receipt_builder: R, /// Chain specification. @@ -404,7 +411,7 @@ impl ScrollBlockExecutorFactory { impl BlockExecutorFactory for ScrollBlockExecutorFactory where R: ScrollReceiptBuilder, - Spec: ScrollHardforks, + Spec: ScrollHardforks + ChainConfig + Clone, P: ScrollPrecompilesFactory, ScrollTransactionIntoTxEnv: FromRecoveredTx + FromTxWithEncoded, @@ -428,6 +435,6 @@ where DB: Database + 'a, I: Inspector<::Context<&'a mut State>> + 'a, { - ScrollBlockExecutor::new(evm, ctx, &self.spec, &self.receipt_builder) + ScrollBlockExecutor::new(evm, ctx, self.spec.clone(), &self.receipt_builder) } } diff --git a/crates/scroll/chainspec/src/genesis.rs b/crates/scroll/chainspec/src/genesis.rs index 747e2ddd1b3..c497b240b9c 100644 --- a/crates/scroll/chainspec/src/genesis.rs +++ b/crates/scroll/chainspec/src/genesis.rs @@ -126,6 +126,8 @@ pub struct ScrollChainConfig { /// The L1 configuration. /// This field encapsulates specific settings and parameters required for L1 pub l1_config: L1Config, + /// Whether the buffer check for L1 data fee is enabled. + pub l1_data_fee_buffer_check: bool, } impl ScrollChainConfig { @@ -141,6 +143,7 @@ impl ScrollChainConfig { fee_vault_address: Some(SCROLL_FEE_VAULT_ADDRESS), max_tx_payload_bytes_per_block: MAX_TX_PAYLOAD_BYTES_PER_BLOCK, l1_config: SCROLL_MAINNET_L1_CONFIG, + l1_data_fee_buffer_check: false, } } @@ -150,6 +153,7 @@ impl ScrollChainConfig { fee_vault_address: Some(SCROLL_FEE_VAULT_ADDRESS), max_tx_payload_bytes_per_block: MAX_TX_PAYLOAD_BYTES_PER_BLOCK, l1_config: SCROLL_SEPOLIA_L1_CONFIG, + l1_data_fee_buffer_check: false, } } @@ -159,6 +163,7 @@ impl ScrollChainConfig { fee_vault_address: Some(SCROLL_FEE_VAULT_ADDRESS), max_tx_payload_bytes_per_block: MAX_TX_PAYLOAD_BYTES_PER_BLOCK, l1_config: SCROLL_DEV_L1_CONFIG, + l1_data_fee_buffer_check: false, } } } @@ -232,6 +237,7 @@ mod tests { "scroll": { "feeVaultAddress": "0x5300000000000000000000000000000000000005", "maxTxPayloadBytesPerBlock": 122880, + "l1DataFeeBufferCheck": false, "l1Config": { "l1ChainId": 1, "l1MessageQueueAddress": "0x0d7E906BD9cAFa154b048cFa766Cc1E54E39AF9B", @@ -273,6 +279,7 @@ mod tests { scroll_chain_address: address!("a13BAF47339d63B743e7Da8741db5456DAc1E556"), num_l1_messages_per_block: 10, }, + l1_data_fee_buffer_check: false, }, }; assert_eq!(chain_info, expected); diff --git a/crates/scroll/chainspec/src/lib.rs b/crates/scroll/chainspec/src/lib.rs index 4f072754568..88755ff01dd 100644 --- a/crates/scroll/chainspec/src/lib.rs +++ b/crates/scroll/chainspec/src/lib.rs @@ -760,6 +760,7 @@ mod tests { "scroll": { "feeVaultAddress": "0x5300000000000000000000000000000000000005", "maxTxPayloadBytesPerBlock": 122880, + "l1DataFeeBufferCheck": false, "l1Config": { "l1ChainId": 1, "l1MessageQueueAddress": "0x0d7E906BD9cAFa154b048cFa766Cc1E54E39AF9B", @@ -798,6 +799,7 @@ mod tests { &serde_json::json!({ "feeVaultAddress": "0x5300000000000000000000000000000000000005", "maxTxPayloadBytesPerBlock": 122880, + "l1DataFeeBufferCheck": false, "l1Config": { "l1ChainId": 1, "l1MessageQueueAddress": "0x0d7E906BD9cAFa154b048cFa766Cc1E54E39AF9B", @@ -864,6 +866,7 @@ mod tests { serde_json::json!({ "feeVaultAddress": "0x5300000000000000000000000000000000000005", "maxTxPayloadBytesPerBlock": 122880, + "l1DataFeeBufferCheck": false, "l1Config": { "l1ChainId": 1, "l1MessageQueueAddress": "0x0d7E906BD9cAFa154b048cFa766Cc1E54E39AF9B", diff --git a/crates/scroll/evm/src/lib.rs b/crates/scroll/evm/src/lib.rs index 745b31c9016..8e709ed5260 100644 --- a/crates/scroll/evm/src/lib.rs +++ b/crates/scroll/evm/src/lib.rs @@ -31,7 +31,7 @@ use alloc::sync::Arc; use alloy_primitives::{Address, BlockNumber, BlockTimestamp}; use reth_primitives_traits::NodePrimitives; -use reth_scroll_chainspec::ScrollChainSpec; +use reth_scroll_chainspec::{ChainConfig, ScrollChainConfig, ScrollChainSpec}; use reth_scroll_primitives::ScrollPrimitives; use revm_scroll::ScrollSpecId; pub use scroll_alloy_evm::{ @@ -56,7 +56,9 @@ pub struct ScrollEvmConfig< _pd: core::marker::PhantomData, } -impl ScrollEvmConfig { +impl> + ScrollEvmConfig +{ /// Creates a new [`ScrollEvmConfig`] with the given chain spec for Scroll chains. pub fn scroll(chain_spec: Arc) -> Self { Self::new(chain_spec, ScrollRethReceiptBuilder::default()) @@ -75,8 +77,12 @@ impl Clone } } -impl - ScrollEvmConfig +impl< + ChainSpec: ScrollHardforks + ChainConfig, + N: NodePrimitives, + R, + P: Default, + > ScrollEvmConfig { /// Creates a new [`ScrollEvmConfig`] with the given chain spec. pub fn new(chain_spec: Arc, receipt_builder: R) -> Self { diff --git a/crates/scroll/node/src/builder/pool.rs b/crates/scroll/node/src/builder/pool.rs index 35950076bb4..9dcbc19fbb3 100644 --- a/crates/scroll/node/src/builder/pool.rs +++ b/crates/scroll/node/src/builder/pool.rs @@ -24,21 +24,13 @@ use scroll_alloy_hardforks::ScrollHardforks; pub struct ScrollPoolBuilder { /// Enforced overrides that are applied to the pool config. pub pool_config_overrides: PoolBuilderConfigOverrides, - /// Require L1 data fee buffer in balance check. - /// When enabled, validates balance >= `L2_cost` + 2*`L1_cost` but only charges `L2_cost` + - /// 1*`L1_cost`. - pub require_l1_data_fee_buffer: bool, /// Marker for the pooled transaction type. _pd: core::marker::PhantomData, } impl Default for ScrollPoolBuilder { fn default() -> Self { - Self { - pool_config_overrides: Default::default(), - require_l1_data_fee_buffer: false, - _pd: Default::default(), - } + Self { pool_config_overrides: Default::default(), _pd: Default::default() } } } @@ -51,14 +43,6 @@ impl ScrollPoolBuilder { self.pool_config_overrides = pool_config_overrides; self } - - /// Sets the require L1 data fee buffer flag. - /// When enabled, validates balance >= `L2_cost` + 2*`L1_cost` but only charges `L2_cost` + - /// 1*`L1_cost`. This matches geth's block validation behavior. - pub const fn with_require_l1_data_fee_buffer(mut self, require: bool) -> Self { - self.require_l1_data_fee_buffer = require; - self - } } impl PoolBuilder for ScrollPoolBuilder @@ -73,7 +57,7 @@ where type Pool = ScrollTransactionPool; async fn build_pool(self, ctx: &BuilderContext) -> eyre::Result { - let Self { pool_config_overrides, require_l1_data_fee_buffer, .. } = self; + let Self { pool_config_overrides, .. } = self; let data_dir = ctx.config().datadir(); let blob_store = DiskFileBlobStore::open(data_dir.blobstore(), Default::default())?; @@ -96,7 +80,9 @@ where // In --dev mode we can't require gas fees because we're unable to decode // the L1 block info .require_l1_data_gas_fee(!ctx.config().dev.dev) - .require_l1_data_fee_buffer(require_l1_data_fee_buffer) + .require_l1_data_fee_buffer( + ctx.chain_spec().chain_config().l1_data_fee_buffer_check, + ) }); let transaction_pool = reth_transaction_pool::Pool::new( @@ -396,19 +382,6 @@ mod tests { drop(manager); } - #[test] - fn test_pool_builder_with_require_l1_data_fee_buffer() { - // Test that the builder method correctly sets the flag - let pool_builder = ScrollPoolBuilder::::default(); - assert!(!pool_builder.require_l1_data_fee_buffer); - - let pool_builder = pool_builder.with_require_l1_data_fee_buffer(true); - assert!(pool_builder.require_l1_data_fee_buffer); - - let pool_builder = pool_builder.with_require_l1_data_fee_buffer(false); - assert!(!pool_builder.require_l1_data_fee_buffer); - } - #[tokio::test] async fn test_l1_data_fee_buffer_validation() { // Test that the L1 data fee buffer feature correctly validates transactions: