Skip to content

Commit b817a9a

Browse files
authored
fix(l2): ignore deposits after state reconstruction (#2642)
**Motivation** Currently, If we start our l2 node with a reconstructed state, the node will process all deposit logs from l1 and mint them again in l2. This is because, in a reconstructed store, we don't have the included transactions to determine whether a deposit was previously processed or not. **Description** - Fixes the reconstruct algorithm to start from batch_number=1. - Fixes the `l2MintTxHash` emitted in the `CommonBridge` contract. - Adds an additional check to the `integration_test` to wait for the deposit receipt on L2. - Reuses the emitted `l2MintTxHash` instead of recalculating it in the watcher. - Checks, in the `CommonBridge` contract, whether a deposit is pending or not before minting the transaction. - Creates `DepositData` struct in `l1_watcher` ### How to test Here we are going to run the integration test on a node with a reconstructed state. You may want to lower the `commit_time_ms`. 1. Start the prover and network with: ``` make init-prover make init ``` 2. Wait until batch 6 is verified and stop the l2 node with `ctrl + c`: ``` INFO ethrex_l2::sequencer::l1_proof_sender: Sent proof for batch 6... ctrl + c ``` > [!NOTE] > This is because we are going to use already created blobs with 6 batches and we need > to advance the L1 until that point. 3. Clean db: ``` make rm-db-l2 ``` 4. Reconstruct the state choosing a `path_to_store`: ``` cargo run --release --manifest-path ../../cmd/ethrex_l2/Cargo.toml --bin ethrex_l2 -- stack reconstruct -g ../../test_data/genesis-l2.json -b ../../test_data/blobs/ -s path_to_store -c 0x0007a881CD95B1484fca47615B64803dad620C8d ``` 5. Start the l2 node using `path_to_store`: ``` make init-l2 ethrex_L2_DEV_LIBMDBX=path_to_store ``` You should observe that all deposits are skipped now. 6. In a new terminal, run the integration test: ``` cd crates/l2 make test ``` > [!WARNING] > Before running the integration test, wait for 20 blocks to be built in the L2. > This is because the test currently uses [estimate_gas_tip](https://github.com/lambdaclass/ethrex/blob/aa3c41b8da043ff5cd1ad699ce882c41edefc460/crates/networking/rpc/eth/fee_calculator.rs#L30) that needs at least 20 blocks to estimate the gas price. Closes #1279
1 parent 3f006c1 commit b817a9a

File tree

8 files changed

+284
-171
lines changed

8 files changed

+284
-171
lines changed

cmd/ethrex_l2/src/commands/stack.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ impl Command {
202202
.await?;
203203
let rollup_store = StoreRollup::new(
204204
store_path
205-
.join("../rollup_store")
205+
.join("./rollup_store")
206206
.to_str()
207207
.expect("Invalid store path"),
208208
EngineTypeRollup::Libmdbx,
@@ -224,11 +224,12 @@ impl Command {
224224

225225
// Iterate over each blob
226226
let files: Vec<std::fs::DirEntry> = read_dir(blobs_dir)?.try_collect()?;
227-
for (batch_number, file) in files
227+
for (file_number, file) in files
228228
.into_iter()
229229
.sorted_by_key(|f| f.file_name())
230230
.enumerate()
231231
{
232+
let batch_number = file_number as u64 + 1;
232233
let blob = std::fs::read(file.path())?;
233234

234235
if blob.len() != BYTES_PER_BLOB {
@@ -294,7 +295,7 @@ impl Command {
294295
// Store batch info in L2 storage
295296
rollup_store
296297
.store_batch(
297-
batch_number as u64,
298+
batch_number,
298299
first_block_number,
299300
last_block_number,
300301
withdrawal_hashes,

crates/l2/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ ethrex_L2_CONTRACTS_PATH=./contracts
6060
L1_RPC_URL=http://localhost:8545
6161
L1_PRIVATE_KEY=0x385c546456b6a603a1cfcaa9ec9494ba4832da08dd6bcf4de9a71e4a01b74924
6262

63-
ethrex_L2_DEV_LIBMDBX=dev_ethrex_l2
63+
ethrex_L2_DEV_LIBMDBX?=dev_ethrex_l2
6464
ethrex_L1_DEV_LIBMDBX=dev_ethrex_l1
6565
L1_PORT=8545
6666
L2_PORT=1729

crates/l2/configs/sequencer_config_example.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ maximum_allowed_max_fee_per_gas = 10000000000
2323
maximum_allowed_max_fee_per_blob_gas = 10000000000
2424

2525
[watcher]
26-
bridge_address = "0x266ffef34e21a7c4ce2e0e42dc780c2c273ca440"
26+
bridge_address = "0x554a14cd047c485b3ac3edbd9fbb373d6f84ad3f"
2727
check_interval_ms = 1000
2828
max_block_step = 5000
2929
l2_proposer_private_key = "0x385c546456b6a603a1cfcaa9ec9494ba4832da08dd6bcf4de9a71e4a01b74924"

crates/l2/contracts/src/l1/CommonBridge.sol

Lines changed: 10 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -76,30 +76,19 @@ contract CommonBridge is ICommonBridge, Ownable, ReentrancyGuard {
7676
require(msg.value > 0, "CommonBridge: amount to deposit is zero");
7777

7878
bytes32 l2MintTxHash = keccak256(
79-
abi.encodePacked(
80-
msg.sender,
81-
depositValues.to,
82-
depositValues.recipient,
83-
msg.value,
84-
depositValues.gasLimit,
85-
depositId,
86-
depositValues.data
79+
bytes.concat(
80+
bytes20(depositValues.to),
81+
bytes32(msg.value),
82+
bytes32(depositId),
83+
bytes20(depositValues.recipient),
84+
bytes20(msg.sender),
85+
bytes32(depositValues.gasLimit),
86+
bytes32(keccak256(depositValues.data))
8787
)
8888
);
8989

90-
pendingDepositLogs.push(
91-
keccak256(
92-
bytes.concat(
93-
bytes20(depositValues.to),
94-
bytes32(msg.value),
95-
bytes32(depositId),
96-
bytes20(depositValues.recipient),
97-
bytes20(msg.sender),
98-
bytes32(depositValues.gasLimit),
99-
bytes32(keccak256(depositValues.data))
100-
)
101-
)
102-
);
90+
pendingDepositLogs.push(l2MintTxHash);
91+
10392
emit DepositInitiated(
10493
msg.value,
10594
depositValues.to,

crates/l2/sdk/src/sdk.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@ use serde::{Deserialize, Deserializer, Serialize, Serializer};
1313
pub mod calldata;
1414
pub mod merkle_tree;
1515

16-
// 0x6bf26397c5676a208d5c4e5f35cb479bacbbe454
16+
// 0x554a14cd047c485b3ac3edbd9fbb373d6f84ad3f
1717
pub const DEFAULT_BRIDGE_ADDRESS: Address = H160([
18-
0x6b, 0xf2, 0x63, 0x97, 0xc5, 0x67, 0x6a, 0x20, 0x8d, 0x5c, 0x4e, 0x5f, 0x35, 0xcb, 0x47, 0x9b,
19-
0xac, 0xbb, 0xe4, 0x54,
18+
0x55, 0x4a, 0x14, 0xcd, 0x04, 0x7c, 0x48, 0x5b, 0x3a, 0xc3, 0xed, 0xbd, 0x9f, 0xbb, 0x37, 0x3d,
19+
0x6f, 0x84, 0xad, 0x3f,
2020
]);
2121

2222
pub const COMMON_BRIDGE_L2_ADDRESS: Address = H160([
@@ -32,7 +32,7 @@ pub enum SdkError {
3232
FailedToParseAddressFromHex,
3333
}
3434

35-
/// BRIDGE_ADDRESS or 0x6bf26397c5676a208d5c4e5f35cb479bacbbe454
35+
/// BRIDGE_ADDRESS or 0x554a14cd047c485b3ac3edbd9fbb373d6f84ad3f
3636
pub fn bridge_address() -> Result<Address, SdkError> {
3737
std::env::var("L1_WATCHER_BRIDGE_ADDRESS")
3838
.unwrap_or(format!("{DEFAULT_BRIDGE_ADDRESS:#x}"))

0 commit comments

Comments
 (0)