Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .github/workflows/ci-core-lint-reusable.yml
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@ jobs:
ci_run zkstack dev lint -t js --check
ci_run zkstack dev lint -t ts --check
ci_run zkstack dev lint -t rs --check
ci_run zkstack dev lint -t rust-toolchain
ci_run zkstack dev lint -t autocompletion

- name: Check Database
Expand Down
1 change: 1 addition & 0 deletions core/lib/types/src/api/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1112,6 +1112,7 @@ pub struct GatewayMigrationStatus {
pub latest_notification: Option<GatewayMigrationNotification>,
pub state: GatewayMigrationState,
pub settlement_layer: Option<SettlementLayer>,
pub wait_for_batches_to_be_committed: bool,
}

#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
Expand Down
24 changes: 24 additions & 0 deletions core/node/api_server/src/web3/namespaces/unstable/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,13 @@ use zksync_dal::{Connection, Core, CoreDal, DalError};
use zksync_mini_merkle_tree::MiniMerkleTree;
use zksync_multivm::{interface::VmEvent, zk_evm_latest::ethereum_types::U64};
use zksync_types::{
aggregated_operations::L1BatchAggregatedActionType,
api,
api::{
ChainAggProof, DataAvailabilityDetails, GatewayMigrationStatus, L1ToL2TxsStatus, TeeProof,
TransactionDetailedResult, TransactionExecutionInfo,
},
eth_sender::EthTxFinalityStatus,
server_notification::GatewayMigrationState,
tee_types::TeeType,
web3,
Expand Down Expand Up @@ -248,6 +250,27 @@ impl UnstableNamespace {
.await
.map_err(DalError::generalize)?;

let all_batches_with_interop_roots_committed = match connection
.interop_root_dal()
.get_latest_processed_interop_root_l1_batch_number()
.await
.map_err(DalError::generalize)?
{
None => true,
Some(latest_processed_l1_batch_number) => {
match connection
.eth_sender_dal()
.get_last_sent_successfully_eth_tx_by_batch_and_op(
L1BatchNumber::from(latest_processed_l1_batch_number),
L1BatchAggregatedActionType::Commit,
)
.await
{
Some(tx) => tx.eth_tx_finality_status == EthTxFinalityStatus::Finalized,
None => false,
}
}
};
let state = GatewayMigrationState::from_sl_and_notification(
self.state.api_config.settlement_layer,
latest_notification,
Expand All @@ -257,6 +280,7 @@ impl UnstableNamespace {
latest_notification,
state,
settlement_layer: self.state.api_config.settlement_layer,
wait_for_batches_to_be_committed: !all_batches_with_interop_roots_committed,
})
}

Expand Down
19 changes: 9 additions & 10 deletions core/node/eth_sender/src/eth_tx_aggregator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -819,18 +819,17 @@ impl EthTxAggregator {
op_restrictions.commit_restriction = reason;
op_restrictions.precommit_restriction = reason;
// For the migration from gateway to L1, we need to wait for all blocks to be executed
if let None | Some(SettlementLayer::L1(_)) = self.settlement_layer {
if matches!(self.settlement_layer, None | Some(SettlementLayer::L1(_))) {
op_restrictions.prove_restriction = reason;
op_restrictions.execute_restriction = reason;
} else {
// For the migration from gateway to L1, we need we need to ensure all batches containing interop roots get committed and executed.
if !self
.is_waiting_for_batches_with_interop_roots_to_be_committed(storage)
.await?
{
op_restrictions.commit_restriction = None;
op_restrictions.precommit_restriction = None;
}
} else if self
.is_waiting_for_batches_with_interop_roots_to_be_committed(storage)
.await?
{
// For the migration from gateway to L1, we need to ensure all batches containing interop roots
// get committed and executed. Once this happens, we can re-enable commit & precommit.
op_restrictions.commit_restriction = None;
op_restrictions.precommit_restriction = None;
}
}

Expand Down
20 changes: 17 additions & 3 deletions core/tests/gateway-migration-test/tests/migration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,9 +170,23 @@ describe('Migration From/To gateway test', function () {
`zkstack chain gateway migrate-to-gateway --chain ${fileConfig.chain} --gateway-chain-name ${gatewayChain}`
);
} else {
await utils.spawn(
`zkstack chain gateway migrate-from-gateway --chain ${fileConfig.chain} --gateway-chain-name ${gatewayChain}`
);
let migrationSucceeded = false;
for (let i = 0; i < 60; i++) {
try {
await utils.spawn(
`zkstack chain gateway migrate-from-gateway --chain ${fileConfig.chain} --gateway-chain-name ${gatewayChain}`
);
migrationSucceeded = true;
break;
} catch (e) {
console.log(`Migration attempt ${i} failed with error: ${e}`);
await utils.sleep(2);
}
}

if (!migrationSucceeded) {
throw new Error('Migration from gateway did not succeed after 60 attempts');
}
}
await mainNodeSpawner.mainNode?.waitForShutdown();
// Node is already killed, so we simply start the new server
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ impl MigrationDirection {

#[derive(Debug, Eq, PartialEq, Copy, Clone)]
pub enum NotificationReceivedState {
NotAllBatchesCommitted,
NotAllBatchesExecuted(U256, U256),
UnconfirmedTxs(usize),
}
Expand All @@ -71,6 +72,9 @@ impl std::fmt::Display for NotificationReceivedState {
"There are some unconfirmed transactions: {unconfirmed_txs}"
)
}
NotificationReceivedState::NotAllBatchesCommitted => {
write!(f, "Not all batches have been committed yet")
}
}
}
}
Expand Down Expand Up @@ -309,6 +313,12 @@ pub(crate) async fn get_gateway_migration_state(
),
));
}

