Skip to content

Commit ed04494

Browse files
authored
Merge pull request #4621 from matter-labs/kl/merge-main
Kl/merge-main
2 parents 69410b6 + 246e570 commit ed04494

File tree

10 files changed

+89
-13
lines changed

10 files changed

+89
-13
lines changed

.github/workflows/ci-core-lint-reusable.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,6 @@ jobs:
8282
ci_run zkstack dev lint -t js --check
8383
ci_run zkstack dev lint -t ts --check
8484
ci_run zkstack dev lint -t rs --check
85-
ci_run zkstack dev lint -t rust-toolchain
8685
ci_run zkstack dev lint -t autocompletion
8786
8887
- name: Check Database

core/lib/types/src/api/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1112,6 +1112,7 @@ pub struct GatewayMigrationStatus {
11121112
pub latest_notification: Option<GatewayMigrationNotification>,
11131113
pub state: GatewayMigrationState,
11141114
pub settlement_layer: Option<SettlementLayer>,
1115+
pub wait_for_batches_to_be_committed: bool,
11151116
}
11161117

11171118
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]

core/node/api_server/src/web3/namespaces/unstable/mod.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,13 @@ use zksync_dal::{Connection, Core, CoreDal, DalError};
88
use zksync_mini_merkle_tree::MiniMerkleTree;
99
use zksync_multivm::{interface::VmEvent, zk_evm_latest::ethereum_types::U64};
1010
use zksync_types::{
11+
aggregated_operations::L1BatchAggregatedActionType,
1112
api,
1213
api::{
1314
ChainAggProof, DataAvailabilityDetails, GatewayMigrationStatus, L1ToL2TxsStatus, TeeProof,
1415
TransactionDetailedResult, TransactionExecutionInfo,
1516
},
17+
eth_sender::EthTxFinalityStatus,
1618
server_notification::GatewayMigrationState,
1719
tee_types::TeeType,
1820
web3,
@@ -248,6 +250,27 @@ impl UnstableNamespace {
248250
.await
249251
.map_err(DalError::generalize)?;
250252

253+
let all_batches_with_interop_roots_committed = match connection
254+
.interop_root_dal()
255+
.get_latest_processed_interop_root_l1_batch_number()
256+
.await
257+
.map_err(DalError::generalize)?
258+
{
259+
None => true,
260+
Some(latest_processed_l1_batch_number) => {
261+
match connection
262+
.eth_sender_dal()
263+
.get_last_sent_successfully_eth_tx_by_batch_and_op(
264+
L1BatchNumber::from(latest_processed_l1_batch_number),
265+
L1BatchAggregatedActionType::Commit,
266+
)
267+
.await
268+
{
269+
Some(tx) => tx.eth_tx_finality_status == EthTxFinalityStatus::Finalized,
270+
None => false,
271+
}
272+
}
273+
};
251274
let state = GatewayMigrationState::from_sl_and_notification(
252275
self.state
253276
.api_config
@@ -264,6 +287,7 @@ impl UnstableNamespace {
264287
.api_config
265288
.settlement_layer
266289
.settlement_layer_for_sending_txs(),
290+
wait_for_batches_to_be_committed: !all_batches_with_interop_roots_committed,
267291
})
268292
}
269293

core/node/eth_sender/src/eth_tx_aggregator.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -857,12 +857,13 @@ impl EthTxAggregator {
857857
op_restrictions.precommit_restriction = reason;
858858
// From V31 when migrating to or from gateway, we need to wait for all blocks to be executed,
859859
// so there is no restriction for prove and execute operations
860-
if let Some(SettlementLayer::Gateway(_)) = self.settlement_layer {
861-
// For the migration from gateway to L1, we need we need to ensure all batches containing interop roots get committed and executed.
862-
if !self
860+
if matches!(self.settlement_layer, Some(SettlementLayer::Gateway(_))) {
861+
if self
863862
.is_waiting_for_batches_with_interop_roots_to_be_committed(storage)
864863
.await?
865864
{
865+
// For the migration from gateway to L1, we need to ensure all batches containing interop roots
866+
// get committed and executed. Once this happens, we can re-enable commit & precommit.
866867
op_restrictions.commit_restriction = None;
867868
op_restrictions.precommit_restriction = None;
868869
}

core/tests/gateway-migration-test/tests/migration.test.ts

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -226,9 +226,23 @@ describe('Migration from gateway test', function () {
226226
}
227227
}
228228
} else {
229-
await utils.spawn(
230-
`zkstack chain gateway migrate-from-gateway --chain ${fileConfig.chain} --gateway-chain-name ${gatewayChain}`
231-
);
229+
let migrationSucceeded = false;
230+
for (let i = 0; i < 60; i++) {
231+
try {
232+
await utils.spawn(
233+
`zkstack chain gateway migrate-from-gateway --chain ${fileConfig.chain} --gateway-chain-name ${gatewayChain}`
234+
);
235+
migrationSucceeded = true;
236+
break;
237+
} catch (e) {
238+
console.log(`Migration attempt ${i} failed with error: ${e}`);
239+
await utils.sleep(2);
240+
}
241+
}
242+
243+
if (!migrationSucceeded) {
244+
throw new Error('Migration from gateway did not succeed after 60 attempts');
245+
}
232246
}
233247
await mainNodeSpawner.mainNode?.waitForShutdown();
234248
// Node is already killed, so we simply start the new server

zkstack_cli/crates/zkstack/src/commands/chain/gateway/gateway_common.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ impl MigrationDirection {
5252

5353
#[derive(Debug, Eq, PartialEq, Copy, Clone)]
5454
pub enum NotificationReceivedState {
55+
NotAllBatchesCommitted,
5556
NotAllBatchesExecuted(U256, U256),
5657
UnconfirmedTxs(usize),
5758
}
@@ -71,6 +72,9 @@ impl std::fmt::Display for NotificationReceivedState {
7172
"There are some unconfirmed transactions: {unconfirmed_txs}"
7273
)
7374
}
75+
NotificationReceivedState::NotAllBatchesCommitted => {
76+
write!(f, "Not all batches have been committed yet")
77+
}
7478
}
7579
}
7680
}
@@ -309,6 +313,12 @@ pub(crate) async fn get_gateway_migration_state(
309313
),
310314
));
311315
}
316+
317+
if gateway_migration_status.wait_for_batches_to_be_committed {
318+
return Ok(GatewayMigrationProgressState::NotificationReceived(
319+
NotificationReceivedState::NotAllBatchesCommitted,
320+
));
321+
}
312322
}
313323

