Skip to content

Commit 2858ba0

Browse files
authored
feat(gateway): Migration to Gateway (matter-labs#3654)
## What ❔ Support migration to Gateway. That will be done through restart. There are few major changes in server 1. Contracats config now splitted to 3 configs: a. L1SpecificConfig - Stuff that exists only on l1 and will never be migrated to gateway b. L2Contracts - Contracts that were deployed on l2 c. ChainSpecificContracts - Contracts that deployed on l1 and on gateway 2. L1 specific contracts and L2 contracts, for now, should be specified in contracts config, manually. In a future we will be able to load them as well 3. ChainSpecificContracts, are loading from the Settlement Layer, no need to specify 4. There are no configuration for settlement layer. The settlement layer known during the start of the node and the source of truth is contracts both on l1 and settlement layer. 5. Server constantly checks that settlement layer has not changed. If it chaged, server will wait until all processed transaction are sent and confirmed and the necessary contracts are deployed to l1. After that server will be killed. We assume that kubernetes will restart the server 6. During the start server checks the settlement layer and download the necessary contracts config, later on almost all components of the system are manipulating only with settlement layer client and config. Only eth watcher knows about both layers. External Node: 1. During the sync with the server External node verifies the transaction on l1 for consistency. Once consistency checker is panicking, external node crashes 2. During the start External node checks the latest eth txs in db and depends on it setup the system to work either on Gateway or on L1 Migration process 1. Operator call the server notifier contract and this contract will send the message to server, that all commit operations, should be stopped 2. Server stops the commit operations, but continue to work in all other parts 3. Operator call the migrate to gateway function on contracts 4. Once the migration is executed both on l1 and gateway, server will crash 5. During the next start server will load all necessary contracts and continue to work ## Why ❔ The migration to settlement layer should be smooth. Without necessary of manual restarts and setting the contracts, it will drastically increase the mistakes, especially with multiple chains in operation. ## Is this a breaking change? - [ ] Yes - [x] No ## Operational changes <!-- Any config changes? Any new flags? Any changes to any scripts? --> <!-- Please add anything that non-Matter Labs entities running their own ZK Chain may need to know --> ## Checklist <!-- Check your PR fulfills the following items. --> <!-- For draft PRs check the boxes as you complete them. --> - [x] PR title corresponds to the body of PR (we generate changelog entries from PRs). - [x] Tests for the changes have been added / updated. - [x] Documentation comments have been added / updated. - [x] Code has been formatted via `zkstack dev fmt` and `zkstack dev lint`. --------- Signed-off-by: Danil <deniallugo@gmail.com>
1 parent 92a5156 commit 2858ba0

File tree

166 files changed

+3820
-2359
lines changed

Some content is hidden

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

166 files changed

+3820
-2359
lines changed

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

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -415,27 +415,32 @@ jobs:
415415
ci_run zkstack server --ignore-prerequisites --chain gateway &> ${{ env.SERVER_LOGS_DIR }}/gateway.log &
416416
ci_run zkstack server wait --ignore-prerequisites --verbose --chain gateway
417417
418+
- name: Build test dependencies
419+
run: |
420+
ci_run zkstack dev test build
421+
418422
- name: Migrate chains to gateway
419423
if: matrix.use_gateway_chain == 'WITH_GATEWAY'
420424
run: |
421-
ci_run zkstack chain migrate-to-gateway --chain era --gateway-chain-name gateway
425+
ci_run zkstack dev test gateway-migration --to-gateway --chain era --no-deps
422426
ci_run zkstack chain migrate-to-gateway --chain validium --gateway-chain-name gateway
423427
ci_run zkstack chain migrate-to-gateway --chain custom_token --gateway-chain-name gateway
424428
ci_run zkstack chain migrate-to-gateway --chain consensus --gateway-chain-name gateway
425429
426430
- name: Migrate back era
427431
if: matrix.use_gateway_chain == 'WITH_GATEWAY'
428432
run: |
429-
ci_run zkstack chain migrate-from-gateway --chain era --gateway-chain-name gateway
433+
ci_run zkstack dev test gateway-migration --from-gateway --chain era --no-deps
430434
431435
- name: Migrate to gateway again
432436
if: matrix.use_gateway_chain == 'WITH_GATEWAY'
433437
run: |
434-
ci_run zkstack chain migrate-to-gateway --chain era --gateway-chain-name gateway
438+
ci_run zkstack dev test gateway-migration --to-gateway --chain era --no-deps
439+
ci_run pkill -9 zksync_server
440+
ci_run zkstack server --ignore-prerequisites --chain gateway &> ${{ env.SERVER_LOGS_DIR }}/gateway.log &
441+
ci_run zkstack server wait --ignore-prerequisites --verbose --chain gateway
442+
435443
436-
- name: Build test dependencies
437-
run: |
438-
ci_run zkstack dev test build
439444
440445
- name: Build tested binaries
441446
run: |

chains/era/ZkStack.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,4 @@ base_token:
1212
nominator: 1
1313
denominator: 1
1414
wallet_creation: Localhost
15+
evm_emulator: false

core/Cargo.lock

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

core/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ members = [
4040
"node/external_proof_integration_api",
4141
"node/logs_bloom_backfill",
4242
"node/da_clients",
43+
"node/gateway_migrator",
4344
"node/zk_os_tree_manager",
4445
# Libraries
4546
"lib/db_connection",
@@ -335,3 +336,4 @@ zksync_contract_verification_server = { version = "27.1.0-non-semver-compat", pa
335336
zksync_node_api_server = { version = "27.1.0-non-semver-compat", path = "node/api_server" }
336337
zksync_base_token_adjuster = { version = "27.1.0-non-semver-compat", path = "node/base_token_adjuster" }
337338
zksync_logs_bloom_backfill = { version = "27.1.0-non-semver-compat", path = "node/logs_bloom_backfill" }
339+
zksync_gateway_migrator = { version = "27.1.0-non-semver-compat", path = "node/gateway_migrator" }

core/bin/block_reverter/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ zksync_object_store.workspace = true
2121
zksync_types.workspace = true
2222
zksync_block_reverter.workspace = true
2323
zksync_vlog.workspace = true
24+
zksync_contracts.workspace = true
2425

2526
anyhow.workspace = true
2627
clap = { workspace = true, features = ["derive"] }

core/bin/block_reverter/src/main.rs

Lines changed: 53 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -9,24 +9,24 @@ use tokio::{
99
use zksync_block_reverter::{
1010
eth_client::{
1111
clients::{Client, PKSigningClient, L1},
12-
EthInterface,
12+
contracts_loader::{get_settlement_layer_from_l1, load_settlement_layer_contracts},
1313
},
1414
BlockReverter, BlockReverterEthConfig, NodeRole,
1515
};
1616
use zksync_config::{
1717
configs::{
1818
chain::NetworkConfig, wallets::Wallets, BasicWitnessInputProducerConfig, DatabaseSecrets,
19-
GatewayChainConfig, GeneralConfig, L1Secrets, ObservabilityConfig,
20-
ProtectiveReadsWriterConfig,
19+
GeneralConfig, L1Secrets, ObservabilityConfig, ProtectiveReadsWriterConfig,
2120
},
2221
ContractsConfig, DBConfig, EthConfig, GenesisConfig, PostgresConfig,
2322
};
23+
use zksync_contracts::getters_facet_contract;
2424
use zksync_core_leftovers::temp_config_store::read_yaml_repr;
2525
use zksync_dal::{ConnectionPool, Core};
2626
use zksync_env_config::{object_store::SnapshotsObjectStoreConfig, FromEnv};
2727
use zksync_object_store::ObjectStoreFactory;
2828
use zksync_protobuf_config::proto;
29-
use zksync_types::{Address, L1BatchNumber};
29+
use zksync_types::{settlement::SettlementLayer, Address, L1BatchNumber, L2_BRIDGEHUB_ADDRESS};
3030

3131
#[derive(Debug, Parser)]
3232
#[command(author = "Matter Labs", version, about = "Block revert utility", long_about = None)]
@@ -203,7 +203,6 @@ async fn main() -> anyhow::Result<()> {
203203

204204
let gas_adjuster = eth_sender.gas_adjuster.context("gas_adjuster")?;
205205
let default_priority_fee_per_gas = gas_adjuster.default_priority_fee_per_gas;
206-
let settlement_mode = gas_adjuster.settlement_mode;
207206

208207
let database_secrets = match &secrets_config {
209208
Some(secrets_config) => secrets_config
@@ -235,33 +234,55 @@ async fn main() -> anyhow::Result<()> {
235234
}
236235
};
237236

238-
let (sl_rpc_url, sl_diamond_proxy, sl_validator_timelock) = if settlement_mode.is_gateway() {
239-
// Gateway config is required to be provided by file for now.
240-
let gateway_chain_config: GatewayChainConfig =
241-
read_yaml_repr::<proto::gateway::GatewayChainConfig>(
242-
&opts
243-
.gateway_chain_path
244-
.context("Genesis config path not provided")?,
245-
)
246-
.context("failed decoding genesis YAML config")?;
237+
let l1_client: Client<L1> = Client::http(l1_secrets.l1_rpc_url)
238+
.context("Ethereum client")?
239+
.build();
247240

248-
let gateway_url = l1_secrets
249-
.gateway_rpc_url
250-
.context("Gateway URL not found")?;
241+
let sl_l1_contracts = load_settlement_layer_contracts(
242+
&l1_client,
243+
contracts.bridgehub_proxy_addr,
244+
zksync_network_id,
245+
None,
246+
)
247+
.await?
248+
// If None has been returned, in case of pre v27 upgrade, use the contracts from configs
249+
.unwrap_or_else(|| contracts.settlement_layer_specific_contracts());
250+
let settlement_mode = get_settlement_layer_from_l1(
251+
&l1_client,
252+
sl_l1_contracts.chain_contracts_config.diamond_proxy_addr,
253+
&getters_facet_contract(),
254+
)
255+
.await?;
251256

252-
(
253-
gateway_url,
254-
gateway_chain_config.diamond_proxy_addr,
255-
gateway_chain_config.validator_timelock_addr,
256-
)
257-
} else {
258-
(
259-
l1_secrets.l1_rpc_url,
260-
contracts.diamond_proxy_addr,
261-
contracts.validator_timelock_addr,
262-
)
257+
let (client, contracts, chain_id) = match settlement_mode {
258+
SettlementLayer::L1(chain_id) => (l1_client, sl_l1_contracts, chain_id),
259+
SettlementLayer::Gateway(chain_id) => {
260+
let gateway_client: Client<L1> = Client::http(
261+
l1_secrets
262+
.gateway_rpc_url
263+
.context("Gateway url is not presented in config")?,
264+
)
265+
.context("Gateway client")?
266+
.build();
267+
268+
let sl_contracts = load_settlement_layer_contracts(
269+
&gateway_client,
270+
L2_BRIDGEHUB_ADDRESS,
271+
zksync_network_id,
272+
None,
273+
)
274+
.await?
275+
.context("No chain has been deployed")?;
276+
(gateway_client, sl_contracts, chain_id)
277+
}
263278
};
264279

280+
let sl_diamond_proxy = contracts.chain_contracts_config.diamond_proxy_addr;
281+
let sl_validator_timelock = contracts
282+
.ecosystem_contracts
283+
.validator_timelock_addr
284+
.expect("Should be presented");
285+
265286
let config = BlockReverterEthConfig::new(
266287
&eth_sender,
267288
sl_diamond_proxy,
@@ -284,12 +305,8 @@ async fn main() -> anyhow::Result<()> {
284305
json,
285306
operator_address,
286307
} => {
287-
let sl_client = Client::<L1>::http(sl_rpc_url)
288-
.context("Ethereum client")?
289-
.build();
290-
291308
let suggested_values = block_reverter
292-
.suggested_values(&sl_client, &config, operator_address)
309+
.suggested_values(&client, &config, operator_address)
293310
.await?;
294311
if json {
295312
println!("{}", serde_json::to_string(&suggested_values)?);
@@ -302,7 +319,6 @@ async fn main() -> anyhow::Result<()> {
302319
priority_fee_per_gas,
303320
nonce,
304321
} => {
305-
let sl_client = Client::http(sl_rpc_url).context("Ethereum client")?.build();
306322
let reverter_private_key = if let Some(wallets_config) = wallets_config {
307323
wallets_config
308324
.eth_sender
@@ -313,24 +329,20 @@ async fn main() -> anyhow::Result<()> {
313329
} else {
314330
#[allow(deprecated)]
315331
eth_sender
316-
.sender
332+
.get_eth_sender_config_for_sender_layer_data_layer()
317333
.context("eth_sender_config")?
318334
.private_key()
319335
.context("eth_sender_config.private_key")?
320336
.context("eth_sender_config.private_key is not set")?
321337
};
322338

323339
let priority_fee_per_gas = priority_fee_per_gas.unwrap_or(default_priority_fee_per_gas);
324-
let l1_chain_id = sl_client
325-
.fetch_chain_id()
326-
.await
327-
.context("cannot fetch Ethereum chain ID")?;
328340
let sl_client = PKSigningClient::new_raw(
329341
reverter_private_key,
330342
sl_diamond_proxy,
331343
priority_fee_per_gas,
332-
l1_chain_id,
333-
Box::new(sl_client),
344+
chain_id,
345+
Box::new(client),
334346
);
335347

336348
block_reverter

0 commit comments

Comments
 (0)