if gateway_migration_status.wait_for_batches_to_be_committed {
return Ok(GatewayMigrationProgressState::NotificationReceived(
NotificationReceivedState::NotAllBatchesCommitted,
));
}
}

let unconfirmed_txs = zk_client.get_unconfirmed_txs_count().await?;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,10 @@ use crate::{
admin_call_builder::AdminCallBuilder,
gateway::{
constants::DEFAULT_MAX_L1_GAS_PRICE_FOR_PRIORITY_TXS,
gateway_common::extract_and_wait_for_priority_ops,
gateway_common::{
extract_and_wait_for_priority_ops, get_gateway_migration_state,
GatewayMigrationProgressState, MigrationDirection,
},
},
init::get_l1_da_validator,
utils::send_tx,
Expand Down Expand Up @@ -88,6 +91,32 @@ pub async fn run(args: MigrateFromGatewayArgs, shell: &Shell) -> anyhow::Result<
.ctm
.diamond_cut_data;

let gateway_general_config = gateway_chain_config.get_general_config().await?;
let gw_rpc_url = gateway_general_config.l2_http_url()?;

let state = get_gateway_migration_state(
l1_url.clone(),
chain_contracts_config
.ecosystem_contracts
.bridgehub_proxy_addr,
chain_config.chain_id.as_u64(),
chain_config
.get_general_config()
.await?
.l2_http_url()
.context("L2 RPC URL must be provided for cross checking")?,
gw_rpc_url.clone(),
MigrationDirection::FromGateway,
)
.await?;

if state != GatewayMigrationProgressState::ServerReady {
anyhow::bail!(
"Chain is not ready for starting the migration from Gateway. Current state: {:?}",
state
);
}

let start_migrate_from_gateway_call = start_migrate_chain_from_gateway(
shell,
&args.forge_args,
Expand All @@ -111,8 +140,6 @@ pub async fn run(args: MigrateFromGatewayArgs, shell: &Shell) -> anyhow::Result<
let (calldata, value) =
AdminCallBuilder::new(start_migrate_from_gateway_call.calls).compile_full_calldata();

let general_config = gateway_chain_config.get_general_config().await?;
let gw_rpc_url = general_config.l2_http_url()?;
let gateway_provider = get_ethers_provider(&gw_rpc_url)?;
let gateway_zk_client = get_zk_client(&gw_rpc_url, chain_config.chain_id.as_u64())?;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ pub fn run(shell: &Shell, args: LintArgs) -> anyhow::Result<()> {
Target::Js,
Target::Ts,
Target::Contracts,
Target::RustToolchain,
Target::Autocompletion,
Target::RustToolchain,
]
} else {
args.targets.clone()
Expand Down
2 changes: 1 addition & 1 deletion zkstack_cli/rust-toolchain
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
[toolchain]
channel = "nightly-2025-03-19"
channel = "nightly-2025-09-19"
Loading