314324
let unconfirmed_txs = zk_client.get_unconfirmed_txs_count().await?;

zkstack_cli/crates/zkstack/src/commands/chain/gateway/migrate_from_gateway.rs

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,10 @@ use crate::{
3939
admin_call_builder::AdminCallBuilder,
4040
gateway::{
4141
constants::DEFAULT_MAX_L1_GAS_PRICE_FOR_PRIORITY_TXS,
42-
gateway_common::extract_and_wait_for_priority_ops,
42+
gateway_common::{
43+
extract_and_wait_for_priority_ops, get_gateway_migration_state,
44+
GatewayMigrationProgressState, MigrationDirection,
45+
},
4346
},
4447
init::get_l1_da_validator,
4548
utils::send_tx,
@@ -85,6 +88,32 @@ pub async fn run(args: MigrateFromGatewayArgs, shell: &Shell) -> anyhow::Result<
8588
.ctm
8689
.diamond_cut_data;
8790

91+
let gateway_general_config = gateway_chain_config.get_general_config().await?;
92+
let gw_rpc_url = gateway_general_config.l2_http_url()?;
93+
94+
let state = get_gateway_migration_state(
95+
l1_url.clone(),
96+
chain_contracts_config
97+
.ecosystem_contracts
98+
.bridgehub_proxy_addr,
99+
chain_config.chain_id.as_u64(),
100+
chain_config
101+
.get_general_config()
102+
.await?
103+
.l2_http_url()
104+
.context("L2 RPC URL must be provided for cross checking")?,
105+
gw_rpc_url.clone(),
106+
MigrationDirection::FromGateway,
107+
)
108+
.await?;
109+
110+
if state != GatewayMigrationProgressState::ServerReady {
111+
anyhow::bail!(
112+
"Chain is not ready for starting the migration from Gateway. Current state: {:?}",
113+
state
114+
);
115+
}
116+
88117
let start_migrate_from_gateway_call = start_migrate_chain_from_gateway(
89118
shell,
90119
&args.forge_args,
@@ -108,8 +137,6 @@ pub async fn run(args: MigrateFromGatewayArgs, shell: &Shell) -> anyhow::Result<
108137
let (calldata, value) =
109138
AdminCallBuilder::new(start_migrate_from_gateway_call.calls).compile_full_calldata();
110139

111-
let general_config = gateway_chain_config.get_general_config().await?;
112-
let gw_rpc_url = general_config.l2_http_url()?;
113140
let gateway_provider = get_ethers_provider(&gw_rpc_url)?;
114141
let gateway_zk_client = get_zk_client(&gw_rpc_url, chain_config.chain_id.as_u64())?;
115142

zkstack_cli/crates/zkstack/src/commands/dev/commands/lint.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@ pub fn run(shell: &Shell, args: LintArgs) -> anyhow::Result<()> {
4141
Target::Js,
4242
Target::Ts,
4343
Target::Contracts,
44-
Target::RustToolchain,
4544
Target::Autocompletion,
45+
Target::RustToolchain,
4646
]
4747
} else {
4848
args.targets.clone()

zkstack_cli/rust-toolchain

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
[toolchain]
2-
channel = "1.89.0"
2+
channel = "nightly-2025-09-19"

0 commit comments

Comments
 (0)