Skip to content

Commit 6b15eb3

Browse files
committed
Merge branch 'scroll' into feat-forward-tx-to-sequencer
2 parents 499e9ae + ea01b62 commit 6b15eb3

File tree

32 files changed

+653
-199
lines changed

32 files changed

+653
-199
lines changed

Cargo.lock

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

crates/ethereum/node/tests/e2e/pool.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ async fn maintain_txpool_stale_eviction() -> eyre::Result<()> {
4545
.build(),
4646
);
4747
let node_config = NodeConfig::test()
48-
.with_chain(chain_spec)
48+
.with_chain(chain_spec.clone())
4949
.with_unused_ports()
5050
.with_rpc(RpcServerArgs::default().with_unused_ports().with_http());
5151
let NodeHandle { node, node_exit_future: _ } = NodeBuilder::new(node_config.clone())
@@ -67,6 +67,7 @@ async fn maintain_txpool_stale_eviction() -> eyre::Result<()> {
6767
"txpool maintenance task",
6868
reth_transaction_pool::maintain::maintain_transaction_pool_future(
6969
node.inner.provider.clone(),
70+
chain_spec,
7071
txpool.clone(),
7172
node.inner.provider.clone().canonical_state_stream(),
7273
executor.clone(),
@@ -120,7 +121,7 @@ async fn maintain_txpool_reorg() -> eyre::Result<()> {
120121
);
121122
let genesis_hash = chain_spec.genesis_hash();
122123
let node_config = NodeConfig::test()
123-
.with_chain(chain_spec)
124+
.with_chain(chain_spec.clone())
124125
.with_unused_ports()
125126
.with_rpc(RpcServerArgs::default().with_unused_ports().with_http());
126127
let NodeHandle { node, node_exit_future: _ } = NodeBuilder::new(node_config.clone())
@@ -139,6 +140,7 @@ async fn maintain_txpool_reorg() -> eyre::Result<()> {
139140
"txpool maintenance task",
140141
reth_transaction_pool::maintain::maintain_transaction_pool_future(
141142
node.inner.provider.clone(),
143+
chain_spec,
142144
txpool.clone(),
143145
node.inner.provider.clone().canonical_state_stream(),
144146
executor.clone(),
@@ -269,6 +271,7 @@ async fn maintain_txpool_commit() -> eyre::Result<()> {
269271
"txpool maintenance task",
270272
reth_transaction_pool::maintain::maintain_transaction_pool_future(
271273
node.inner.provider.clone(),
274+
MAINNET.clone(),
272275
txpool.clone(),
273276
node.inner.provider.clone().canonical_state_stream(),
274277
executor.clone(),

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
11
//! Pool component for the node builder.
22
3+
use crate::{BuilderContext, FullNodeTypes};
4+
35
use alloy_primitives::Address;
46
use reth_chain_state::CanonStateSubscriptions;
7+
use reth_chainspec::ChainSpecProvider;
58
use reth_node_api::TxTy;
69
use reth_transaction_pool::{
710
blobstore::DiskFileBlobStore, CoinbaseTipOrdering, PoolConfig, PoolTransaction, SubPoolLimit,
811
TransactionPool, TransactionValidationTaskExecutor, TransactionValidator,
912
};
1013
use std::{collections::HashSet, future::Future};
1114

12-
use crate::{BuilderContext, FullNodeTypes};
13-
1415
/// A type that knows how to build the transaction pool.
1516
pub trait PoolBuilder<Node: FullNodeTypes>: Send {
1617
/// The transaction pool to build.
@@ -241,11 +242,13 @@ where
241242
{
242243
let chain_events = ctx.provider().canonical_state_stream();
243244
let client = ctx.provider().clone();
245+
let chain_spec = client.chain_spec();
244246

245247
ctx.task_executor().spawn_critical(
246248
"txpool maintenance task",
247249
reth_transaction_pool::maintain::maintain_transaction_pool_future(
248250
client,
251+
chain_spec,
249252
pool,
250253
chain_events,
251254
ctx.task_executor().clone(),

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

Lines changed: 70 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,17 +42,17 @@ const FEYNMAN_L1_GAS_PRICE_ORACLE_STORAGE: [(U256, U256); 3] = [
4242
pub(super) fn apply_feynman_hard_fork<DB: Database>(
4343
state: &mut State<DB>,
4444
) -> Result<(), DB::Error> {
45-
let oracle = state.load_cache_account(L1_GAS_PRICE_ORACLE_ADDRESS)?;
46-
4745
// No-op if already applied.
4846
// Note: This requires a storage read for every Feynman block, and it means this
4947
// read needs to be included in the execution witness. Unfortunately, there is no
5048
// other reliable way to apply the change only at the transition block, since
5149
// `ScrollBlockExecutor` does not have access to the parent timestamp.
52-
if matches!(oracle.storage_slot(IS_FEYNMAN_SLOT), Some(val) if val == IS_FEYNMAN) {
50+
if state.storage(L1_GAS_PRICE_ORACLE_ADDRESS, IS_FEYNMAN_SLOT)? == IS_FEYNMAN {
5351
return Ok(())
5452
}
5553

54+
let oracle = state.load_cache_account(L1_GAS_PRICE_ORACLE_ADDRESS)?;
55+
5656
// compute the code hash
5757
let bytecode = Bytecode::new_raw(FEYNMAN_L1_GAS_PRICE_ORACLE_BYTECODE);
5858
let code_hash = bytecode.hash_slow();
@@ -94,7 +94,7 @@ mod tests {
9494
use revm::{
9595
database::{
9696
states::{bundle_state::BundleRetention, plain_account::PlainStorage, StorageSlot},
97-
EmptyDB, State,
97+
CacheDB, EmptyDB, State,
9898
},
9999
primitives::{keccak256, U256},
100100
state::{AccountInfo, Bytecode},
@@ -195,4 +195,70 @@ mod tests {
195195

196196
Ok(())
197197
}
198+
199+
#[test]
200+
fn test_apply_feynman_fork_only_once() -> eyre::Result<()> {
201+
let bytecode = Bytecode::new_raw(FEYNMAN_L1_GAS_PRICE_ORACLE_BYTECODE);
202+
203+
let oracle_account = AccountInfo {
204+
code_hash: bytecode.hash_slow(),
205+
code: Some(bytecode),
206+
..Default::default()
207+
};
208+
209+
let oracle_storage = PlainStorage::from_iter([
210+
// owner
211+
(U256::ZERO, U256::from_str("0x13d24a7ff6f5ec5ff0e9c40fc3b8c9c01c65437b")?),
212+
// l1BaseFee
213+
(U256::from(1), U256::from(0x15f50e5e)),
214+
// overhead
215+
(U256::from(2), U256::from(0x38)),
216+
// scalar
217+
(U256::from(3), U256::from(0x3e95ba80)),
218+
// whitelist
219+
(U256::from(4), U256::from_str("0x5300000000000000000000000000000000000003")?),
220+
// l1BlobBaseFee
221+
(U256::from(5), U256::from(0x15f50e5e)),
222+
// commitScalar
223+
(U256::from(6), U256::from(0x3e95ba80)),
224+
// blobScalar
225+
(U256::from(7), U256::from(0x3e95ba80)),
226+
// isCurie
227+
(U256::from(8), U256::from(1)),
228+
// penaltyThreshold
229+
(U256::from(9), U256::from(1_100_000_000u64)),
230+
// penaltyFactor
231+
(U256::from(10), U256::from(3_000_000_000u64)),
232+
// isFeynman
233+
(U256::from(11), U256::from(1)),
234+
]);
235+
236+
// init state,
237+
// we write to db directly to make sure we do not have account storage in cache
238+
let mut db = CacheDB::new(EmptyDB::default());
239+
240+
db.insert_account_info(L1_GAS_PRICE_ORACLE_ADDRESS, oracle_account);
241+
242+
for (slot, value) in oracle_storage {
243+
db.insert_account_storage(L1_GAS_PRICE_ORACLE_ADDRESS, slot, value).unwrap();
244+
}
245+
246+
let mut state =
247+
State::builder().with_database(db).with_bundle_update().without_state_clear().build();
248+
249+
// make sure account is in cache
250+
state.load_cache_account(L1_GAS_PRICE_ORACLE_ADDRESS)?;
251+
252+
// apply feynman fork
253+
apply_feynman_hard_fork(&mut state)?;
254+
255+
// merge transitions
256+
state.merge_transitions(BundleRetention::Reverts);
257+
let bundle = state.take_bundle();
258+
259+
// isFeynman is already set, apply_feynman_hard_fork should be a no-op
260+
assert_eq!(bundle.state.get(&L1_GAS_PRICE_ORACLE_ADDRESS), None);
261+
262+
Ok(())
263+
}
198264
}

crates/scroll/alloy/evm/src/tx/compression.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,15 @@ use alloy_eips::{Encodable2718, Typed2718};
55
use alloy_evm::{IntoTxEnv, RecoveredTx};
66
use alloy_primitives::{Address, Bytes, TxKind, U256};
77
use revm::context::TxEnv;
8-
use revm_scroll::l1block::TX_L1_FEE_PRECISION_U256;
98
use scroll_alloy_consensus::{ScrollTxEnvelope, TxL1Message};
109
pub use zstd_compression::compute_compression_ratio;
1110

1211
#[cfg(feature = "zstd_compression")]
1312
mod zstd_compression {
1413
use super::*;
1514
use std::io::Write;
15+
16+
use revm_scroll::l1block::TX_L1_FEE_PRECISION_U256;
1617
use zstd::{
1718
stream::Encoder,
1819
zstd_safe::{CParameter, ParamSwitch},

crates/scroll/alloy/hardforks/src/hardfork.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ impl ScrollHardfork {
3737
(Self::Euclid, ForkCondition::Timestamp(1744815600)),
3838
(Self::EuclidV2, ForkCondition::Timestamp(1745305200)),
3939
// TODO: update
40-
(Self::Feynman, ForkCondition::Timestamp(u64::MAX)),
40+
(Self::Feynman, ForkCondition::Timestamp(6000000000)),
4141
]
4242
}
4343

@@ -51,8 +51,7 @@ impl ScrollHardfork {
5151
(Self::DarwinV2, ForkCondition::Timestamp(1724832000)),
5252
(Self::Euclid, ForkCondition::Timestamp(1741680000)),
5353
(Self::EuclidV2, ForkCondition::Timestamp(1741852800)),
54-
// TODO: update
55-
(Self::Feynman, ForkCondition::Timestamp(u64::MAX)),
54+
(Self::Feynman, ForkCondition::Timestamp(1753167600)),
5655
]
5756
}
5857
}

crates/scroll/alloy/rpc-types/src/transaction.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ impl Transaction {
3535
// For l1 messages, we set the `gasPrice` field to 0 in rpc
3636
0
3737
} else {
38+
// TODO: should we get the pool base fee in the case where the transaction is a pending
39+
// transaction here?
3840
base_fee
3941
.map(|base_fee| {
4042
tx.effective_tip_per_gas(base_fee).unwrap_or_default() + base_fee as u128

crates/scroll/chainspec/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ serde_json = { workspace = true, default-features = false }
3636
serde = { workspace = true, default-features = false, features = ["derive"] }
3737

3838
# misc
39+
auto_impl.workspace = true
3940
derive_more = { workspace = true, default-features = false }
4041
once_cell = { workspace = true, default-features = false }
4142

crates/scroll/chainspec/res/genesis/dev.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
"timestamp": "0x6490fdd2",
44
"extraData": "0x",
55
"gasLimit": "0x1c9c380",
6+
"baseFeePerGas": "0x0",
67
"difficulty": "0x0",
78
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
89
"coinbase": "0x0000000000000000000000000000000000000000",
@@ -83,4 +84,4 @@
8384
"number": "0x0",
8485
"gasUsed": "0x0",
8586
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000"
86-
}
87+
}

crates/scroll/chainspec/src/constants.rs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,24 @@
11
use crate::genesis::L1Config;
2+
use alloy_eips::eip1559::BaseFeeParams;
23
use alloy_primitives::{address, b256, Address, B256};
34

45
/// The transaction fee recipient on the L2.
56
pub const SCROLL_FEE_VAULT_ADDRESS: Address = address!("5300000000000000000000000000000000000005");
67

8+
/// The system contract on L2 mainnet.
9+
pub const SCROLL_MAINNET_L2_SYSTEM_CONFIG_CONTRACT_ADDRESS: Address =
10+
address!("331A873a2a85219863d80d248F9e2978fE88D0Ea");
11+
712
/// The L1 message queue address for Scroll mainnet.
813
/// <https://etherscan.io/address/0x0d7E906BD9cAFa154b048cFa766Cc1E54E39AF9B>.
914
pub const SCROLL_MAINNET_L1_MESSAGE_QUEUE_ADDRESS: Address =
1015
address!("0d7E906BD9cAFa154b048cFa766Cc1E54E39AF9B");
1116

17+
/// The L1 message queue v2 address for Scroll mainnet.
18+
/// <https://etherscan.io/address/0x56971da63A3C0205184FEF096E9ddFc7A8C2D18a>.
19+
pub const SCROLL_MAINNET_L1_MESSAGE_QUEUE_V2_ADDRESS: Address =
20+
address!("56971da63A3C0205184FEF096E9ddFc7A8C2D18a");
21+
1222
/// The L1 proxy address for Scroll mainnet.
1323
/// <https://etherscan.io/address/0xa13BAF47339d63B743e7Da8741db5456DAc1E556>.
1424
pub const SCROLL_MAINNET_L1_PROXY_ADDRESS: Address =
@@ -21,6 +31,8 @@ pub const SCROLL_MAINNET_MAX_L1_MESSAGES: u64 = 10;
2131
pub const SCROLL_MAINNET_L1_CONFIG: L1Config = L1Config {
2232
l1_chain_id: alloy_chains::NamedChain::Mainnet as u64,
2333
l1_message_queue_address: SCROLL_MAINNET_L1_MESSAGE_QUEUE_ADDRESS,
34+
l1_message_queue_v2_address: SCROLL_MAINNET_L1_MESSAGE_QUEUE_V2_ADDRESS,
35+
l2_system_config_address: SCROLL_MAINNET_L2_SYSTEM_CONFIG_CONTRACT_ADDRESS,
2436
scroll_chain_address: SCROLL_MAINNET_L1_PROXY_ADDRESS,
2537
num_l1_messages_per_block: SCROLL_MAINNET_MAX_L1_MESSAGES,
2638
};
@@ -29,11 +41,20 @@ pub const SCROLL_MAINNET_L1_CONFIG: L1Config = L1Config {
2941
pub const SCROLL_MAINNET_GENESIS_HASH: B256 =
3042
b256!("bbc05efd412b7cd47a2ed0e5ddfcf87af251e414ea4c801d78b6784513180a80");
3143

44+
/// The system contract on L2 sepolia.
45+
pub const SCROLL_SEPOLIA_L2_SYSTEM_CONFIG_CONTRACT_ADDRESS: Address =
46+
address!("F444cF06A3E3724e20B35c2989d3942ea8b59124");
47+
3248
/// The L1 message queue address for Scroll sepolia.
3349
/// <https://sepolia.etherscan.io/address/0xF0B2293F5D834eAe920c6974D50957A1732de763>.
3450
pub const SCROLL_SEPOLIA_L1_MESSAGE_QUEUE_ADDRESS: Address =
3551
address!("F0B2293F5D834eAe920c6974D50957A1732de763");
3652

53+
/// The L1 message queue address v2 for Scroll sepolia.
54+
/// <https://sepolia.etherscan.io/address/0xA0673eC0A48aa924f067F1274EcD281A10c5f19F>.
55+
pub const SCROLL_SEPOLIA_L1_MESSAGE_QUEUE_V2_ADDRESS: Address =
56+
address!("A0673eC0A48aa924f067F1274EcD281A10c5f19F");
57+
3758
/// The L1 proxy address for Scroll sepolia.
3859
/// <https://sepolia.etherscan.io/address/0x2D567EcE699Eabe5afCd141eDB7A4f2D0D6ce8a0>
3960
pub const SCROLL_SEPOLIA_L1_PROXY_ADDRESS: Address =
@@ -46,14 +67,24 @@ pub const SCROLL_SEPOLIA_MAX_L1_MESSAGES: u64 = 10;
4667
pub const SCROLL_SEPOLIA_L1_CONFIG: L1Config = L1Config {
4768
l1_chain_id: alloy_chains::NamedChain::Sepolia as u64,
4869
l1_message_queue_address: SCROLL_SEPOLIA_L1_MESSAGE_QUEUE_ADDRESS,
70+
l1_message_queue_v2_address: SCROLL_SEPOLIA_L1_MESSAGE_QUEUE_V2_ADDRESS,
71+
l2_system_config_address: SCROLL_SEPOLIA_L2_SYSTEM_CONFIG_CONTRACT_ADDRESS,
4972
scroll_chain_address: SCROLL_SEPOLIA_L1_PROXY_ADDRESS,
5073
num_l1_messages_per_block: SCROLL_SEPOLIA_MAX_L1_MESSAGES,
5174
};
5275

76+
/// The system contract on devnet.
77+
pub const SCROLL_DEV_L2_SYSTEM_CONFIG_CONTRACT_ADDRESS: Address =
78+
address!("0000000000000000000000000000000000000000");
79+
5380
/// The L1 message queue address for Scroll dev.
5481
pub const SCROLL_DEV_L1_MESSAGE_QUEUE_ADDRESS: Address =
5582
address!("0000000000000000000000000000000000000000");
5683

84+
/// The L1 message queue v2 address for Scroll dev.
85+
pub const SCROLL_DEV_L1_MESSAGE_QUEUE_V2_ADDRESS: Address =
86+
address!("0000000000000000000000000000000000000000");
87+
5788
/// The L1 proxy address for Scroll dev.
5889
pub const SCROLL_DEV_L1_PROXY_ADDRESS: Address =
5990
address!("0000000000000000000000000000000000000000");
@@ -65,10 +96,24 @@ pub const SCROLL_DEV_MAX_L1_MESSAGES: u64 = 10;
6596
pub const SCROLL_DEV_L1_CONFIG: L1Config = L1Config {
6697
l1_chain_id: alloy_chains::NamedChain::Goerli as u64,
6798
l1_message_queue_address: SCROLL_DEV_L1_MESSAGE_QUEUE_ADDRESS,
99+
l1_message_queue_v2_address: SCROLL_DEV_L1_MESSAGE_QUEUE_V2_ADDRESS,
68100
scroll_chain_address: SCROLL_DEV_L1_PROXY_ADDRESS,
101+
l2_system_config_address: SCROLL_DEV_L2_SYSTEM_CONFIG_CONTRACT_ADDRESS,
69102
num_l1_messages_per_block: SCROLL_DEV_MAX_L1_MESSAGES,
70103
};
71104

72105
/// The Scroll Sepolia genesis hash
73106
pub const SCROLL_SEPOLIA_GENESIS_HASH: B256 =
74107
b256!("aa62d1a8b2bffa9e5d2368b63aae0d98d54928bd713125e3fd9e5c896c68592c");
108+
109+
/// The base fee params for Feynman.
110+
pub const SCROLL_BASE_FEE_PARAMS_FEYNMAN: BaseFeeParams = BaseFeeParams::new(
111+
SCROLL_EIP1559_BASE_FEE_MAX_CHANGE_DENOMINATOR_FEYNMAN,
112+
SCROLL_EIP1559_DEFAULT_ELASTICITY_MULTIPLIER_FEYNMAN,
113+
);
114+
115+
/// The scroll EIP1559 max change denominator for Feynman.
116+
pub const SCROLL_EIP1559_BASE_FEE_MAX_CHANGE_DENOMINATOR_FEYNMAN: u128 = 8;
117+
118+
/// The scroll EIP1559 default elasticity multiplier for Feynman.
119+
pub const SCROLL_EIP1559_DEFAULT_ELASTICITY_MULTIPLIER_FEYNMAN: u128 = 2;

0 commit comments

Comments
 (0)