Skip to content

Commit 7a4f60d

Browse files
sync with base
2 parents 06d0bd5 + 1032e2a commit 7a4f60d

File tree

10 files changed

+105
-33
lines changed

10 files changed

+105
-33
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/eth_client/src/contracts_loader.rs

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -186,25 +186,21 @@ pub async fn get_zk_chain_on_chain_params(
186186
diamond_proxy_addr: Address,
187187
) -> Result<ZkChainOnChainConfig, ContractCallError> {
188188
let abi = getters_facet_contract();
189-
let l2_da_commitment_scheme: Token = CallFunctionArgs::new("getDAValidatorPair", ())
189+
let token: Token = CallFunctionArgs::new("getDAValidatorPair", ())
190190
.for_contract(diamond_proxy_addr, &abi)
191191
.call(eth_client)
192192
.await?;
193-
let l2_da_commitment_scheme =
194-
if let Token::Tuple(l2_da_commitment_scheme) = l2_da_commitment_scheme {
195-
if let [Token::Address(_), Token::Uint(l2_da_commitment_scheme)] =
196-
l2_da_commitment_scheme.as_slice()
197-
{
198-
Some(
199-
L2DACommitmentScheme::try_from(l2_da_commitment_scheme.as_u64() as u8)
200-
.expect("wrong l2_da_commitment_scheme"),
201-
)
202-
} else {
203-
None
204-
}
205-
} else {
206-
None
207-
};
193+
194+
let l2_da_commitment_scheme = match token {
195+
Token::Tuple(tuple) if tuple.len() == 2 => match tuple.as_slice() {
196+
[Token::Address(_), Token::Uint(value)] if *value <= U256::from(u8::MAX) => Some(
197+
L2DACommitmentScheme::try_from(value.as_u64() as u8)
198+
.expect("Wrong L2DACommitmentScheme"),
199+
),
200+
_ => None,
201+
},
202+
_ => None,
203+
};
208204

209205
Ok(ZkChainOnChainConfig {
210206
l2_da_commitment_scheme,

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
@@ -63,6 +63,7 @@ pub struct NotifyServerArgs {
6363

6464
#[derive(Debug, Eq, PartialEq, Copy, Clone)]
6565
pub enum NotificationReceivedState {
66+
NotAllBatchesCommitted,
6667
NotAllBatchesExecuted(U256, U256),
6768
UnconfirmedTxs(usize),
6869
}
@@ -82,6 +83,9 @@ impl std::fmt::Display for NotificationReceivedState {
8283
"There are some unconfirmed transactions: {unconfirmed_txs}"
8384
)
8485
}
86+
NotificationReceivedState::NotAllBatchesCommitted => {
87+
write!(f, "Not all batches have been committed yet")
88+
}
8589
}
8690
}
8791
}
@@ -320,6 +324,12 @@ pub(crate) async fn get_gateway_migration_state(
320324
),
321325
));
322326
}
327+
328+
if gateway_migration_status.wait_for_batches_to_be_committed {
329+
return Ok(GatewayMigrationProgressState::NotificationReceived(
330+
NotificationReceivedState::NotAllBatchesCommitted,
331+
));
332+
}
323333
}
324334

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

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

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,10 @@ use crate::{
4040
args::init::da_configs::ValidiumTypeInternal,
4141
gateway::{
4242
constants::DEFAULT_MAX_L1_GAS_PRICE_FOR_PRIORITY_TXS,
43-
gateway_common::extract_and_wait_for_priority_ops,
43+
gateway_common::{
44+
extract_and_wait_for_priority_ops, get_gateway_migration_state,
45+
GatewayMigrationProgressState, MigrationDirection,
46+
},
4447
},
4548
init::get_l1_da_validator,
4649
utils::send_tx,
@@ -101,6 +104,37 @@ pub async fn run(args: MigrateFromGatewayArgs, shell: &Shell) -> anyhow::Result<
101104
.ctm
102105
.diamond_cut_data;
103106

107+
let gw_rpc_url = match args.gateway_rpc_url {
108+
Some(url) => url,
109+
None => {
110+
let general_config = gateway_chain_config.get_general_config().await?;
111+
general_config.l2_http_url()?
112+
}
113+
};
114+
115+
let state = get_gateway_migration_state(
116+
l1_url.clone(),
117+
chain_contracts_config
118+
.ecosystem_contracts
119+
.bridgehub_proxy_addr,
120+
chain_config.chain_id.as_u64(),
121+
chain_config
122+
.get_general_config()
123+
.await?
124+
.l2_http_url()
125+
.context("L2 RPC URL must be provided for cross checking")?,
126+
gw_rpc_url.clone(),
127+
MigrationDirection::FromGateway,
128+
)
129+
.await?;
130+
131+
if state != GatewayMigrationProgressState::ServerReady {
132+
anyhow::bail!(
133+
"Chain is not ready for starting the migration from Gateway. Current state: {:?}",
134+
state
135+
);
136+
}
137+
104138
let start_migrate_from_gateway_call = start_migrate_chain_from_gateway(
105139
shell,
106140
&args.forge_args,
@@ -124,13 +158,6 @@ pub async fn run(args: MigrateFromGatewayArgs, shell: &Shell) -> anyhow::Result<
124158
let (calldata, value) =
125159
AdminCallBuilder::new(start_migrate_from_gateway_call.calls).compile_full_calldata();
126160

127-
let gw_rpc_url = match args.gateway_rpc_url {
128-
Some(url) => url,
129-
None => {
130-
let general_config = gateway_chain_config.get_general_config().await?;
131-
general_config.l2_http_url()?
132-
}
133-
};
134161
let gateway_provider = get_ethers_provider(&gw_rpc_url)?;
135162
let gateway_zk_client = get_zk_client(&gw_rpc_url, chain_config.chain_id.as_u64())?;
136163

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)