Skip to content

Commit a8d2ec4

Browse files
avilagaston9edg-lVolodymyrBgtomip01jrchatruc
authored
feat(l2): commit blocks in batches (#2397)
**Motivation** To reduce the number of times we go to the L1 to commit/verify blocks. **Description** - Modifies `l1_committer` to merge as many blocks as possible into a single `StateDiff` before committing, limited by the blob size. - Modifies `StateDiff` to now contain both the resulting `AccountUpdates` from executing all blocks in the batch and the header of the last block. - Adapts contracts to use `batchNumbers` instead of `blockNumbers`. - Adds a new RPC endpoint, `ethrex_getWithdrawalProof`, which returns all necessary data to claim an L1 withdrawal for a given L2 withdrawal transaction hash. - Implements `apply_account_updates` for the `ExecutionDB` to prepare the db for executing the next block in the batch. - Adds a `L2/storage` with the following tables: - `block_number` => `batch_number`: Maps block numbers to batches (used by the endpoint to locate a withdrawal's batch). - `batch_number` => `Vec<block_number>`: Lists all block numbers included in a given batch. - `batch_number` => `withdrawal_hashes`: Stores withdrawal hashes per batch (used to construct merkle proofs). Closes None Created issues: - #2563 - #2578 - #2579 - #2617 --------- Co-authored-by: Edgar <git@edgl.dev> Co-authored-by: VolodymyrBg <aqdrgg19@gmail.com> Co-authored-by: Tomás Paradelo <112426153+tomip01@users.noreply.github.com> Co-authored-by: Javier Rodríguez Chatruc <49622509+jrchatruc@users.noreply.github.com> Co-authored-by: Mauro Toscano <12560266+MauroToscano@users.noreply.github.com> Co-authored-by: Martin Paulucci <martin.c.paulucci@gmail.com> Co-authored-by: Jeremías Salomón <48994069+JereSalo@users.noreply.github.com> Co-authored-by: Lucas Fiegl <iovoid@users.noreply.github.com> Co-authored-by: Cypher Pepe <125112044+cypherpepe@users.noreply.github.com>
1 parent b421c5f commit a8d2ec4

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

86 files changed

+2476
-1614
lines changed

Cargo.lock

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

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ members = [
1717
"crates/l2/prover",
1818
"crates/l2/prover/bench",
1919
"crates/l2/sdk",
20+
"crates/l2/storage",
2021
"crates/networking/p2p",
2122
"crates/networking/rpc",
2223
"crates/storage",
@@ -49,6 +50,7 @@ ethrex-rlp = { path = "./crates/common/rlp" }
4950
ethrex-l2 = { path = "./crates/l2" }
5051
ethrex-sdk = { path = "./crates/l2/sdk" }
5152
ethrex-prover = { path = "./crates/l2/prover" }
53+
ethrex-storage-rollup = { path = "./crates/l2/storage" }
5254

5355
tracing = { version = "0.1", features = ["log"] }
5456
tracing-subscriber = { version = "0.3.0", features = ["env-filter"] }

cmd/ethrex/Cargo.toml

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ ethrex-p2p.workspace = true
1313
ethrex-storage.workspace = true
1414
ethrex-vm.workspace = true
1515
ethrex-rlp.workspace = true
16+
ethrex-storage-rollup = { workspace = true, optional = true }
1617
ethrex-l2 = { workspace = true, optional = true }
1718

1819
bytes.workspace = true
@@ -63,12 +64,15 @@ libmdbx = ["ethrex-storage/libmdbx"]
6364
redb = ["dep:redb", "ethrex-storage/redb"]
6465
blst = ["ethrex-vm/blst"]
6566
l2 = [
66-
"dep:ethrex-l2",
67-
"ethrex-vm/l2",
68-
"ethrex-blockchain/l2",
69-
"ethrex-rpc/l2",
70-
"dep:secp256k1",
67+
"dep:ethrex-l2",
68+
"ethrex-vm/l2",
69+
"ethrex-blockchain/l2",
70+
"ethrex-rpc/l2",
71+
"dep:secp256k1",
72+
"ethrex-storage-rollup"
7173
]
74+
rollup_storage_libmdbx = ["ethrex-storage-rollup/libmdbx"]
75+
rollup_storage_redb = ["ethrex-storage-rollup/redb"]
7276
based = ["l2", "ethrex-rpc/based"]
7377

7478

cmd/ethrex/ethrex.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ use tracing::info;
1414

1515
#[cfg(any(feature = "l2", feature = "based"))]
1616
use ethrex::l2::L2Options;
17+
#[cfg(feature = "l2")]
18+
use ethrex_storage_rollup::StoreRollup;
1719

1820
#[tokio::main]
1921
async fn main() -> eyre::Result<()> {
@@ -55,6 +57,8 @@ async fn main() -> eyre::Result<()> {
5557
blockchain.clone(),
5658
cancel_token.clone(),
5759
tracker.clone(),
60+
#[cfg(feature = "l2")]
61+
StoreRollup::default(),
5862
)
5963
.await;
6064

cmd/ethrex/initializers.rs

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ use crate::l2::L2Options;
3333
use ::{
3434
ethrex_common::Address,
3535
ethrex_l2::utils::config::{read_env_file_by_config, ConfigMode},
36+
ethrex_storage_rollup::{EngineTypeRollup, StoreRollup},
3637
secp256k1::SecretKey,
3738
};
3839

@@ -79,7 +80,6 @@ pub async fn init_store(data_dir: &str, network: &str) -> Store {
7980
} else if #[cfg(feature = "libmdbx")] {
8081
let engine_type = EngineType::Libmdbx;
8182
} else {
82-
let engine_type = EngineType::InMemory;
8383
error!("No database specified. The feature flag `redb` or `libmdbx` should've been set while building.");
8484
panic!("Specify the desired database engine.");
8585
}
@@ -94,6 +94,26 @@ pub async fn init_store(data_dir: &str, network: &str) -> Store {
9494
store
9595
}
9696

97+
#[cfg(feature = "l2")]
98+
pub async fn init_rollup_store(data_dir: &str) -> StoreRollup {
99+
cfg_if::cfg_if! {
100+
if #[cfg(feature = "rollup_storage_redb")] {
101+
let engine_type = EngineTypeRollup::RedB;
102+
} else if #[cfg(feature = "rollup_storage_libmdbx")] {
103+
let engine_type = EngineTypeRollup::Libmdbx;
104+
} else {
105+
let engine_type = EngineTypeRollup::InMemory;
106+
}
107+
}
108+
let rollup_store =
109+
StoreRollup::new(data_dir, engine_type).expect("Failed to create StoreRollup");
110+
rollup_store
111+
.init()
112+
.await
113+
.expect("Failed to init rollup store");
114+
rollup_store
115+
}
116+
97117
pub fn init_blockchain(evm_engine: EvmEngine, store: Store) -> Arc<Blockchain> {
98118
Blockchain::new(evm_engine, store).into()
99119
}
@@ -109,6 +129,7 @@ pub async fn init_rpc_api(
109129
blockchain: Arc<Blockchain>,
110130
cancel_token: CancellationToken,
111131
tracker: TaskTracker,
132+
#[cfg(feature = "l2")] rollup_store: StoreRollup,
112133
) {
113134
let enr_seq = std::time::SystemTime::now()
114135
.duration_since(std::time::UNIX_EPOCH)
@@ -146,6 +167,8 @@ pub async fn init_rpc_api(
146167
get_valid_delegation_addresses(l2_opts),
147168
#[cfg(feature = "l2")]
148169
get_sponsor_pk(l2_opts),
170+
#[cfg(feature = "l2")]
171+
rollup_store,
149172
)
150173
.into_future();
151174

cmd/ethrex/l2.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use crate::{
22
cli::{self as ethrex_cli, Options},
33
initializers::{
44
get_local_p2p_node, get_network, get_signer, init_blockchain, init_metrics, init_network,
5-
init_rpc_api, init_store,
5+
init_rollup_store, init_rpc_api, init_store,
66
},
77
utils::{self, set_datadir, store_known_peers},
88
DEFAULT_L2_DATADIR,
@@ -121,10 +121,12 @@ impl Command {
121121
match self {
122122
Command::Init { opts } => {
123123
let data_dir = set_datadir(&opts.node_opts.datadir);
124+
let rollup_store_dir = data_dir.clone() + "/rollup_store";
124125

125126
let network = get_network(&opts.node_opts);
126127

127128
let store = init_store(&data_dir, &network).await;
129+
let rollup_store = init_rollup_store(&rollup_store_dir).await;
128130

129131
let blockchain = init_blockchain(opts.node_opts.evm, store.clone());
130132

@@ -149,6 +151,7 @@ impl Command {
149151
blockchain.clone(),
150152
cancel_token.clone(),
151153
tracker.clone(),
154+
rollup_store.clone(),
152155
)
153156
.await;
154157

@@ -174,7 +177,8 @@ impl Command {
174177
info!("P2P is disabled");
175178
}
176179

177-
let l2_sequencer = ethrex_l2::start_l2(store, blockchain).into_future();
180+
let l2_sequencer =
181+
ethrex_l2::start_l2(store, rollup_store, blockchain).into_future();
178182

179183
tracker.spawn(l2_sequencer);
180184

@@ -219,7 +223,7 @@ impl Command {
219223
.checked_sub(U256::from(64))
220224
.ok_or_eyre("Cannot get finalized block")?;
221225

222-
let event_signature = keccak("BlockCommitted(bytes32)");
226+
let event_signature = keccak("BatchCommitted(bytes32)");
223227

224228
loop {
225229
// Wait for a block

cmd/ethrex_l2/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ ethrex-blockchain = { workspace = true, features = ["l2"] }
1111
ethrex-rlp.workspace = true
1212
ethrex-rpc.workspace = true
1313
ethrex-storage = { workspace = true, features = ["libmdbx"] }
14+
ethrex-storage-rollup = { workspace = true, features = ["libmdbx"] }
1415

1516
serde_json.workspace = true
1617
serde.workspace = true

cmd/ethrex_l2/src/commands/info.rs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ use std::str::FromStr;
99
#[derive(Subcommand)]
1010
pub(crate) enum Command {
1111
#[clap(
12-
about = "Get latestCommittedBlock and latestVerifiedBlock from the OnChainProposer.",
12+
about = "Get latestCommittedBatch and latestVerifiedBatch from the OnChainProposer.",
1313
short_flag = 'l'
1414
)]
15-
LatestBlocks,
15+
LatestBatches,
1616
#[clap(about = "Get the current block_number.", alias = "bl")]
1717
BlockNumber {
1818
#[arg(long = "l2", required = false)]
@@ -48,23 +48,23 @@ impl Command {
4848
let rollup_client = EthClient::new(&cfg.network.l2_rpc_url);
4949
let on_chain_proposer_address = cfg.contracts.on_chain_proposer;
5050
match self {
51-
Command::LatestBlocks => {
52-
let last_committed_block =
53-
EthClient::get_last_committed_block(&eth_client, on_chain_proposer_address)
54-
.await?;
51+
Command::LatestBatches => {
52+
let last_committed_batch = eth_client
53+
.get_last_committed_batch(on_chain_proposer_address)
54+
.await?;
5555

56-
let last_verified_block =
57-
EthClient::get_last_verified_block(&eth_client, on_chain_proposer_address)
58-
.await?;
56+
let last_verified_batch = eth_client
57+
.get_last_verified_batch(on_chain_proposer_address)
58+
.await?;
5959

6060
println!(
61-
"latestCommittedBlock: {}",
62-
format!("{last_committed_block}").bright_cyan()
61+
"latestCommittedBatch: {}",
62+
format!("{last_committed_batch}").bright_cyan()
6363
);
6464

6565
println!(
66-
"latestVerifiedBlock: {}",
67-
format!("{last_verified_block}").bright_cyan()
66+
"latestVerifiedBatch: {}",
67+
format!("{last_verified_batch}").bright_cyan()
6868
);
6969
}
7070
Command::BlockNumber { l2, l1 } => {

0 commit comments

Comments
 (0)