From d6de4f40ddce339c760c95e2bf4b8aceb571af7f Mon Sep 17 00:00:00 2001 From: Daniyar Itegulov Date: Mon, 21 Oct 2024 22:17:08 +1100 Subject: [PATCH 01/27] feat(external-node): save protocol version before opening a batch (#3136) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## What ❔ Moved protocol version fetching a bit earlier in the flow for EN so that it is present by the time we insert the corresponding unsealed batch. ## Why ❔ Persisted unsealed batches now uniformly have protocol version present in them (both main and external nodes). ## Checklist - [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`. --- core/lib/dal/src/protocol_versions_dal.rs | 41 ++++- core/node/node_sync/src/external_io.rs | 211 +++++++++++++++++----- 2 files changed, 201 insertions(+), 51 deletions(-) diff --git a/core/lib/dal/src/protocol_versions_dal.rs b/core/lib/dal/src/protocol_versions_dal.rs index 3382d8c836e5..fcc756e30069 100644 --- a/core/lib/dal/src/protocol_versions_dal.rs +++ b/core/lib/dal/src/protocol_versions_dal.rs @@ -190,6 +190,43 @@ impl ProtocolVersionsDal<'_, '_> { ProtocolVersionId::try_from(row.id as u16).map_err(|err| sqlx::Error::Decode(err.into())) } + /// Returns base system contracts' hashes. Prefer `load_base_system_contracts_by_version_id` if + /// you also want to load the contracts themselves AND expect the contracts to be in the DB + /// already. + pub async fn get_base_system_contract_hashes_by_version_id( + &mut self, + version_id: u16, + ) -> anyhow::Result> { + let row = sqlx::query!( + r#" + SELECT + bootloader_code_hash, + default_account_code_hash, + evm_emulator_code_hash + FROM + protocol_versions + WHERE + id = $1 + "#, + i32::from(version_id) + ) + .instrument("get_base_system_contract_hashes_by_version_id") + .with_arg("version_id", &version_id) + .fetch_optional(self.storage) + .await + .context("cannot fetch system contract hashes")?; + + Ok(if let Some(row) = row { + Some(BaseSystemContractsHashes { + bootloader: H256::from_slice(&row.bootloader_code_hash), + default_aa: H256::from_slice(&row.default_account_code_hash), + evm_emulator: row.evm_emulator_code_hash.as_deref().map(H256::from_slice), + }) + } else { + None + }) + } + pub async fn load_base_system_contracts_by_version_id( &mut self, version_id: u16, @@ -207,7 +244,9 @@ impl ProtocolVersionsDal<'_, '_> { "#, i32::from(version_id) ) - .fetch_optional(self.storage.conn()) + .instrument("load_base_system_contracts_by_version_id") + .with_arg("version_id", &version_id) + .fetch_optional(self.storage) .await .context("cannot fetch system contract hashes")?; diff --git a/core/node/node_sync/src/external_io.rs b/core/node/node_sync/src/external_io.rs index 5e3a5ce9f46e..a0be233a002e 100644 --- a/core/node/node_sync/src/external_io.rs +++ b/core/node/node_sync/src/external_io.rs @@ -104,6 +104,63 @@ impl ExternalIO { } }) } + + async fn ensure_protocol_version_is_saved( + &self, + protocol_version: ProtocolVersionId, + ) -> anyhow::Result<()> { + let base_system_contract_hashes = self + .pool + .connection_tagged("sync_layer") + .await? + .protocol_versions_dal() + .get_base_system_contract_hashes_by_version_id(protocol_version as u16) + .await?; + if base_system_contract_hashes.is_some() { + return Ok(()); + } + tracing::info!("Fetching protocol version {protocol_version:?} from the main node"); + + let protocol_version = self + .main_node_client + .fetch_protocol_version(protocol_version) + .await + .context("failed to fetch protocol version from the main node")? + .context("protocol version is missing on the main node")?; + let minor = protocol_version + .minor_version() + .context("Missing minor protocol version")?; + let bootloader_code_hash = protocol_version + .bootloader_code_hash() + .context("Missing bootloader code hash")?; + let default_account_code_hash = protocol_version + .default_account_code_hash() + .context("Missing default account code hash")?; + let evm_emulator_code_hash = protocol_version.evm_emulator_code_hash(); + let l2_system_upgrade_tx_hash = protocol_version.l2_system_upgrade_tx_hash(); + self.pool + .connection_tagged("sync_layer") + .await? + .protocol_versions_dal() + .save_protocol_version( + ProtocolSemanticVersion { + minor: minor + .try_into() + .context("cannot convert protocol version")?, + patch: VersionPatch(0), + }, + protocol_version.timestamp, + Default::default(), // verification keys are unused for EN + BaseSystemContractsHashes { + bootloader: bootloader_code_hash, + default_aa: default_account_code_hash, + evm_emulator: evm_emulator_code_hash, + }, + l2_system_upgrade_tx_hash, + ) + .await?; + Ok(()) + } } impl IoSealCriteria for ExternalIO { @@ -254,6 +311,8 @@ impl StateKeeperIO for ExternalIO { cursor.next_l2_block ); + self.ensure_protocol_version_is_saved(params.protocol_version) + .await?; self.pool .connection_tagged("sync_layer") .await? @@ -261,7 +320,7 @@ impl StateKeeperIO for ExternalIO { .insert_l1_batch(UnsealedL1BatchHeader { number: cursor.l1_batch, timestamp: params.first_l2_block.timestamp, - protocol_version: None, + protocol_version: Some(params.protocol_version), fee_address: params.operator_address, fee_input: params.fee_input, }) @@ -351,63 +410,21 @@ impl StateKeeperIO for ExternalIO { .connection_tagged("sync_layer") .await? .protocol_versions_dal() - .load_base_system_contracts_by_version_id(protocol_version as u16) - .await - .context("failed loading base system contracts")?; - - if let Some(contracts) = base_system_contracts { - return Ok(contracts); - } - tracing::info!("Fetching protocol version {protocol_version:?} from the main node"); - - let protocol_version = self - .main_node_client - .fetch_protocol_version(protocol_version) - .await - .context("failed to fetch protocol version from the main node")? - .context("protocol version is missing on the main node")?; - let minor = protocol_version - .minor_version() - .context("Missing minor protocol version")?; - let bootloader_code_hash = protocol_version - .bootloader_code_hash() - .context("Missing bootloader code hash")?; - let default_account_code_hash = protocol_version - .default_account_code_hash() - .context("Missing default account code hash")?; - let evm_emulator_code_hash = protocol_version.evm_emulator_code_hash(); - let l2_system_upgrade_tx_hash = protocol_version.l2_system_upgrade_tx_hash(); - self.pool - .connection_tagged("sync_layer") + .get_base_system_contract_hashes_by_version_id(protocol_version as u16) .await? - .protocol_versions_dal() - .save_protocol_version( - ProtocolSemanticVersion { - minor: minor - .try_into() - .context("cannot convert protocol version")?, - patch: VersionPatch(0), - }, - protocol_version.timestamp, - Default::default(), // verification keys are unused for EN - BaseSystemContractsHashes { - bootloader: bootloader_code_hash, - default_aa: default_account_code_hash, - evm_emulator: evm_emulator_code_hash, - }, - l2_system_upgrade_tx_hash, - ) - .await?; + .with_context(|| { + format!("Cannot load base system contracts' hashes for {protocol_version:?}. They should already be present") + })?; let bootloader = self - .get_base_system_contract(bootloader_code_hash, cursor.next_l2_block) + .get_base_system_contract(base_system_contracts.bootloader, cursor.next_l2_block) .await .with_context(|| format!("cannot fetch bootloader code for {protocol_version:?}"))?; let default_aa = self - .get_base_system_contract(default_account_code_hash, cursor.next_l2_block) + .get_base_system_contract(base_system_contracts.default_aa, cursor.next_l2_block) .await .with_context(|| format!("cannot fetch default AA code for {protocol_version:?}"))?; - let evm_emulator = if let Some(hash) = evm_emulator_code_hash { + let evm_emulator = if let Some(hash) = base_system_contracts.evm_emulator { Some( self.get_base_system_contract(hash, cursor.next_l2_block) .await @@ -459,3 +476,97 @@ impl StateKeeperIO for ExternalIO { Ok(hash) } } + +#[cfg(test)] +mod tests { + use std::time::Duration; + + use zksync_dal::{ConnectionPool, CoreDal}; + use zksync_node_genesis::{insert_genesis_batch, GenesisParams}; + use zksync_state_keeper::{io::L1BatchParams, L2BlockParams, StateKeeperIO}; + use zksync_types::{ + api, fee_model::BatchFeeInput, L1BatchNumber, L2BlockNumber, L2ChainId, ProtocolVersionId, + H256, + }; + + use crate::{sync_action::SyncAction, testonly::MockMainNodeClient, ActionQueue, ExternalIO}; + + #[tokio::test] + async fn insert_batch_with_protocol_version() { + // Whenever ExternalIO inserts an unsealed batch into DB it should populate it with protocol + // version and make sure that it is present in the DB (i.e. fetch it from main node if not). + let pool = ConnectionPool::test_pool().await; + let mut conn = pool.connection().await.unwrap(); + insert_genesis_batch(&mut conn, &GenesisParams::mock()) + .await + .unwrap(); + let (actions_sender, action_queue) = ActionQueue::new(); + let mut client = MockMainNodeClient::default(); + let next_protocol_version = api::ProtocolVersion { + minor_version: Some(ProtocolVersionId::next() as u16), + timestamp: 1, + bootloader_code_hash: Some(H256::repeat_byte(1)), + default_account_code_hash: Some(H256::repeat_byte(1)), + evm_emulator_code_hash: Some(H256::repeat_byte(1)), + ..api::ProtocolVersion::default() + }; + client.insert_protocol_version(next_protocol_version.clone()); + let mut external_io = ExternalIO::new( + pool.clone(), + action_queue, + Box::new(client), + L2ChainId::default(), + ) + .unwrap(); + + let (cursor, _) = external_io.initialize().await.unwrap(); + let params = L1BatchParams { + protocol_version: ProtocolVersionId::next(), + validation_computational_gas_limit: u32::MAX, + operator_address: Default::default(), + fee_input: BatchFeeInput::pubdata_independent(2, 3, 4), + first_l2_block: L2BlockParams { + timestamp: 1, + virtual_blocks: 1, + }, + }; + actions_sender + .push_action_unchecked(SyncAction::OpenBatch { + params: params.clone(), + number: L1BatchNumber(1), + first_l2_block_number: L2BlockNumber(1), + }) + .await + .unwrap(); + let fetched_params = external_io + .wait_for_new_batch_params(&cursor, Duration::from_secs(10)) + .await + .unwrap() + .unwrap(); + assert_eq!(fetched_params, params); + + // Verify that the next protocol version is in DB + let fetched_protocol_version = conn + .protocol_versions_dal() + .get_protocol_version_with_latest_patch(ProtocolVersionId::next()) + .await + .unwrap() + .unwrap(); + assert_eq!( + fetched_protocol_version.version.minor as u16, + next_protocol_version.minor_version.unwrap() + ); + + // Verify that the unsealed batch has protocol version + let unsealed_batch = conn + .blocks_dal() + .get_unsealed_l1_batch() + .await + .unwrap() + .unwrap(); + assert_eq!( + unsealed_batch.protocol_version, + Some(fetched_protocol_version.version.minor) + ); + } +} From cd160830a0b7ebe5af4ecbd944da1cd51af3528a Mon Sep 17 00:00:00 2001 From: perekopskiy <53865202+perekopskiy@users.noreply.github.com> Date: Mon, 21 Oct 2024 15:35:40 +0300 Subject: [PATCH 02/27] fix(mempool): minor mempool improvements (#3113) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## What ❔ fixes two mempool issues: 1) `gc` does not really ensure `size <= capatity` (found by @jcsec-security), fix: purge some accounts with lowest score from priority queue 2) Mempool actor built l2 tx filter based on current l1 gas prices. This doesn't make sense when there is an open batch, if there is some then we should use its fee params. ## Checklist - [ ] PR title corresponds to the body of PR (we generate changelog entries from PRs). - [ ] Tests for the changes have been added / updated. - [ ] Documentation comments have been added / updated. - [ ] Code has been formatted via `zkstack dev fmt` and `zkstack dev lint`. --- core/lib/mempool/src/mempool_store.rs | 55 +++++++++++++++++---- core/lib/mempool/src/tests.rs | 50 +++++++++++++------ core/node/state_keeper/src/mempool_actor.rs | 31 +++++++++--- 3 files changed, 104 insertions(+), 32 deletions(-) diff --git a/core/lib/mempool/src/mempool_store.rs b/core/lib/mempool/src/mempool_store.rs index 334a4783a76c..f6f9b72f9b64 100644 --- a/core/lib/mempool/src/mempool_store.rs +++ b/core/lib/mempool/src/mempool_store.rs @@ -1,4 +1,4 @@ -use std::collections::{hash_map, BTreeSet, HashMap, HashSet}; +use std::collections::{hash_map, BTreeSet, HashMap}; use zksync_types::{ l1::L1Tx, l2::L2Tx, Address, ExecuteTransactionCommon, Nonce, PriorityOpId, Transaction, @@ -221,22 +221,57 @@ impl MempoolStore { } fn gc(&mut self) -> Vec
{ - if self.size >= self.capacity { - let index: HashSet<_> = self + if self.size > self.capacity { + let mut transactions = std::mem::take(&mut self.l2_transactions_per_account); + let mut possibly_kept: Vec<_> = self .l2_priority_queue .iter() - .map(|pointer| pointer.account) + .rev() + .filter_map(|pointer| { + transactions + .remove(&pointer.account) + .map(|txs| (pointer.account, txs)) + }) .collect(); - let transactions = std::mem::take(&mut self.l2_transactions_per_account); - let (kept, drained) = transactions + + let mut sum = 0; + let mut number_of_accounts_kept = 0; + for (_, txs) in &possibly_kept { + sum += txs.len(); + if sum <= self.capacity as usize { + number_of_accounts_kept += 1; + } else { + break; + } + } + if number_of_accounts_kept == 0 && !possibly_kept.is_empty() { + tracing::warn!("mempool capacity is too low to handle txs from single account, consider increasing capacity"); + // Keep at least one entry, otherwise mempool won't return any new L2 tx to process. + number_of_accounts_kept = 1; + } + let (kept, drained) = { + let mut drained: Vec<_> = transactions.into_keys().collect(); + let also_drained = possibly_kept + .split_off(number_of_accounts_kept) + .into_iter() + .map(|(address, _)| address); + drained.extend(also_drained); + + (possibly_kept, drained) + }; + + let l2_priority_queue = std::mem::take(&mut self.l2_priority_queue); + self.l2_priority_queue = l2_priority_queue .into_iter() - .partition(|(address, _)| index.contains(address)); - self.l2_transactions_per_account = kept; + .rev() + .take(number_of_accounts_kept) + .collect(); + self.l2_transactions_per_account = kept.into_iter().collect(); self.size = self .l2_transactions_per_account .iter() - .fold(0, |agg, (_, tnxs)| agg + tnxs.len() as u64); - return drained.into_keys().collect(); + .fold(0, |agg, (_, txs)| agg + txs.len() as u64); + return drained; } vec![] } diff --git a/core/lib/mempool/src/tests.rs b/core/lib/mempool/src/tests.rs index 96ef600984f9..b84ab7d57651 100644 --- a/core/lib/mempool/src/tests.rs +++ b/core/lib/mempool/src/tests.rs @@ -321,32 +321,26 @@ fn stashed_accounts() { #[test] fn mempool_capacity() { - let mut mempool = MempoolStore::new(PriorityOpId(0), 5); + let mut mempool = MempoolStore::new(PriorityOpId(0), 4); let account0 = Address::random(); let account1 = Address::random(); let account2 = Address::random(); + let account3 = Address::random(); let transactions = vec![ gen_l2_tx(account0, Nonce(0)), gen_l2_tx(account0, Nonce(1)), gen_l2_tx(account0, Nonce(2)), - gen_l2_tx(account1, Nonce(1)), - gen_l2_tx(account2, Nonce(1)), + gen_l2_tx_with_timestamp(account1, Nonce(0), unix_timestamp_ms() + 1), + gen_l2_tx_with_timestamp(account2, Nonce(0), unix_timestamp_ms() + 2), + gen_l2_tx(account3, Nonce(1)), ]; mempool.insert(transactions, HashMap::new()); - // the mempool is full. Accounts with non-sequential nonces got stashed + // Mempool is full. Accounts with non-sequential nonces and some accounts with lowest score should be purged. assert_eq!( HashSet::<_>::from_iter(mempool.get_mempool_info().purged_accounts), - HashSet::<_>::from_iter(vec![account1, account2]), - ); - // verify that existing good-to-go transactions and new ones got picked - mempool.insert( - vec![gen_l2_tx_with_timestamp( - account1, - Nonce(0), - unix_timestamp_ms() + 1, - )], - HashMap::new(), + HashSet::from([account2, account3]), ); + // verify that good-to-go transactions are kept. for _ in 0..3 { assert_eq!( mempool @@ -363,6 +357,34 @@ fn mempool_capacity() { .initiator_account(), account1 ); + assert!(!mempool.has_next(&L2TxFilter::default())); +} + +#[test] +fn mempool_does_not_purge_all_accounts() { + let mut mempool = MempoolStore::new(PriorityOpId(0), 1); + let account0 = Address::random(); + let account1 = Address::random(); + let transactions = vec![ + gen_l2_tx(account0, Nonce(0)), + gen_l2_tx(account0, Nonce(1)), + gen_l2_tx(account1, Nonce(1)), + ]; + mempool.insert(transactions, HashMap::new()); + // Mempool is full. Account 1 has tx with non-sequential nonce so it should be purged. + // Txs from account 0 have sequential nonces but their number is greater than capacity; they should be kept. + assert_eq!(mempool.get_mempool_info().purged_accounts, vec![account1]); + // verify that good-to-go transactions are kept. + for _ in 0..2 { + assert_eq!( + mempool + .next_transaction(&L2TxFilter::default()) + .unwrap() + .initiator_account(), + account0 + ); + } + assert!(!mempool.has_next(&L2TxFilter::default())); } fn gen_l2_tx(address: Address, nonce: Nonce) -> Transaction { diff --git a/core/node/state_keeper/src/mempool_actor.rs b/core/node/state_keeper/src/mempool_actor.rs index dbe1e4cb977f..a17f2670cbb9 100644 --- a/core/node/state_keeper/src/mempool_actor.rs +++ b/core/node/state_keeper/src/mempool_actor.rs @@ -89,20 +89,35 @@ impl MempoolFetcher { .await .context("failed getting pending protocol version")?; - let l2_tx_filter = l2_tx_filter( - self.batch_fee_input_provider.as_ref(), - protocol_version.into(), - ) - .await - .context("failed creating L2 transaction filter")?; + let (fee_per_gas, gas_per_pubdata) = if let Some(unsealed_batch) = storage + .blocks_dal() + .get_unsealed_l1_batch() + .await + .context("failed getting unsealed batch")? + { + let (fee_per_gas, gas_per_pubdata) = derive_base_fee_and_gas_per_pubdata( + unsealed_batch.fee_input, + protocol_version.into(), + ); + (fee_per_gas, gas_per_pubdata as u32) + } else { + let filter = l2_tx_filter( + self.batch_fee_input_provider.as_ref(), + protocol_version.into(), + ) + .await + .context("failed creating L2 transaction filter")?; + + (filter.fee_per_gas, filter.gas_per_pubdata) + }; let transactions = storage .transactions_dal() .sync_mempool( &mempool_info.stashed_accounts, &mempool_info.purged_accounts, - l2_tx_filter.gas_per_pubdata, - l2_tx_filter.fee_per_gas, + gas_per_pubdata, + fee_per_gas, self.sync_batch_size, ) .await From 0757ecd56e531888127cd146f8c2745099a6ed93 Mon Sep 17 00:00:00 2001 From: Daniyar Itegulov Date: Mon, 21 Oct 2024 23:52:59 +1100 Subject: [PATCH 03/27] chore(zkstack_cli): build sys contract with `--frozen-lockfile` (#3138) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## What ❔ ## Why ❔ ## Checklist - [ ] PR title corresponds to the body of PR (we generate changelog entries from PRs). - [ ] Tests for the changes have been added / updated. - [ ] Documentation comments have been added / updated. - [ ] Code has been formatted via `zkstack dev fmt` and `zkstack dev lint`. --- zkstack_cli/crates/common/src/contracts.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/zkstack_cli/crates/common/src/contracts.rs b/zkstack_cli/crates/common/src/contracts.rs index c95849131c1f..8f5ae8056029 100644 --- a/zkstack_cli/crates/common/src/contracts.rs +++ b/zkstack_cli/crates/common/src/contracts.rs @@ -26,7 +26,8 @@ pub fn build_l2_contracts(shell: Shell, link_to_code: PathBuf) -> anyhow::Result pub fn build_system_contracts(shell: Shell, link_to_code: PathBuf) -> anyhow::Result<()> { let _dir_guard = shell.push_dir(link_to_code.join("contracts/system-contracts")); - Cmd::new(cmd!(shell, "yarn install")).run()?; + // Do not update era-contract's lockfile to avoid dirty submodule + Cmd::new(cmd!(shell, "yarn install --frozen-lockfile")).run()?; Cmd::new(cmd!(shell, "yarn preprocess:system-contracts")).run()?; Cmd::new(cmd!( shell, From 7c289649b7b3c418c7193a35b51c264cf4970f3c Mon Sep 17 00:00:00 2001 From: Yury Akudovich Date: Mon, 21 Oct 2024 16:01:59 +0200 Subject: [PATCH 04/27] feat(prover): Add min_provers and dry_run features. Improve metrics and test. (#3129) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## What ❔ Improve metrics and test. Add min_provers config. Add dry_run config option for Agent. ## Why ❔ ## Checklist - [x] PR title corresponds to the body of PR (we generate changelog entries from PRs). - [x] Tests for the changes have been added / updated. - [ ] Documentation comments have been added / updated. - [x] Code has been formatted via `zkstack dev fmt` and `zkstack dev lint`. --- .../config/src/configs/prover_autoscaler.rs | 9 + .../src/proto/config/prover_autoscaler.proto | 7 + .../protobuf_config/src/prover_autoscaler.rs | 32 +- prover/Cargo.lock | 22 + prover/Cargo.toml | 1 + .../crates/bin/prover_autoscaler/Cargo.toml | 1 + .../prover_autoscaler/src/global/queuer.rs | 18 +- .../prover_autoscaler/src/global/scaler.rs | 399 +++++++++++++++--- .../prover_autoscaler/src/global/watcher.rs | 21 +- .../bin/prover_autoscaler/src/k8s/scaler.rs | 15 + .../bin/prover_autoscaler/src/k8s/watcher.rs | 7 +- .../crates/bin/prover_autoscaler/src/main.rs | 2 +- .../bin/prover_autoscaler/src/metrics.rs | 10 +- 13 files changed, 467 insertions(+), 77 deletions(-) diff --git a/core/lib/config/src/configs/prover_autoscaler.rs b/core/lib/config/src/configs/prover_autoscaler.rs index 6f83f0d2d18b..b24a1a26651f 100644 --- a/core/lib/config/src/configs/prover_autoscaler.rs +++ b/core/lib/config/src/configs/prover_autoscaler.rs @@ -30,6 +30,9 @@ pub struct ProverAutoscalerAgentConfig { pub namespaces: Vec, /// Watched cluster name. Also can be set via flag. pub cluster_name: Option, + /// If dry-run enabled don't do any k8s updates, just report success. + #[serde(default = "ProverAutoscalerAgentConfig::default_dry_run")] + pub dry_run: bool, } #[derive(Debug, Clone, PartialEq, Deserialize, Default)] @@ -53,6 +56,8 @@ pub struct ProverAutoscalerScalerConfig { pub prover_speed: HashMap, /// Maximum number of provers which can be run per cluster/GPU. pub max_provers: HashMap>, + /// Minimum number of provers per namespace. + pub min_provers: HashMap, /// Duration after which pending pod considered long pending. #[serde(default = "ProverAutoscalerScalerConfig::default_long_pending_duration")] pub long_pending_duration: Duration, @@ -99,6 +104,10 @@ impl ProverAutoscalerAgentConfig { pub fn default_namespaces() -> Vec { vec!["prover-blue".to_string(), "prover-red".to_string()] } + + pub fn default_dry_run() -> bool { + true + } } impl ProverAutoscalerScalerConfig { diff --git a/core/lib/protobuf_config/src/proto/config/prover_autoscaler.proto b/core/lib/protobuf_config/src/proto/config/prover_autoscaler.proto index 8363b6251199..9b7f201e9b77 100644 --- a/core/lib/protobuf_config/src/proto/config/prover_autoscaler.proto +++ b/core/lib/protobuf_config/src/proto/config/prover_autoscaler.proto @@ -17,6 +17,7 @@ message ProverAutoscalerAgentConfig { optional uint32 http_port = 2; // required repeated string namespaces = 3; // optional optional string cluster_name = 4; // optional + optional bool dry_run = 5; // optional } message ProtocolVersion { @@ -39,6 +40,11 @@ message MaxProver { optional uint32 max = 2; // required } +message MinProver { + optional string namespace = 1; // required + optional uint32 min = 2; // required +} + message ProverAutoscalerScalerConfig { optional uint32 prometheus_port = 1; // required optional std.Duration scaler_run_interval = 2; // optional @@ -49,4 +55,5 @@ message ProverAutoscalerScalerConfig { repeated ProverSpeed prover_speed = 7; // optional optional uint32 long_pending_duration_s = 8; // optional repeated MaxProver max_provers = 9; // optional + repeated MinProver min_provers = 10; // optional } diff --git a/core/lib/protobuf_config/src/prover_autoscaler.rs b/core/lib/protobuf_config/src/prover_autoscaler.rs index e95e4003972e..51f1b162d4cf 100644 --- a/core/lib/protobuf_config/src/prover_autoscaler.rs +++ b/core/lib/protobuf_config/src/prover_autoscaler.rs @@ -1,6 +1,6 @@ use std::collections::HashMap; -use anyhow::Context as _; +use anyhow::Context; use time::Duration; use zksync_config::configs::{self, prover_autoscaler::Gpu}; use zksync_protobuf::{read_optional, repr::ProtoRepr, required, ProtoFmt}; @@ -42,6 +42,7 @@ impl ProtoRepr for proto::ProverAutoscalerAgentConfig { .context("http_port")?, namespaces: self.namespaces.to_vec(), cluster_name: Some("".to_string()), + dry_run: self.dry_run.unwrap_or(Self::Type::default_dry_run()), }) } @@ -51,6 +52,7 @@ impl ProtoRepr for proto::ProverAutoscalerAgentConfig { http_port: Some(this.http_port.into()), namespaces: this.namespaces.clone(), cluster_name: this.cluster_name.clone(), + dry_run: Some(this.dry_run), } } } @@ -103,6 +105,13 @@ impl ProtoRepr for proto::ProverAutoscalerScalerConfig { } acc }), + min_provers: self + .min_provers + .iter() + .enumerate() + .map(|(i, e)| e.read().context(i)) + .collect::>() + .context("min_provers")?, }) } @@ -137,6 +146,11 @@ impl ProtoRepr for proto::ProverAutoscalerScalerConfig { }) }) .collect(), + min_provers: this + .min_provers + .iter() + .map(|(k, v)| proto::MinProver::build(&(k.clone(), *v))) + .collect(), } } } @@ -208,3 +222,19 @@ impl ProtoRepr for proto::MaxProver { } } } + +impl ProtoRepr for proto::MinProver { + type Type = (String, u32); + fn read(&self) -> anyhow::Result { + Ok(( + required(&self.namespace).context("namespace")?.clone(), + *required(&self.min).context("min")?, + )) + } + fn build(this: &Self::Type) -> Self { + Self { + namespace: Some(this.0.to_string()), + min: Some(this.1), + } + } +} diff --git a/prover/Cargo.lock b/prover/Cargo.lock index dd2df67902ff..e5b42f1601b1 100644 --- a/prover/Cargo.lock +++ b/prover/Cargo.lock @@ -6702,6 +6702,27 @@ dependencies = [ "tracing-serde", ] +[[package]] +name = "tracing-test" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "557b891436fe0d5e0e363427fc7f217abf9ccd510d5136549847bdcbcd011d68" +dependencies = [ + "tracing-core", + "tracing-subscriber", + "tracing-test-macro", +] + +[[package]] +name = "tracing-test-macro" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04659ddb06c87d233c566112c1c9c5b9e98256d9af50ec3bc9c8327f873a7568" +dependencies = [ + "quote 1.0.36", + "syn 2.0.66", +] + [[package]] name = "try-lock" version = "0.2.5" @@ -8300,6 +8321,7 @@ dependencies = [ "tokio", "tracing", "tracing-subscriber", + "tracing-test", "url", "vise", "zksync_config", diff --git a/prover/Cargo.toml b/prover/Cargo.toml index 61169dd43636..af022e691c1f 100644 --- a/prover/Cargo.toml +++ b/prover/Cargo.toml @@ -58,6 +58,7 @@ tokio-util = "0.7.11" toml_edit = "0.14.4" tracing = "0.1" tracing-subscriber = "0.3" +tracing-test = "0.2.5" url = "2.5.2" vise = "0.2.0" diff --git a/prover/crates/bin/prover_autoscaler/Cargo.toml b/prover/crates/bin/prover_autoscaler/Cargo.toml index 9743b45593e7..fbf3ecae9098 100644 --- a/prover/crates/bin/prover_autoscaler/Cargo.toml +++ b/prover/crates/bin/prover_autoscaler/Cargo.toml @@ -43,3 +43,4 @@ tracing-subscriber = { workspace = true, features = ["env-filter"] } tracing.workspace = true url.workspace = true vise.workspace = true +tracing-test.workspace = true diff --git a/prover/crates/bin/prover_autoscaler/src/global/queuer.rs b/prover/crates/bin/prover_autoscaler/src/global/queuer.rs index 1ef5d96386b5..32610ebf3c3d 100644 --- a/prover/crates/bin/prover_autoscaler/src/global/queuer.rs +++ b/prover/crates/bin/prover_autoscaler/src/global/queuer.rs @@ -5,6 +5,10 @@ use reqwest::Method; use zksync_prover_job_monitor::autoscaler_queue_reporter::VersionedQueueReport; use zksync_utils::http_with_retries::send_request_with_retries; +use crate::metrics::{AUTOSCALER_METRICS, DEFAULT_ERROR_CODE}; + +const MAX_RETRIES: usize = 5; + #[derive(Debug)] pub struct Queue { pub queue: HashMap, @@ -24,15 +28,19 @@ impl Queuer { pub async fn get_queue(&self) -> anyhow::Result { let url = &self.prover_job_monitor_url; - let response = send_request_with_retries(url, 5, Method::GET, None, None).await; - let res = response - .map_err(|err| anyhow::anyhow!("Failed fetching queue from url: {url}: {err:?}"))? + let response = send_request_with_retries(url, MAX_RETRIES, Method::GET, None, None).await; + let response = response.map_err(|err| { + AUTOSCALER_METRICS.calls[&(url.clone(), DEFAULT_ERROR_CODE)].inc(); + anyhow::anyhow!("Failed fetching queue from url: {url}: {err:?}") + })?; + + AUTOSCALER_METRICS.calls[&(url.clone(), response.status().as_u16())].inc(); + let response = response .json::>() .await .context("Failed to read response as json")?; - Ok(Queue { - queue: res + queue: response .iter() .map(|x| (x.version.to_string(), x.report.prover_jobs.queued as u64)) .collect::>(), diff --git a/prover/crates/bin/prover_autoscaler/src/global/scaler.rs b/prover/crates/bin/prover_autoscaler/src/global/scaler.rs index dd3f3cf1ad3a..f10902f5dd2f 100644 --- a/prover/crates/bin/prover_autoscaler/src/global/scaler.rs +++ b/prover/crates/bin/prover_autoscaler/src/global/scaler.rs @@ -44,9 +44,9 @@ struct GPUPoolKey { } static PROVER_DEPLOYMENT_RE: Lazy = - Lazy::new(|| Regex::new(r"^prover-gpu-fri-spec-(\d{1,2})?(-(?[ltvpa]\d+))?$").unwrap()); + Lazy::new(|| Regex::new(r"^circuit-prover-gpu(-(?[ltvpa]\d+))?$").unwrap()); static PROVER_POD_RE: Lazy = - Lazy::new(|| Regex::new(r"^prover-gpu-fri-spec-(\d{1,2})?(-(?[ltvpa]\d+))?").unwrap()); + Lazy::new(|| Regex::new(r"^circuit-prover-gpu(-(?[ltvpa]\d+))?").unwrap()); pub struct Scaler { /// namespace to Protocol Version configuration. @@ -56,6 +56,7 @@ pub struct Scaler { /// Which cluster to use first. cluster_priorities: HashMap, + min_provers: HashMap, max_provers: HashMap>, prover_speed: HashMap, long_pending_duration: chrono::Duration, @@ -83,11 +84,19 @@ impl Scaler { queuer: queuer::Queuer, config: ProverAutoscalerScalerConfig, ) -> Self { + config + .protocol_versions + .iter() + .for_each(|(namespace, version)| { + AUTOSCALER_METRICS.prover_protocol_version[&(namespace.clone(), version.clone())] + .set(1); + }); Self { namespaces: config.protocol_versions, watcher, queuer, cluster_priorities: config.cluster_priorities, + min_provers: config.min_provers, max_provers: config.max_provers, prover_speed: config.prover_speed, long_pending_duration: chrono::Duration::seconds( @@ -200,16 +209,23 @@ impl Scaler { self.speed(gpu) * n as u64 } - fn normalize_queue(&self, gpu: Gpu, q: u64) -> u64 { + fn normalize_queue(&self, gpu: Gpu, queue: u64) -> u64 { let speed = self.speed(gpu); // Divide and round up if there's any remainder. - (q + speed - 1) / speed * speed + (queue + speed - 1) / speed * speed } - fn run(&self, namespace: &String, q: u64, clusters: &Clusters) -> HashMap { + fn run(&self, namespace: &String, queue: u64, clusters: &Clusters) -> HashMap { let sc = self.sorted_clusters(namespace, clusters); tracing::debug!("Sorted clusters for namespace {}: {:?}", namespace, &sc); + // Increase queue size, if it's too small, to make sure that required min_provers are + // running. + let queue: u64 = self.min_provers.get(namespace).map_or(queue, |min| { + self.normalize_queue(Gpu::L4, queue) + .max(self.provers_to_speed(Gpu::L4, *min)) + }); + let mut total: i64 = 0; let mut provers: HashMap = HashMap::new(); for c in &sc { @@ -228,9 +244,9 @@ impl Scaler { } // Remove unneeded pods. - if (total as u64) > self.normalize_queue(Gpu::L4, q) { + if (total as u64) > self.normalize_queue(Gpu::L4, queue) { for c in sc.iter().rev() { - let mut excess_queue = total as u64 - self.normalize_queue(c.gpu, q); + let mut excess_queue = total as u64 - self.normalize_queue(c.gpu, queue); let mut excess_provers = (excess_queue / self.speed(c.gpu)) as u32; let p = provers.entry(c.to_key()).or_default(); if *p < excess_provers { @@ -255,11 +271,11 @@ impl Scaler { } } - tracing::debug!("Queue coverd with provers: {}", total); + tracing::debug!("Queue covered with provers: {}", total); // Add required provers. - if (total as u64) < q { + if (total as u64) < queue { for c in &sc { - let mut required_queue = q - total as u64; + let mut required_queue = queue - total as u64; let mut required_provers = (self.normalize_queue(c.gpu, required_queue) / self.speed(c.gpu)) as u32; let p = provers.entry(c.to_key()).or_default(); @@ -306,6 +322,7 @@ impl Task for Scaler { let guard = self.watcher.data.lock().await; if let Err(err) = watcher::check_is_ready(&guard.is_ready) { + AUTOSCALER_METRICS.clusters_not_ready.inc(); tracing::warn!("Skipping Scaler run: {}", err); return Ok(()); } @@ -329,70 +346,342 @@ impl Task for Scaler { #[cfg(test)] mod tests { - use std::sync::Arc; - - use tokio::sync::Mutex; - use super::*; use crate::{ cluster_types::{Deployment, Namespace, Pod}, global::{queuer, watcher}, }; + #[tracing_test::traced_test] #[test] fn test_run() { - let watcher = watcher::Watcher { - cluster_agents: vec![], - data: Arc::new(Mutex::new(watcher::WatchedData::default())), - }; - let queuer = queuer::Queuer { - prover_job_monitor_url: "".to_string(), - }; let scaler = Scaler::new( - watcher, - queuer, + watcher::Watcher::default(), + queuer::Queuer::default(), ProverAutoscalerScalerConfig { - max_provers: HashMap::from([("foo".to_string(), HashMap::from([(Gpu::L4, 100)]))]), + cluster_priorities: [("foo".into(), 0), ("bar".into(), 10)].into(), + min_provers: [("prover-other".into(), 2)].into(), + max_provers: [ + ("foo".into(), [(Gpu::L4, 100)].into()), + ("bar".into(), [(Gpu::L4, 100)].into()), + ] + .into(), ..Default::default() }, ); - let got = scaler.run( - &"prover".to_string(), - 1499, - &Clusters { - clusters: HashMap::from([( - "foo".to_string(), - Cluster { - name: "foo".to_string(), - namespaces: HashMap::from([( - "prover".to_string(), - Namespace { - deployments: HashMap::from([( - "prover-gpu-fri-spec-1".to_string(), - Deployment { + + assert_eq!( + scaler.run( + &"prover".into(), + 1499, + &Clusters { + clusters: [( + "foo".into(), + Cluster { + name: "foo".into(), + namespaces: [( + "prover".into(), + Namespace { + deployments: [( + "circuit-prover-gpu".into(), + Deployment::default(), + )] + .into(), + pods: [( + "circuit-prover-gpu-7c5f8fc747-gmtcr".into(), + Pod { + status: "Running".into(), + ..Default::default() + }, + )] + .into(), + }, + )] + .into(), + }, + )] + .into(), + }, + ), + [( + GPUPoolKey { + cluster: "foo".into(), + gpu: Gpu::L4, + }, + 3, + )] + .into(), + "3 new provers" + ); + assert_eq!( + scaler.run( + &"prover".into(), + 499, + &Clusters { + clusters: [ + ( + "foo".into(), + Cluster { + name: "foo".into(), + namespaces: [( + "prover".into(), + Namespace { + deployments: [( + "circuit-prover-gpu".into(), + Deployment::default(), + )] + .into(), ..Default::default() }, - )]), - pods: HashMap::from([( - "prover-gpu-fri-spec-1-c47644679-x9xqp".to_string(), - Pod { - status: "Running".to_string(), - ..Default::default() + )] + .into(), + }, + ), + ( + "bar".into(), + Cluster { + name: "bar".into(), + namespaces: [( + "prover".into(), + Namespace { + deployments: [( + "circuit-prover-gpu".into(), + Deployment { + running: 1, + desired: 1, + }, + )] + .into(), + pods: [( + "circuit-prover-gpu-7c5f8fc747-gmtcr".into(), + Pod { + status: "Running".into(), + ..Default::default() + }, + )] + .into(), }, - )]), + )] + .into(), }, - )]), + ) + ] + .into(), + }, + ), + [ + ( + GPUPoolKey { + cluster: "foo".into(), + gpu: Gpu::L4, }, - )]), - }, + 0, + ), + ( + GPUPoolKey { + cluster: "bar".into(), + gpu: Gpu::L4, + }, + 1, + ) + ] + .into(), + "Preserve running" ); - let want = HashMap::from([( - GPUPoolKey { - cluster: "foo".to_string(), - gpu: Gpu::L4, + } + + #[tracing_test::traced_test] + #[test] + fn test_run_min_provers() { + let scaler = Scaler::new( + watcher::Watcher::default(), + queuer::Queuer::default(), + ProverAutoscalerScalerConfig { + cluster_priorities: [("foo".into(), 0), ("bar".into(), 10)].into(), + min_provers: [("prover".into(), 2)].into(), + max_provers: [ + ("foo".into(), [(Gpu::L4, 100)].into()), + ("bar".into(), [(Gpu::L4, 100)].into()), + ] + .into(), + ..Default::default() }, - 3, - )]); - assert_eq!(got, want); + ); + + assert_eq!( + scaler.run( + &"prover".into(), + 10, + &Clusters { + clusters: [ + ( + "foo".into(), + Cluster { + name: "foo".into(), + namespaces: [( + "prover".into(), + Namespace { + deployments: [( + "circuit-prover-gpu".into(), + Deployment::default(), + )] + .into(), + ..Default::default() + }, + )] + .into(), + }, + ), + ( + "bar".into(), + Cluster { + name: "bar".into(), + namespaces: [( + "prover".into(), + Namespace { + deployments: [( + "circuit-prover-gpu".into(), + Deployment::default(), + )] + .into(), + ..Default::default() + }, + )] + .into(), + }, + ) + ] + .into(), + }, + ), + [ + ( + GPUPoolKey { + cluster: "foo".into(), + gpu: Gpu::L4, + }, + 2, + ), + ( + GPUPoolKey { + cluster: "bar".into(), + gpu: Gpu::L4, + }, + 0, + ) + ] + .into(), + "Min 2 provers, non running" + ); + assert_eq!( + scaler.run( + &"prover".into(), + 0, + &Clusters { + clusters: [ + ( + "foo".into(), + Cluster { + name: "foo".into(), + namespaces: [( + "prover".into(), + Namespace { + deployments: [( + "circuit-prover-gpu".into(), + Deployment { + running: 3, + desired: 3, + }, + )] + .into(), + pods: [ + ( + "circuit-prover-gpu-7c5f8fc747-gmtcr".into(), + Pod { + status: "Running".into(), + ..Default::default() + }, + ), + ( + "circuit-prover-gpu-7c5f8fc747-gmtc2".into(), + Pod { + status: "Running".into(), + ..Default::default() + }, + ), + ( + "circuit-prover-gpu-7c5f8fc747-gmtc3".into(), + Pod { + status: "Running".into(), + ..Default::default() + }, + ) + ] + .into(), + }, + )] + .into(), + }, + ), + ( + "bar".into(), + Cluster { + name: "bar".into(), + namespaces: [( + "prover".into(), + Namespace { + deployments: [( + "circuit-prover-gpu".into(), + Deployment { + running: 2, + desired: 2, + }, + )] + .into(), + pods: [ + ( + "circuit-prover-gpu-7c5f8fc747-gmtcr".into(), + Pod { + status: "Running".into(), + ..Default::default() + }, + ), + ( + "circuit-prover-gpu-7c5f8fc747-gmtc2".into(), + Pod { + status: "Running".into(), + ..Default::default() + }, + ) + ] + .into(), + }, + )] + .into(), + }, + ) + ] + .into(), + }, + ), + [ + ( + GPUPoolKey { + cluster: "foo".into(), + gpu: Gpu::L4, + }, + 2, + ), + ( + GPUPoolKey { + cluster: "bar".into(), + gpu: Gpu::L4, + }, + 0, + ) + ] + .into(), + "Min 2 provers, 5 running" + ); } } diff --git a/prover/crates/bin/prover_autoscaler/src/global/watcher.rs b/prover/crates/bin/prover_autoscaler/src/global/watcher.rs index 01fa68c60f84..646b320e12df 100644 --- a/prover/crates/bin/prover_autoscaler/src/global/watcher.rs +++ b/prover/crates/bin/prover_autoscaler/src/global/watcher.rs @@ -9,9 +9,12 @@ use zksync_utils::http_with_retries::send_request_with_retries; use crate::{ cluster_types::{Cluster, Clusters}, + metrics::{AUTOSCALER_METRICS, DEFAULT_ERROR_CODE}, task_wiring::Task, }; +const MAX_RETRIES: usize = 5; + #[derive(Default)] pub struct WatchedData { pub clusters: Clusters, @@ -27,7 +30,7 @@ pub fn check_is_ready(v: &Vec) -> Result<()> { Ok(()) } -#[derive(Clone)] +#[derive(Default, Clone)] pub struct Watcher { /// List of base URLs of all agents. pub cluster_agents: Vec>, @@ -74,15 +77,19 @@ impl Task for Watcher { .context("Failed to join URL with /cluster")? .to_string(); let response = - send_request_with_retries(&url, 5, Method::GET, None, None).await; - let res = response - .map_err(|err| { - anyhow::anyhow!("Failed fetching cluster from url: {url}: {err:?}") - })? + send_request_with_retries(&url, MAX_RETRIES, Method::GET, None, None).await; + + let response = response.map_err(|err| { + // TODO: refactor send_request_with_retries to return status. + AUTOSCALER_METRICS.calls[&(url.clone(), DEFAULT_ERROR_CODE)].inc(); + anyhow::anyhow!("Failed fetching cluster from url: {url}: {err:?}") + })?; + AUTOSCALER_METRICS.calls[&(url, response.status().as_u16())].inc(); + let response = response .json::() .await .context("Failed to read response as json"); - Ok((i, res)) + Ok((i, response)) }) }) .collect(); diff --git a/prover/crates/bin/prover_autoscaler/src/k8s/scaler.rs b/prover/crates/bin/prover_autoscaler/src/k8s/scaler.rs index 170b0b106507..5e6f56aacc93 100644 --- a/prover/crates/bin/prover_autoscaler/src/k8s/scaler.rs +++ b/prover/crates/bin/prover_autoscaler/src/k8s/scaler.rs @@ -4,9 +4,14 @@ use kube::api::{Api, Patch, PatchParams}; #[derive(Clone)] pub struct Scaler { pub client: kube::Client, + dry_run: bool, } impl Scaler { + pub fn new(client: kube::Client, dry_run: bool) -> Self { + Self { client, dry_run } + } + pub async fn scale(&self, namespace: &str, name: &str, size: i32) -> anyhow::Result<()> { let deployments: Api = Api::namespaced(self.client.clone(), namespace); @@ -18,6 +23,16 @@ impl Scaler { "replicas": size } }); + + if self.dry_run { + tracing::info!( + "Dry run of scaled deployment/{} to {} replica(s).", + name, + size + ); + return Ok(()); + } + let pp = PatchParams::default(); deployments.patch(name, &pp, &Patch::Merge(patch)).await?; tracing::info!("Scaled deployment/{} to {} replica(s).", name, size); diff --git a/prover/crates/bin/prover_autoscaler/src/k8s/watcher.rs b/prover/crates/bin/prover_autoscaler/src/k8s/watcher.rs index 8746d17663be..f94dfc3704fb 100644 --- a/prover/crates/bin/prover_autoscaler/src/k8s/watcher.rs +++ b/prover/crates/bin/prover_autoscaler/src/k8s/watcher.rs @@ -9,10 +9,7 @@ use kube::{ }; use tokio::sync::Mutex; -use crate::{ - cluster_types::{Cluster, Deployment, Namespace, Pod}, - metrics::AUTOSCALER_METRICS, -}; +use crate::cluster_types::{Cluster, Deployment, Namespace, Pod}; #[derive(Clone)] pub struct Watcher { @@ -38,8 +35,6 @@ impl Watcher { pub async fn run(self) -> anyhow::Result<()> { // TODO: add actual metrics - AUTOSCALER_METRICS.protocol_version.set(1); - AUTOSCALER_METRICS.calls.inc_by(1); // TODO: watch for a list of namespaces, get: // - deployments (name, running, desired) [done] diff --git a/prover/crates/bin/prover_autoscaler/src/main.rs b/prover/crates/bin/prover_autoscaler/src/main.rs index e3aec1fbd392..45e476079a55 100644 --- a/prover/crates/bin/prover_autoscaler/src/main.rs +++ b/prover/crates/bin/prover_autoscaler/src/main.rs @@ -95,7 +95,7 @@ async fn main() -> anyhow::Result<()> { // TODO: maybe get cluster name from curl -H "Metadata-Flavor: Google" // http://metadata.google.internal/computeMetadata/v1/instance/attributes/cluster-name let watcher = Watcher::new(client.clone(), cluster, agent_config.namespaces); - let scaler = Scaler { client }; + let scaler = Scaler::new(client, agent_config.dry_run); tasks.push(tokio::spawn(watcher.clone().run())); tasks.push(tokio::spawn(agent::run_server( agent_config.http_port, diff --git a/prover/crates/bin/prover_autoscaler/src/metrics.rs b/prover/crates/bin/prover_autoscaler/src/metrics.rs index 09cbaa6ba00f..d94ac8b97e97 100644 --- a/prover/crates/bin/prover_autoscaler/src/metrics.rs +++ b/prover/crates/bin/prover_autoscaler/src/metrics.rs @@ -1,13 +1,19 @@ use vise::{Counter, Gauge, LabeledFamily, Metrics}; use zksync_config::configs::prover_autoscaler::Gpu; +pub const DEFAULT_ERROR_CODE: u16 = 500; + #[derive(Debug, Metrics)] #[metrics(prefix = "autoscaler")] pub(crate) struct AutoscalerMetrics { - pub protocol_version: Gauge, - pub calls: Counter, + #[metrics(labels = ["target_namespace", "protocol_version"])] + pub prover_protocol_version: LabeledFamily<(String, String), Gauge, 2>, #[metrics(labels = ["target_cluster", "target_namespace", "gpu"])] pub provers: LabeledFamily<(String, String, Gpu), Gauge, 3>, + pub clusters_not_ready: Counter, + #[metrics(labels = ["target", "status"])] + pub calls: LabeledFamily<(String, u16), Counter, 2>, + // TODO: count of command send succes/fail } #[vise::register] From 7241ae139b2b6bf9a9966eaa2f22203583a3786f Mon Sep 17 00:00:00 2001 From: Harald Hoyer Date: Tue, 22 Oct 2024 09:29:51 +0200 Subject: [PATCH 05/27] fix(tee_prover): add zstd compression (#3144) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## What ❔ Add zstd compression for the HTTP connection between `proof_data_handler` and `zksync_tee_prover`. ## Why ❔ This enables faster intercloud communication. ## Checklist - [x] PR title corresponds to the body of PR (we generate changelog entries from PRs). - [ ] Tests for the changes have been added / updated. - [ ] Documentation comments have been added / updated. - [x] Code has been formatted via `zkstack dev fmt` and `zkstack dev lint`. --------- Signed-off-by: Harald Hoyer --- Cargo.lock | 37 +++++++++++++++++++++++++ core/bin/zksync_tee_prover/Cargo.toml | 2 +- core/node/proof_data_handler/Cargo.toml | 1 + core/node/proof_data_handler/src/lib.rs | 2 ++ 4 files changed, 41 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 5da4cc8c1439..05c26a748347 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -292,6 +292,20 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "async-compression" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd066d0b4ef8ecb03a55319dc13aa6910616d0f44008a045bb1835af830abff5" +dependencies = [ + "futures-core", + "memchr", + "pin-project-lite", + "tokio", + "zstd", + "zstd-safe", +] + [[package]] name = "async-executor" version = "1.13.1" @@ -5886,6 +5900,7 @@ version = "0.12.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8f4955649ef5c38cc7f9e8aa41761d48fb9677197daea9984dc54f56aad5e63" dependencies = [ + "async-compression", "base64 0.22.1", "bytes", "encoding_rs", @@ -8309,13 +8324,16 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e9cd434a998747dd2c4276bc96ee2e0c7a2eadf3cae88e52be55a05fa9053f5" dependencies = [ + "async-compression", "bitflags 2.6.0", "bytes", + "futures-core", "http 1.1.0", "http-body 1.0.1", "http-body-util", "pin-project-lite", "tokio", + "tokio-util", "tower-layer", "tower-service", ] @@ -10866,6 +10884,7 @@ dependencies = [ "serde_json", "tokio", "tower 0.4.13", + "tower-http", "tracing", "vise", "zksync_basic_types", @@ -11414,6 +11433,24 @@ dependencies = [ "zksync_types", ] +[[package]] +name = "zstd" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcf2b778a664581e31e389454a7072dab1647606d44f7feea22cd5abb9c9f3f9" +dependencies = [ + "zstd-safe", +] + +[[package]] +name = "zstd-safe" +version = "7.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54a3ab4db68cea366acc5c897c7b4d4d1b8994a9cd6e6f841f8964566a419059" +dependencies = [ + "zstd-sys", +] + [[package]] name = "zstd-sys" version = "2.0.13+zstd.1.5.6" diff --git a/core/bin/zksync_tee_prover/Cargo.toml b/core/bin/zksync_tee_prover/Cargo.toml index 85908eebeaaa..b853da348ee0 100644 --- a/core/bin/zksync_tee_prover/Cargo.toml +++ b/core/bin/zksync_tee_prover/Cargo.toml @@ -15,7 +15,7 @@ publish = false anyhow.workspace = true async-trait.workspace = true envy.workspace = true -reqwest.workspace = true +reqwest = { workspace = true, features = ["zstd"] } secp256k1 = { workspace = true, features = ["serde"] } serde = { workspace = true, features = ["derive"] } thiserror.workspace = true diff --git a/core/node/proof_data_handler/Cargo.toml b/core/node/proof_data_handler/Cargo.toml index 76dc89eda04b..e2ddc972a2f5 100644 --- a/core/node/proof_data_handler/Cargo.toml +++ b/core/node/proof_data_handler/Cargo.toml @@ -22,6 +22,7 @@ zksync_utils.workspace = true anyhow.workspace = true axum.workspace = true tokio.workspace = true +tower-http = { workspace = true, features = ["compression-zstd", "decompression-zstd"] } tracing.workspace = true [dev-dependencies] diff --git a/core/node/proof_data_handler/src/lib.rs b/core/node/proof_data_handler/src/lib.rs index a482a7bc07b2..661c76d20006 100644 --- a/core/node/proof_data_handler/src/lib.rs +++ b/core/node/proof_data_handler/src/lib.rs @@ -139,4 +139,6 @@ fn create_proof_processing_router( } router + .layer(tower_http::compression::CompressionLayer::new()) + .layer(tower_http::decompression::RequestDecompressionLayer::new().zstd(true)) } From abeee8190d3c3a5e577d71024bdfb30ff516ad03 Mon Sep 17 00:00:00 2001 From: Alex Ostrovski Date: Tue, 22 Oct 2024 16:19:30 +0300 Subject: [PATCH 06/27] fix(en): Return `SyncState` health check (#3142) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## What ❔ Returns `SyncState`-based health check, which was removed when transitioning to the node framework. ## Why ❔ This health check looks useful and is used at least in some internal automations. ## Checklist - [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`. --- core/bin/external_node/src/tests/mod.rs | 14 +++++++++++--- .../layers/state_keeper/external_io.rs | 6 ++++++ .../implementations/layers/sync_state_updater.rs | 8 ++++++++ core/node/node_sync/src/sync_state.rs | 1 + 4 files changed, 26 insertions(+), 3 deletions(-) diff --git a/core/bin/external_node/src/tests/mod.rs b/core/bin/external_node/src/tests/mod.rs index b21dbd0db9a3..c5dd88748e52 100644 --- a/core/bin/external_node/src/tests/mod.rs +++ b/core/bin/external_node/src/tests/mod.rs @@ -22,10 +22,18 @@ const POLL_INTERVAL: Duration = Duration::from_millis(100); #[tracing::instrument] // Add args to the test logs async fn external_node_basics(components_str: &'static str) { let _guard = zksync_vlog::ObservabilityBuilder::new().try_build().ok(); // Enable logging to simplify debugging - let (env, env_handles) = utils::TestEnvironment::with_genesis_block(components_str).await; - let expected_health_components = utils::expected_health_components(&env.components); + let mut expected_health_components = utils::expected_health_components(&env.components); + let expected_shutdown_components = expected_health_components.clone(); + let has_core_or_api = env.components.0.iter().any(|component| { + [Component::Core, Component::HttpApi, Component::WsApi].contains(component) + }); + if has_core_or_api { + // The `sync_state` component doesn't signal its shutdown, but should be present in the list of components + expected_health_components.push("sync_state"); + } + let l2_client = utils::mock_l2_client(&env); let eth_client = utils::mock_eth_client(env.config.diamond_proxy_address()); @@ -84,7 +92,7 @@ async fn external_node_basics(components_str: &'static str) { let health_data = app_health.check_health().await; tracing::info!(?health_data, "final health data"); assert_matches!(health_data.inner().status(), HealthStatus::ShutDown); - for name in expected_health_components { + for name in expected_shutdown_components { let component_health = &health_data.components()[name]; assert_matches!(component_health.status(), HealthStatus::ShutDown); } diff --git a/core/node/node_framework/src/implementations/layers/state_keeper/external_io.rs b/core/node/node_framework/src/implementations/layers/state_keeper/external_io.rs index 31b76550767c..2c23f5aa9a17 100644 --- a/core/node/node_framework/src/implementations/layers/state_keeper/external_io.rs +++ b/core/node/node_framework/src/implementations/layers/state_keeper/external_io.rs @@ -8,6 +8,7 @@ use zksync_types::L2ChainId; use crate::{ implementations::resources::{ action_queue::ActionQueueSenderResource, + healthcheck::AppHealthCheckResource, main_node_client::MainNodeClientResource, pools::{MasterPool, PoolResource}, state_keeper::{ConditionalSealerResource, StateKeeperIOResource}, @@ -26,6 +27,7 @@ pub struct ExternalIOLayer { #[derive(Debug, FromContext)] #[context(crate = crate)] pub struct Input { + pub app_health: AppHealthCheckResource, pub pool: PoolResource, pub main_node_client: MainNodeClientResource, } @@ -57,6 +59,10 @@ impl WiringLayer for ExternalIOLayer { async fn wire(self, input: Self::Input) -> Result { // Create `SyncState` resource. let sync_state = SyncState::default(); + let app_health = &input.app_health.0; + app_health + .insert_custom_component(Arc::new(sync_state.clone())) + .map_err(WiringError::internal)?; // Create `ActionQueueSender` resource. let (action_queue_sender, action_queue) = ActionQueue::new(); diff --git a/core/node/node_framework/src/implementations/layers/sync_state_updater.rs b/core/node/node_framework/src/implementations/layers/sync_state_updater.rs index 1f86b43f7a5b..dd2652dfddb0 100644 --- a/core/node/node_framework/src/implementations/layers/sync_state_updater.rs +++ b/core/node/node_framework/src/implementations/layers/sync_state_updater.rs @@ -1,9 +1,12 @@ +use std::sync::Arc; + use zksync_dal::{ConnectionPool, Core}; use zksync_node_sync::SyncState; use zksync_web3_decl::client::{DynClient, L2}; use crate::{ implementations::resources::{ + healthcheck::AppHealthCheckResource, main_node_client::MainNodeClientResource, pools::{MasterPool, PoolResource}, sync_state::SyncStateResource, @@ -24,6 +27,7 @@ pub struct SyncStateUpdaterLayer; pub struct Input { /// Fetched to check whether the `SyncState` was already provided by another layer. pub sync_state: Option, + pub app_health: AppHealthCheckResource, pub master_pool: PoolResource, pub main_node_client: MainNodeClientResource, } @@ -62,6 +66,10 @@ impl WiringLayer for SyncStateUpdaterLayer { let MainNodeClientResource(main_node_client) = input.main_node_client; let sync_state = SyncState::default(); + let app_health = &input.app_health.0; + app_health + .insert_custom_component(Arc::new(sync_state.clone())) + .map_err(WiringError::internal)?; Ok(Output { sync_state: Some(sync_state.clone().into()), diff --git a/core/node/node_sync/src/sync_state.rs b/core/node/node_sync/src/sync_state.rs index e061ff7da012..f8a2fe00ec09 100644 --- a/core/node/node_sync/src/sync_state.rs +++ b/core/node/node_sync/src/sync_state.rs @@ -173,6 +173,7 @@ impl CheckHealth for SyncState { Health::from(&*self.0.borrow()) } } + impl SyncStateInner { fn is_synced(&self) -> (bool, Option) { if let (Some(main_node_block), Some(local_block)) = (self.main_node_block, self.local_block) From b29be7d9a8c664beac5d8384548db54de0ba882f Mon Sep 17 00:00:00 2001 From: Manuel Mauro Date: Tue, 22 Oct 2024 16:45:10 +0200 Subject: [PATCH 07/27] feat(zkstack_cli): Autocompletion support (#3097) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## What ❔ Add autocomplete feature to zkstack: ```bash ❯ zkstack chain dev -- Chain related commands consensus -- Update ZKsync containers -- Run containers for local development contract-verifier -- Run contract verifier ecosystem -- Ecosystem related commands explorer -- Run block-explorer external-node -- External Node related commands help -- Print this message or the help of the given subcommand(s) markdown update -- portal -- Run dapp-portal prover -- Prover related commands server -- Run server ``` ```bash ❯ zkstack ecosystem build-transactions -- Create transactions to build ecosystem contracts change-default-chain -- Change the default chain create -- Create a new ecosystem and chain, setting necessary configurations for later initialization help -- Print this message or the help of the given subcommand(s) init -- Initialize ecosystem and chain, deploying necessary contracts and performing on-chain operations setup-observability -- Setup observability for the ecosystem, downloading Grafana dashboards from the era-observability repo ``` ## Why ❔ ## Checklist - [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`. --------- Co-authored-by: Danil --- .github/workflows/ci-core-lint-reusable.yml | 1 + zkstack_cli/Cargo.lock | 12 +- zkstack_cli/Cargo.toml | 3 +- zkstack_cli/crates/zkstack/Cargo.toml | 6 +- zkstack_cli/crates/zkstack/build.rs | 121 +- .../crates/zkstack/completion/_zkstack.zsh | 4997 ++++++++++++ .../crates/zkstack/completion/zkstack.fish | 701 ++ .../crates/zkstack/completion/zkstack.sh | 6998 +++++++++++++++++ .../zkstack/src/commands/args/autocomplete.rs | 13 + .../crates/zkstack/src/commands/args/mod.rs | 2 + .../zkstack/src/commands/autocomplete.rs | 52 + .../zkstack/src/commands/chain/args/create.rs | 4 +- .../src/commands/chain/args/init/configs.rs | 2 +- .../src/commands/chain/args/init/mod.rs | 2 +- .../zkstack/src/commands/dev/commands/lint.rs | 67 +- .../src/commands/dev/commands/lint_utils.rs | 1 + .../commands/dev/commands/test/args/fees.rs | 2 +- .../dev/commands/test/args/recovery.rs | 2 +- .../commands/dev/commands/test/args/revert.rs | 2 +- .../src/commands/ecosystem/args/create.rs | 4 +- .../src/commands/ecosystem/args/init.rs | 2 +- .../crates/zkstack/src/commands/mod.rs | 1 + zkstack_cli/crates/zkstack/src/main.rs | 78 +- zkstack_cli/crates/zkstack/src/messages.rs | 7 + 24 files changed, 13021 insertions(+), 59 deletions(-) create mode 100644 zkstack_cli/crates/zkstack/completion/_zkstack.zsh create mode 100644 zkstack_cli/crates/zkstack/completion/zkstack.fish create mode 100644 zkstack_cli/crates/zkstack/completion/zkstack.sh create mode 100644 zkstack_cli/crates/zkstack/src/commands/args/autocomplete.rs create mode 100644 zkstack_cli/crates/zkstack/src/commands/autocomplete.rs diff --git a/.github/workflows/ci-core-lint-reusable.yml b/.github/workflows/ci-core-lint-reusable.yml index 53b25835ff57..0babbd1c9db7 100644 --- a/.github/workflows/ci-core-lint-reusable.yml +++ b/.github/workflows/ci-core-lint-reusable.yml @@ -49,6 +49,7 @@ 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 autocompletion --check - name: Check Database run: | diff --git a/zkstack_cli/Cargo.lock b/zkstack_cli/Cargo.lock index 63561c02b9d8..7770d06a1977 100644 --- a/zkstack_cli/Cargo.lock +++ b/zkstack_cli/Cargo.lock @@ -609,6 +609,15 @@ dependencies = [ "terminal_size", ] +[[package]] +name = "clap_complete" +version = "4.5.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9646e2e245bf62f45d39a0f3f36f1171ad1ea0d6967fd114bca72cb02a8fcdfb" +dependencies = [ + "clap", +] + [[package]] name = "clap_derive" version = "4.5.18" @@ -6709,11 +6718,12 @@ dependencies = [ "chrono", "clap", "clap-markdown", + "clap_complete", "cliclack", "common", "config", + "dirs", "ethers", - "eyre", "futures", "human-panic", "lazy_static", diff --git a/zkstack_cli/Cargo.toml b/zkstack_cli/Cargo.toml index a805cf85d518..1f493f9c3e41 100644 --- a/zkstack_cli/Cargo.toml +++ b/zkstack_cli/Cargo.toml @@ -40,11 +40,12 @@ zksync_protobuf_build = "=0.5.0" # External dependencies anyhow = "1.0.82" clap = { version = "4.4", features = ["derive", "wrap_help", "string"] } +clap_complete = "4.5.33" +dirs = "5.0.1" slugify-rs = "0.0.3" cliclack = "0.2.5" console = "0.15.8" chrono = "0.4.38" -eyre = "0.6.12" ethers = "2.0" futures = "0.3.30" human-panic = "2.0" diff --git a/zkstack_cli/crates/zkstack/Cargo.toml b/zkstack_cli/crates/zkstack/Cargo.toml index a9fcecaf79b4..93a78c751b14 100644 --- a/zkstack_cli/crates/zkstack/Cargo.toml +++ b/zkstack_cli/crates/zkstack/Cargo.toml @@ -14,10 +14,12 @@ keywords.workspace = true anyhow.workspace = true chrono.workspace = true clap.workspace = true +clap_complete.workspace = true clap-markdown.workspace = true cliclack.workspace = true common.workspace = true config.workspace = true +dirs.workspace = true ethers.workspace = true futures.workspace = true human-panic.workspace = true @@ -49,6 +51,8 @@ rand.workspace = true zksync_consensus_utils.workspace = true [build-dependencies] -eyre.workspace = true +anyhow.workspace = true +clap_complete.workspace = true +dirs.workspace = true ethers.workspace = true zksync_protobuf_build.workspace = true diff --git a/zkstack_cli/crates/zkstack/build.rs b/zkstack_cli/crates/zkstack/build.rs index 92f34a542b7f..bccf5bae89f9 100644 --- a/zkstack_cli/crates/zkstack/build.rs +++ b/zkstack_cli/crates/zkstack/build.rs @@ -1,12 +1,23 @@ -use std::path::PathBuf; +use std::path::{Path, PathBuf}; +use anyhow::{anyhow, Context}; use ethers::contract::Abigen; -fn main() -> eyre::Result<()> { +const COMPLETION_DIR: &str = "completion"; + +fn main() -> anyhow::Result<()> { let outdir = PathBuf::from(std::env::var("OUT_DIR")?).canonicalize()?; - Abigen::new("ConsensusRegistry", "abi/ConsensusRegistry.json")? - .generate()? - .write_to_file(outdir.join("consensus_registry_abi.rs"))?; + Abigen::new("ConsensusRegistry", "abi/ConsensusRegistry.json") + .map_err(|_| anyhow!("Failed ABI deserialization"))? + .generate() + .map_err(|_| anyhow!("Failed ABI generation"))? + .write_to_file(outdir.join("consensus_registry_abi.rs")) + .context("Failed to write ABI to file")?; + + if let Err(e) = configure_shell_autocompletion() { + println!("cargo:warning=It was not possible to install autocomplete scripts. Please generate them manually with `zkstack autocomplete`"); + println!("cargo:error={}", e); + }; zksync_protobuf_build::Config { input_root: "src/commands/consensus/proto".into(), @@ -19,3 +30,103 @@ fn main() -> eyre::Result<()> { .unwrap(); Ok(()) } + +fn configure_shell_autocompletion() -> anyhow::Result<()> { + // Array of supported shells + let shells = [ + clap_complete::Shell::Bash, + clap_complete::Shell::Fish, + clap_complete::Shell::Zsh, + ]; + + for shell in shells { + std::fs::create_dir_all(&shell.autocomplete_folder()?) + .context("it was impossible to create the configuration directory")?; + + let src = Path::new(COMPLETION_DIR).join(shell.autocomplete_file_name()?); + let dst = shell + .autocomplete_folder()? + .join(shell.autocomplete_file_name()?); + + std::fs::copy(src, dst)?; + + shell + .configure_autocomplete() + .context("failed to run extra configuration requirements")?; + } + + Ok(()) +} + +pub trait ShellAutocomplete { + fn autocomplete_folder(&self) -> anyhow::Result; + fn autocomplete_file_name(&self) -> anyhow::Result; + /// Extra steps required for shells enable command autocomplete. + fn configure_autocomplete(&self) -> anyhow::Result<()>; +} + +impl ShellAutocomplete for clap_complete::Shell { + fn autocomplete_folder(&self) -> anyhow::Result { + let home_dir = dirs::home_dir().context("missing home folder")?; + + match self { + clap_complete::Shell::Bash => Ok(home_dir.join(".bash_completion.d")), + clap_complete::Shell::Fish => Ok(home_dir.join(".config/fish/completions")), + clap_complete::Shell::Zsh => Ok(home_dir.join(".zsh/completion")), + _ => anyhow::bail!("unsupported shell"), + } + } + + fn autocomplete_file_name(&self) -> anyhow::Result { + let crate_name = env!("CARGO_PKG_NAME"); + + match self { + clap_complete::Shell::Bash => Ok(format!("{}.sh", crate_name)), + clap_complete::Shell::Fish => Ok(format!("{}.fish", crate_name)), + clap_complete::Shell::Zsh => Ok(format!("_{}.zsh", crate_name)), + _ => anyhow::bail!("unsupported shell"), + } + } + + fn configure_autocomplete(&self) -> anyhow::Result<()> { + match self { + clap_complete::Shell::Bash | clap_complete::Shell::Zsh => { + let shell = &self.to_string().to_lowercase(); + let completion_file = self + .autocomplete_folder()? + .join(self.autocomplete_file_name()?); + + // Source the completion file inside .{shell}rc + let shell_rc = dirs::home_dir() + .context("missing home directory")? + .join(format!(".{}rc", shell)); + + if shell_rc.exists() { + let shell_rc_content = std::fs::read_to_string(&shell_rc) + .context(format!("could not read .{}rc", shell))?; + + if !shell_rc_content.contains("# zkstack completion") { + std::fs::write( + shell_rc, + format!( + "{}\n# zkstack completion\nsource \"{}\"\n", + shell_rc_content, + completion_file.to_str().unwrap() + ), + ) + .context(format!("could not write .{}rc", shell))?; + } + } else { + println!( + "cargo:warning=Please add the following line to your .{}rc:", + shell + ); + println!("cargo:warning=source {}", completion_file.to_str().unwrap()); + } + } + _ => (), + } + + Ok(()) + } +} diff --git a/zkstack_cli/crates/zkstack/completion/_zkstack.zsh b/zkstack_cli/crates/zkstack/completion/_zkstack.zsh new file mode 100644 index 000000000000..a8a60a6130a6 --- /dev/null +++ b/zkstack_cli/crates/zkstack/completion/_zkstack.zsh @@ -0,0 +1,4997 @@ +#compdef zkstack + +autoload -U is-at-least + +_zkstack() { + typeset -A opt_args + typeset -a _arguments_options + local ret=1 + + if is-at-least 5.2; then + _arguments_options=(-s -S -C) + else + _arguments_options=(-s -C) + fi + + local context curcontext="$curcontext" state line + _arguments "${_arguments_options[@]}" : \ +'--chain=[Chain to use]:CHAIN: ' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help]' \ +'--help[Print help]' \ +'-V[Print version]' \ +'--version[Print version]' \ +":: :_zkstack_commands" \ +"*::: :->zkstack" \ +&& ret=0 + case $state in + (zkstack) + words=($line[1] "${words[@]}") + (( CURRENT += 1 )) + curcontext="${curcontext%:*:*}:zkstack-command-$line[1]:" + case $line[1] in + (autocomplete) +_arguments "${_arguments_options[@]}" : \ +'--generate=[The shell to generate the autocomplete script for]:GENERATOR:(bash elvish fish powershell zsh)' \ +'-o+[The out directory to write the autocomplete script to]:OUT:_files' \ +'--out=[The out directory to write the autocomplete script to]:OUT:_files' \ +'--chain=[Chain to use]:CHAIN: ' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; +(ecosystem) +_arguments "${_arguments_options[@]}" : \ +'--chain=[Chain to use]:CHAIN: ' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help]' \ +'--help[Print help]' \ +":: :_zkstack__ecosystem_commands" \ +"*::: :->ecosystem" \ +&& ret=0 + + case $state in + (ecosystem) + words=($line[1] "${words[@]}") + (( CURRENT += 1 )) + curcontext="${curcontext%:*:*}:zkstack-ecosystem-command-$line[1]:" + case $line[1] in + (create) +_arguments "${_arguments_options[@]}" : \ +'--ecosystem-name=[]:ECOSYSTEM_NAME: ' \ +'--l1-network=[L1 Network]:L1_NETWORK:(localhost sepolia holesky mainnet)' \ +'--link-to-code=[Code link]:LINK_TO_CODE:_files -/' \ +'--chain-name=[]:CHAIN_NAME: ' \ +'--chain-id=[Chain ID]:CHAIN_ID: ' \ +'--prover-mode=[Prover options]:PROVER_MODE:(no-proofs gpu)' \ +'--wallet-creation=[Wallet options]:WALLET_CREATION:((localhost\:"Load wallets from localhost mnemonic, they are funded for localhost env" +random\:"Generate random wallets" +empty\:"Generate placeholder wallets" +in-file\:"Specify file with wallets"))' \ +'--wallet-path=[Wallet path]:WALLET_PATH:_files' \ +'--l1-batch-commit-data-generator-mode=[Commit data generation mode]:L1_BATCH_COMMIT_DATA_GENERATOR_MODE:(rollup validium)' \ +'--base-token-address=[Base token address]:BASE_TOKEN_ADDRESS: ' \ +'--base-token-price-nominator=[Base token nominator]:BASE_TOKEN_PRICE_NOMINATOR: ' \ +'--base-token-price-denominator=[Base token denominator]:BASE_TOKEN_PRICE_DENOMINATOR: ' \ +'--set-as-default=[Set as default chain]' \ +'--start-containers=[Start reth and postgres containers after creation]' \ +'--chain=[Chain to use]:CHAIN: ' \ +'--legacy-bridge[]' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help (see more with '\''--help'\'')]' \ +'--help[Print help (see more with '\''--help'\'')]' \ +&& ret=0 +;; +(build-transactions) +_arguments "${_arguments_options[@]}" : \ +'--sender=[Address of the transaction sender]:SENDER: ' \ +'--l1-rpc-url=[L1 RPC URL]:L1_RPC_URL: ' \ +'-o+[Output directory for the generated files]:OUT:_files' \ +'--out=[Output directory for the generated files]:OUT:_files' \ +'--verify=[Verify deployed contracts]' \ +'--verifier=[Verifier to use]:VERIFIER:(etherscan sourcify blockscout oklink)' \ +'--verifier-url=[Verifier URL, if using a custom provider]:VERIFIER_URL: ' \ +'--verifier-api-key=[Verifier API key]:VERIFIER_API_KEY: ' \ +'*-a+[List of additional arguments that can be passed through the CLI]:ADDITIONAL_ARGS: ' \ +'*--additional-args=[List of additional arguments that can be passed through the CLI]:ADDITIONAL_ARGS: ' \ +'--chain=[Chain to use]:CHAIN: ' \ +'--resume[]' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help (see more with '\''--help'\'')]' \ +'--help[Print help (see more with '\''--help'\'')]' \ +&& ret=0 +;; +(init) +_arguments "${_arguments_options[@]}" : \ +'--deploy-erc20=[Deploy ERC20 contracts]' \ +'--deploy-ecosystem=[Deploy ecosystem contracts]' \ +'--ecosystem-contracts-path=[Path to ecosystem contracts]:ECOSYSTEM_CONTRACTS_PATH:_files' \ +'--l1-rpc-url=[L1 RPC URL]:L1_RPC_URL: ' \ +'--verify=[Verify deployed contracts]' \ +'--verifier=[Verifier to use]:VERIFIER:(etherscan sourcify blockscout oklink)' \ +'--verifier-url=[Verifier URL, if using a custom provider]:VERIFIER_URL: ' \ +'--verifier-api-key=[Verifier API key]:VERIFIER_API_KEY: ' \ +'*-a+[List of additional arguments that can be passed through the CLI]:ADDITIONAL_ARGS: ' \ +'*--additional-args=[List of additional arguments that can be passed through the CLI]:ADDITIONAL_ARGS: ' \ +'--deploy-paymaster=[Deploy Paymaster contract]' \ +'--server-db-url=[Server database url without database name]:SERVER_DB_URL: ' \ +'--server-db-name=[Server database name]:SERVER_DB_NAME: ' \ +'-o+[Enable Grafana]' \ +'--observability=[Enable Grafana]' \ +'--chain=[Chain to use]:CHAIN: ' \ +'--resume[]' \ +'-u[Use default database urls and names]' \ +'--use-default[Use default database urls and names]' \ +'-d[]' \ +'--dont-drop[]' \ +'--ecosystem-only[Initialize ecosystem only and skip chain initialization (chain can be initialized later with \`chain init\` subcommand)]' \ +'--dev[Deploy ecosystem using all defaults. Suitable for local development]' \ +'--no-port-reallocation[Do not reallocate ports]' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help (see more with '\''--help'\'')]' \ +'--help[Print help (see more with '\''--help'\'')]' \ +&& ret=0 +;; +(change-default-chain) +_arguments "${_arguments_options[@]}" : \ +'--chain=[Chain to use]:CHAIN: ' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help]' \ +'--help[Print help]' \ +'::name:' \ +&& ret=0 +;; +(setup-observability) +_arguments "${_arguments_options[@]}" : \ +'--chain=[Chain to use]:CHAIN: ' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; +(help) +_arguments "${_arguments_options[@]}" : \ +":: :_zkstack__ecosystem__help_commands" \ +"*::: :->help" \ +&& ret=0 + + case $state in + (help) + words=($line[1] "${words[@]}") + (( CURRENT += 1 )) + curcontext="${curcontext%:*:*}:zkstack-ecosystem-help-command-$line[1]:" + case $line[1] in + (create) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(build-transactions) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(init) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(change-default-chain) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(setup-observability) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(help) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; + esac + ;; +esac +;; + esac + ;; +esac +;; +(chain) +_arguments "${_arguments_options[@]}" : \ +'--chain=[Chain to use]:CHAIN: ' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help]' \ +'--help[Print help]' \ +":: :_zkstack__chain_commands" \ +"*::: :->chain" \ +&& ret=0 + + case $state in + (chain) + words=($line[1] "${words[@]}") + (( CURRENT += 1 )) + curcontext="${curcontext%:*:*}:zkstack-chain-command-$line[1]:" + case $line[1] in + (create) +_arguments "${_arguments_options[@]}" : \ +'--chain-name=[]:CHAIN_NAME: ' \ +'--chain-id=[Chain ID]:CHAIN_ID: ' \ +'--prover-mode=[Prover options]:PROVER_MODE:(no-proofs gpu)' \ +'--wallet-creation=[Wallet options]:WALLET_CREATION:((localhost\:"Load wallets from localhost mnemonic, they are funded for localhost env" +random\:"Generate random wallets" +empty\:"Generate placeholder wallets" +in-file\:"Specify file with wallets"))' \ +'--wallet-path=[Wallet path]:WALLET_PATH:_files' \ +'--l1-batch-commit-data-generator-mode=[Commit data generation mode]:L1_BATCH_COMMIT_DATA_GENERATOR_MODE:(rollup validium)' \ +'--base-token-address=[Base token address]:BASE_TOKEN_ADDRESS: ' \ +'--base-token-price-nominator=[Base token nominator]:BASE_TOKEN_PRICE_NOMINATOR: ' \ +'--base-token-price-denominator=[Base token denominator]:BASE_TOKEN_PRICE_DENOMINATOR: ' \ +'--set-as-default=[Set as default chain]' \ +'--chain=[Chain to use]:CHAIN: ' \ +'--legacy-bridge[]' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help (see more with '\''--help'\'')]' \ +'--help[Print help (see more with '\''--help'\'')]' \ +&& ret=0 +;; +(build-transactions) +_arguments "${_arguments_options[@]}" : \ +'-o+[Output directory for the generated files]:OUT:_files' \ +'--out=[Output directory for the generated files]:OUT:_files' \ +'--verify=[Verify deployed contracts]' \ +'--verifier=[Verifier to use]:VERIFIER:(etherscan sourcify blockscout oklink)' \ +'--verifier-url=[Verifier URL, if using a custom provider]:VERIFIER_URL: ' \ +'--verifier-api-key=[Verifier API key]:VERIFIER_API_KEY: ' \ +'*-a+[List of additional arguments that can be passed through the CLI]:ADDITIONAL_ARGS: ' \ +'*--additional-args=[List of additional arguments that can be passed through the CLI]:ADDITIONAL_ARGS: ' \ +'--l1-rpc-url=[L1 RPC URL]:L1_RPC_URL: ' \ +'--chain=[Chain to use]:CHAIN: ' \ +'--resume[]' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help (see more with '\''--help'\'')]' \ +'--help[Print help (see more with '\''--help'\'')]' \ +&& ret=0 +;; +(init) +_arguments "${_arguments_options[@]}" : \ +'--verify=[Verify deployed contracts]' \ +'--verifier=[Verifier to use]:VERIFIER:(etherscan sourcify blockscout oklink)' \ +'--verifier-url=[Verifier URL, if using a custom provider]:VERIFIER_URL: ' \ +'--verifier-api-key=[Verifier API key]:VERIFIER_API_KEY: ' \ +'*-a+[List of additional arguments that can be passed through the CLI]:ADDITIONAL_ARGS: ' \ +'*--additional-args=[List of additional arguments that can be passed through the CLI]:ADDITIONAL_ARGS: ' \ +'--server-db-url=[Server database url without database name]:SERVER_DB_URL: ' \ +'--server-db-name=[Server database name]:SERVER_DB_NAME: ' \ +'--deploy-paymaster=[]' \ +'--l1-rpc-url=[L1 RPC URL]:L1_RPC_URL: ' \ +'--chain=[Chain to use]:CHAIN: ' \ +'--resume[]' \ +'-u[Use default database urls and names]' \ +'--use-default[Use default database urls and names]' \ +'-d[]' \ +'--dont-drop[]' \ +'--no-port-reallocation[Do not reallocate ports]' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help (see more with '\''--help'\'')]' \ +'--help[Print help (see more with '\''--help'\'')]' \ +":: :_zkstack__chain__init_commands" \ +"*::: :->init" \ +&& ret=0 + + case $state in + (init) + words=($line[1] "${words[@]}") + (( CURRENT += 1 )) + curcontext="${curcontext%:*:*}:zkstack-chain-init-command-$line[1]:" + case $line[1] in + (configs) +_arguments "${_arguments_options[@]}" : \ +'--server-db-url=[Server database url without database name]:SERVER_DB_URL: ' \ +'--server-db-name=[Server database name]:SERVER_DB_NAME: ' \ +'--l1-rpc-url=[L1 RPC URL]:L1_RPC_URL: ' \ +'--chain=[Chain to use]:CHAIN: ' \ +'-u[Use default database urls and names]' \ +'--use-default[Use default database urls and names]' \ +'-d[]' \ +'--dont-drop[]' \ +'--no-port-reallocation[Do not reallocate ports]' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; +(help) +_arguments "${_arguments_options[@]}" : \ +":: :_zkstack__chain__init__help_commands" \ +"*::: :->help" \ +&& ret=0 + + case $state in + (help) + words=($line[1] "${words[@]}") + (( CURRENT += 1 )) + curcontext="${curcontext%:*:*}:zkstack-chain-init-help-command-$line[1]:" + case $line[1] in + (configs) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(help) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; + esac + ;; +esac +;; + esac + ;; +esac +;; +(genesis) +_arguments "${_arguments_options[@]}" : \ +'--server-db-url=[Server database url without database name]:SERVER_DB_URL: ' \ +'--server-db-name=[Server database name]:SERVER_DB_NAME: ' \ +'--chain=[Chain to use]:CHAIN: ' \ +'-u[Use default database urls and names]' \ +'--use-default[Use default database urls and names]' \ +'-d[]' \ +'--dont-drop[]' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help]' \ +'--help[Print help]' \ +":: :_zkstack__chain__genesis_commands" \ +"*::: :->genesis" \ +&& ret=0 + + case $state in + (genesis) + words=($line[1] "${words[@]}") + (( CURRENT += 1 )) + curcontext="${curcontext%:*:*}:zkstack-chain-genesis-command-$line[1]:" + case $line[1] in + (init-database) +_arguments "${_arguments_options[@]}" : \ +'--server-db-url=[Server database url without database name]:SERVER_DB_URL: ' \ +'--server-db-name=[Server database name]:SERVER_DB_NAME: ' \ +'--chain=[Chain to use]:CHAIN: ' \ +'-u[Use default database urls and names]' \ +'--use-default[Use default database urls and names]' \ +'-d[]' \ +'--dont-drop[]' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; +(server) +_arguments "${_arguments_options[@]}" : \ +'--chain=[Chain to use]:CHAIN: ' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; +(help) +_arguments "${_arguments_options[@]}" : \ +":: :_zkstack__chain__genesis__help_commands" \ +"*::: :->help" \ +&& ret=0 + + case $state in + (help) + words=($line[1] "${words[@]}") + (( CURRENT += 1 )) + curcontext="${curcontext%:*:*}:zkstack-chain-genesis-help-command-$line[1]:" + case $line[1] in + (init-database) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(server) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(help) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; + esac + ;; +esac +;; + esac + ;; +esac +;; +(register-chain) +_arguments "${_arguments_options[@]}" : \ +'--verify=[Verify deployed contracts]' \ +'--verifier=[Verifier to use]:VERIFIER:(etherscan sourcify blockscout oklink)' \ +'--verifier-url=[Verifier URL, if using a custom provider]:VERIFIER_URL: ' \ +'--verifier-api-key=[Verifier API key]:VERIFIER_API_KEY: ' \ +'*-a+[List of additional arguments that can be passed through the CLI]:ADDITIONAL_ARGS: ' \ +'*--additional-args=[List of additional arguments that can be passed through the CLI]:ADDITIONAL_ARGS: ' \ +'--chain=[Chain to use]:CHAIN: ' \ +'--resume[]' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help (see more with '\''--help'\'')]' \ +'--help[Print help (see more with '\''--help'\'')]' \ +&& ret=0 +;; +(deploy-l2-contracts) +_arguments "${_arguments_options[@]}" : \ +'--verify=[Verify deployed contracts]' \ +'--verifier=[Verifier to use]:VERIFIER:(etherscan sourcify blockscout oklink)' \ +'--verifier-url=[Verifier URL, if using a custom provider]:VERIFIER_URL: ' \ +'--verifier-api-key=[Verifier API key]:VERIFIER_API_KEY: ' \ +'*-a+[List of additional arguments that can be passed through the CLI]:ADDITIONAL_ARGS: ' \ +'*--additional-args=[List of additional arguments that can be passed through the CLI]:ADDITIONAL_ARGS: ' \ +'--chain=[Chain to use]:CHAIN: ' \ +'--resume[]' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help (see more with '\''--help'\'')]' \ +'--help[Print help (see more with '\''--help'\'')]' \ +&& ret=0 +;; +(accept-chain-ownership) +_arguments "${_arguments_options[@]}" : \ +'--verify=[Verify deployed contracts]' \ +'--verifier=[Verifier to use]:VERIFIER:(etherscan sourcify blockscout oklink)' \ +'--verifier-url=[Verifier URL, if using a custom provider]:VERIFIER_URL: ' \ +'--verifier-api-key=[Verifier API key]:VERIFIER_API_KEY: ' \ +'*-a+[List of additional arguments that can be passed through the CLI]:ADDITIONAL_ARGS: ' \ +'*--additional-args=[List of additional arguments that can be passed through the CLI]:ADDITIONAL_ARGS: ' \ +'--chain=[Chain to use]:CHAIN: ' \ +'--resume[]' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help (see more with '\''--help'\'')]' \ +'--help[Print help (see more with '\''--help'\'')]' \ +&& ret=0 +;; +(initialize-bridges) +_arguments "${_arguments_options[@]}" : \ +'--verify=[Verify deployed contracts]' \ +'--verifier=[Verifier to use]:VERIFIER:(etherscan sourcify blockscout oklink)' \ +'--verifier-url=[Verifier URL, if using a custom provider]:VERIFIER_URL: ' \ +'--verifier-api-key=[Verifier API key]:VERIFIER_API_KEY: ' \ +'*-a+[List of additional arguments that can be passed through the CLI]:ADDITIONAL_ARGS: ' \ +'*--additional-args=[List of additional arguments that can be passed through the CLI]:ADDITIONAL_ARGS: ' \ +'--chain=[Chain to use]:CHAIN: ' \ +'--resume[]' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help (see more with '\''--help'\'')]' \ +'--help[Print help (see more with '\''--help'\'')]' \ +&& ret=0 +;; +(deploy-consensus-registry) +_arguments "${_arguments_options[@]}" : \ +'--verify=[Verify deployed contracts]' \ +'--verifier=[Verifier to use]:VERIFIER:(etherscan sourcify blockscout oklink)' \ +'--verifier-url=[Verifier URL, if using a custom provider]:VERIFIER_URL: ' \ +'--verifier-api-key=[Verifier API key]:VERIFIER_API_KEY: ' \ +'*-a+[List of additional arguments that can be passed through the CLI]:ADDITIONAL_ARGS: ' \ +'*--additional-args=[List of additional arguments that can be passed through the CLI]:ADDITIONAL_ARGS: ' \ +'--chain=[Chain to use]:CHAIN: ' \ +'--resume[]' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help (see more with '\''--help'\'')]' \ +'--help[Print help (see more with '\''--help'\'')]' \ +&& ret=0 +;; +(deploy-multicall3) +_arguments "${_arguments_options[@]}" : \ +'--verify=[Verify deployed contracts]' \ +'--verifier=[Verifier to use]:VERIFIER:(etherscan sourcify blockscout oklink)' \ +'--verifier-url=[Verifier URL, if using a custom provider]:VERIFIER_URL: ' \ +'--verifier-api-key=[Verifier API key]:VERIFIER_API_KEY: ' \ +'*-a+[List of additional arguments that can be passed through the CLI]:ADDITIONAL_ARGS: ' \ +'*--additional-args=[List of additional arguments that can be passed through the CLI]:ADDITIONAL_ARGS: ' \ +'--chain=[Chain to use]:CHAIN: ' \ +'--resume[]' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help (see more with '\''--help'\'')]' \ +'--help[Print help (see more with '\''--help'\'')]' \ +&& ret=0 +;; +(deploy-upgrader) +_arguments "${_arguments_options[@]}" : \ +'--verify=[Verify deployed contracts]' \ +'--verifier=[Verifier to use]:VERIFIER:(etherscan sourcify blockscout oklink)' \ +'--verifier-url=[Verifier URL, if using a custom provider]:VERIFIER_URL: ' \ +'--verifier-api-key=[Verifier API key]:VERIFIER_API_KEY: ' \ +'*-a+[List of additional arguments that can be passed through the CLI]:ADDITIONAL_ARGS: ' \ +'*--additional-args=[List of additional arguments that can be passed through the CLI]:ADDITIONAL_ARGS: ' \ +'--chain=[Chain to use]:CHAIN: ' \ +'--resume[]' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help (see more with '\''--help'\'')]' \ +'--help[Print help (see more with '\''--help'\'')]' \ +&& ret=0 +;; +(deploy-paymaster) +_arguments "${_arguments_options[@]}" : \ +'--verify=[Verify deployed contracts]' \ +'--verifier=[Verifier to use]:VERIFIER:(etherscan sourcify blockscout oklink)' \ +'--verifier-url=[Verifier URL, if using a custom provider]:VERIFIER_URL: ' \ +'--verifier-api-key=[Verifier API key]:VERIFIER_API_KEY: ' \ +'*-a+[List of additional arguments that can be passed through the CLI]:ADDITIONAL_ARGS: ' \ +'*--additional-args=[List of additional arguments that can be passed through the CLI]:ADDITIONAL_ARGS: ' \ +'--chain=[Chain to use]:CHAIN: ' \ +'--resume[]' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help (see more with '\''--help'\'')]' \ +'--help[Print help (see more with '\''--help'\'')]' \ +&& ret=0 +;; +(update-token-multiplier-setter) +_arguments "${_arguments_options[@]}" : \ +'--verify=[Verify deployed contracts]' \ +'--verifier=[Verifier to use]:VERIFIER:(etherscan sourcify blockscout oklink)' \ +'--verifier-url=[Verifier URL, if using a custom provider]:VERIFIER_URL: ' \ +'--verifier-api-key=[Verifier API key]:VERIFIER_API_KEY: ' \ +'*-a+[List of additional arguments that can be passed through the CLI]:ADDITIONAL_ARGS: ' \ +'*--additional-args=[List of additional arguments that can be passed through the CLI]:ADDITIONAL_ARGS: ' \ +'--chain=[Chain to use]:CHAIN: ' \ +'--resume[]' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help (see more with '\''--help'\'')]' \ +'--help[Print help (see more with '\''--help'\'')]' \ +&& ret=0 +;; +(help) +_arguments "${_arguments_options[@]}" : \ +":: :_zkstack__chain__help_commands" \ +"*::: :->help" \ +&& ret=0 + + case $state in + (help) + words=($line[1] "${words[@]}") + (( CURRENT += 1 )) + curcontext="${curcontext%:*:*}:zkstack-chain-help-command-$line[1]:" + case $line[1] in + (create) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(build-transactions) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(init) +_arguments "${_arguments_options[@]}" : \ +":: :_zkstack__chain__help__init_commands" \ +"*::: :->init" \ +&& ret=0 + + case $state in + (init) + words=($line[1] "${words[@]}") + (( CURRENT += 1 )) + curcontext="${curcontext%:*:*}:zkstack-chain-help-init-command-$line[1]:" + case $line[1] in + (configs) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; + esac + ;; +esac +;; +(genesis) +_arguments "${_arguments_options[@]}" : \ +":: :_zkstack__chain__help__genesis_commands" \ +"*::: :->genesis" \ +&& ret=0 + + case $state in + (genesis) + words=($line[1] "${words[@]}") + (( CURRENT += 1 )) + curcontext="${curcontext%:*:*}:zkstack-chain-help-genesis-command-$line[1]:" + case $line[1] in + (init-database) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(server) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; + esac + ;; +esac +;; +(register-chain) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(deploy-l2-contracts) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(accept-chain-ownership) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(initialize-bridges) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(deploy-consensus-registry) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(deploy-multicall3) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(deploy-upgrader) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(deploy-paymaster) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(update-token-multiplier-setter) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(help) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; + esac + ;; +esac +;; + esac + ;; +esac +;; +(dev) +_arguments "${_arguments_options[@]}" : \ +'--chain=[Chain to use]:CHAIN: ' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help]' \ +'--help[Print help]' \ +":: :_zkstack__dev_commands" \ +"*::: :->dev" \ +&& ret=0 + + case $state in + (dev) + words=($line[1] "${words[@]}") + (( CURRENT += 1 )) + curcontext="${curcontext%:*:*}:zkstack-dev-command-$line[1]:" + case $line[1] in + (database) +_arguments "${_arguments_options[@]}" : \ +'--chain=[Chain to use]:CHAIN: ' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help]' \ +'--help[Print help]' \ +":: :_zkstack__dev__database_commands" \ +"*::: :->database" \ +&& ret=0 + + case $state in + (database) + words=($line[1] "${words[@]}") + (( CURRENT += 1 )) + curcontext="${curcontext%:*:*}:zkstack-dev-database-command-$line[1]:" + case $line[1] in + (check-sqlx-data) +_arguments "${_arguments_options[@]}" : \ +'-p+[Prover database]' \ +'--prover=[Prover database]' \ +'--prover-url=[URL of the Prover database. If not specified, it is used from the current chain'\''s secrets]:PROVER_URL: ' \ +'-c+[Core database]' \ +'--core=[Core database]' \ +'--core-url=[URL of the Core database. If not specified, it is used from the current chain'\''s secrets.]:CORE_URL: ' \ +'--chain=[Chain to use]:CHAIN: ' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; +(drop) +_arguments "${_arguments_options[@]}" : \ +'-p+[Prover database]' \ +'--prover=[Prover database]' \ +'--prover-url=[URL of the Prover database. If not specified, it is used from the current chain'\''s secrets]:PROVER_URL: ' \ +'-c+[Core database]' \ +'--core=[Core database]' \ +'--core-url=[URL of the Core database. If not specified, it is used from the current chain'\''s secrets.]:CORE_URL: ' \ +'--chain=[Chain to use]:CHAIN: ' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; +(migrate) +_arguments "${_arguments_options[@]}" : \ +'-p+[Prover database]' \ +'--prover=[Prover database]' \ +'--prover-url=[URL of the Prover database. If not specified, it is used from the current chain'\''s secrets]:PROVER_URL: ' \ +'-c+[Core database]' \ +'--core=[Core database]' \ +'--core-url=[URL of the Core database. If not specified, it is used from the current chain'\''s secrets.]:CORE_URL: ' \ +'--chain=[Chain to use]:CHAIN: ' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; +(new-migration) +_arguments "${_arguments_options[@]}" : \ +'--database=[Database to create new migration for]:DATABASE:(prover core)' \ +'--name=[Migration name]:NAME: ' \ +'--chain=[Chain to use]:CHAIN: ' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; +(prepare) +_arguments "${_arguments_options[@]}" : \ +'-p+[Prover database]' \ +'--prover=[Prover database]' \ +'--prover-url=[URL of the Prover database. If not specified, it is used from the current chain'\''s secrets]:PROVER_URL: ' \ +'-c+[Core database]' \ +'--core=[Core database]' \ +'--core-url=[URL of the Core database. If not specified, it is used from the current chain'\''s secrets.]:CORE_URL: ' \ +'--chain=[Chain to use]:CHAIN: ' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; +(reset) +_arguments "${_arguments_options[@]}" : \ +'-p+[Prover database]' \ +'--prover=[Prover database]' \ +'--prover-url=[URL of the Prover database. If not specified, it is used from the current chain'\''s secrets]:PROVER_URL: ' \ +'-c+[Core database]' \ +'--core=[Core database]' \ +'--core-url=[URL of the Core database. If not specified, it is used from the current chain'\''s secrets.]:CORE_URL: ' \ +'--chain=[Chain to use]:CHAIN: ' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; +(setup) +_arguments "${_arguments_options[@]}" : \ +'-p+[Prover database]' \ +'--prover=[Prover database]' \ +'--prover-url=[URL of the Prover database. If not specified, it is used from the current chain'\''s secrets]:PROVER_URL: ' \ +'-c+[Core database]' \ +'--core=[Core database]' \ +'--core-url=[URL of the Core database. If not specified, it is used from the current chain'\''s secrets.]:CORE_URL: ' \ +'--chain=[Chain to use]:CHAIN: ' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; +(help) +_arguments "${_arguments_options[@]}" : \ +":: :_zkstack__dev__database__help_commands" \ +"*::: :->help" \ +&& ret=0 + + case $state in + (help) + words=($line[1] "${words[@]}") + (( CURRENT += 1 )) + curcontext="${curcontext%:*:*}:zkstack-dev-database-help-command-$line[1]:" + case $line[1] in + (check-sqlx-data) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(drop) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(migrate) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(new-migration) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(prepare) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(reset) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(setup) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(help) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; + esac + ;; +esac +;; + esac + ;; +esac +;; +(test) +_arguments "${_arguments_options[@]}" : \ +'--chain=[Chain to use]:CHAIN: ' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help]' \ +'--help[Print help]' \ +":: :_zkstack__dev__test_commands" \ +"*::: :->test" \ +&& ret=0 + + case $state in + (test) + words=($line[1] "${words[@]}") + (( CURRENT += 1 )) + curcontext="${curcontext%:*:*}:zkstack-dev-test-command-$line[1]:" + case $line[1] in + (integration) +_arguments "${_arguments_options[@]}" : \ +'-t+[Run just the tests matching a pattern. Same as the -t flag on jest.]:TEST_PATTERN: ' \ +'--test-pattern=[Run just the tests matching a pattern. Same as the -t flag on jest.]:TEST_PATTERN: ' \ +'--chain=[Chain to use]:CHAIN: ' \ +'-e[Run tests for external node]' \ +'--external-node[Run tests for external node]' \ +'-n[Do not install or build dependencies]' \ +'--no-deps[Do not install or build dependencies]' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; +(fees) +_arguments "${_arguments_options[@]}" : \ +'--chain=[Chain to use]:CHAIN: ' \ +'-n[Do not install or build dependencies]' \ +'--no-deps[Do not install or build dependencies]' \ +'--no-kill[The test will not kill all the nodes during execution]' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; +(revert) +_arguments "${_arguments_options[@]}" : \ +'--chain=[Chain to use]:CHAIN: ' \ +'--enable-consensus[Enable consensus]' \ +'-e[Run tests for external node]' \ +'--external-node[Run tests for external node]' \ +'-n[Do not install or build dependencies]' \ +'--no-deps[Do not install or build dependencies]' \ +'--no-kill[The test will not kill all the nodes during execution]' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; +(recovery) +_arguments "${_arguments_options[@]}" : \ +'--chain=[Chain to use]:CHAIN: ' \ +'-s[Run recovery from a snapshot instead of genesis]' \ +'--snapshot[Run recovery from a snapshot instead of genesis]' \ +'-n[Do not install or build dependencies]' \ +'--no-deps[Do not install or build dependencies]' \ +'--no-kill[The test will not kill all the nodes during execution]' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; +(upgrade) +_arguments "${_arguments_options[@]}" : \ +'--chain=[Chain to use]:CHAIN: ' \ +'-n[Do not install or build dependencies]' \ +'--no-deps[Do not install or build dependencies]' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; +(build) +_arguments "${_arguments_options[@]}" : \ +'--chain=[Chain to use]:CHAIN: ' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; +(rust) +_arguments "${_arguments_options[@]}" : \ +'--options=[Cargo test flags]:OPTIONS: ' \ +'--chain=[Chain to use]:CHAIN: ' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; +(l1-contracts) +_arguments "${_arguments_options[@]}" : \ +'--chain=[Chain to use]:CHAIN: ' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; +(prover) +_arguments "${_arguments_options[@]}" : \ +'--chain=[Chain to use]:CHAIN: ' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; +(wallet) +_arguments "${_arguments_options[@]}" : \ +'--chain=[Chain to use]:CHAIN: ' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; +(loadtest) +_arguments "${_arguments_options[@]}" : \ +'--chain=[Chain to use]:CHAIN: ' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; +(help) +_arguments "${_arguments_options[@]}" : \ +":: :_zkstack__dev__test__help_commands" \ +"*::: :->help" \ +&& ret=0 + + case $state in + (help) + words=($line[1] "${words[@]}") + (( CURRENT += 1 )) + curcontext="${curcontext%:*:*}:zkstack-dev-test-help-command-$line[1]:" + case $line[1] in + (integration) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(fees) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(revert) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(recovery) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(upgrade) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(build) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(rust) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(l1-contracts) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(prover) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(wallet) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(loadtest) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(help) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; + esac + ;; +esac +;; + esac + ;; +esac +;; +(clean) +_arguments "${_arguments_options[@]}" : \ +'--chain=[Chain to use]:CHAIN: ' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help]' \ +'--help[Print help]' \ +":: :_zkstack__dev__clean_commands" \ +"*::: :->clean" \ +&& ret=0 + + case $state in + (clean) + words=($line[1] "${words[@]}") + (( CURRENT += 1 )) + curcontext="${curcontext%:*:*}:zkstack-dev-clean-command-$line[1]:" + case $line[1] in + (all) +_arguments "${_arguments_options[@]}" : \ +'--chain=[Chain to use]:CHAIN: ' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; +(containers) +_arguments "${_arguments_options[@]}" : \ +'--chain=[Chain to use]:CHAIN: ' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; +(contracts-cache) +_arguments "${_arguments_options[@]}" : \ +'--chain=[Chain to use]:CHAIN: ' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; +(help) +_arguments "${_arguments_options[@]}" : \ +":: :_zkstack__dev__clean__help_commands" \ +"*::: :->help" \ +&& ret=0 + + case $state in + (help) + words=($line[1] "${words[@]}") + (( CURRENT += 1 )) + curcontext="${curcontext%:*:*}:zkstack-dev-clean-help-command-$line[1]:" + case $line[1] in + (all) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(containers) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(contracts-cache) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(help) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; + esac + ;; +esac +;; + esac + ;; +esac +;; +(snapshot) +_arguments "${_arguments_options[@]}" : \ +'--chain=[Chain to use]:CHAIN: ' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help]' \ +'--help[Print help]' \ +":: :_zkstack__dev__snapshot_commands" \ +"*::: :->snapshot" \ +&& ret=0 + + case $state in + (snapshot) + words=($line[1] "${words[@]}") + (( CURRENT += 1 )) + curcontext="${curcontext%:*:*}:zkstack-dev-snapshot-command-$line[1]:" + case $line[1] in + (create) +_arguments "${_arguments_options[@]}" : \ +'--chain=[Chain to use]:CHAIN: ' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; +(help) +_arguments "${_arguments_options[@]}" : \ +":: :_zkstack__dev__snapshot__help_commands" \ +"*::: :->help" \ +&& ret=0 + + case $state in + (help) + words=($line[1] "${words[@]}") + (( CURRENT += 1 )) + curcontext="${curcontext%:*:*}:zkstack-dev-snapshot-help-command-$line[1]:" + case $line[1] in + (create) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(help) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; + esac + ;; +esac +;; + esac + ;; +esac +;; +(lint) +_arguments "${_arguments_options[@]}" : \ +'*-t+[]:TARGETS:(md sol js ts rs contracts autocompletion)' \ +'*--targets=[]:TARGETS:(md sol js ts rs contracts autocompletion)' \ +'--chain=[Chain to use]:CHAIN: ' \ +'-c[]' \ +'--check[]' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; +(fmt) +_arguments "${_arguments_options[@]}" : \ +'--chain=[Chain to use]:CHAIN: ' \ +'-c[]' \ +'--check[]' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help]' \ +'--help[Print help]' \ +":: :_zkstack__dev__fmt_commands" \ +"*::: :->fmt" \ +&& ret=0 + + case $state in + (fmt) + words=($line[1] "${words[@]}") + (( CURRENT += 1 )) + curcontext="${curcontext%:*:*}:zkstack-dev-fmt-command-$line[1]:" + case $line[1] in + (rustfmt) +_arguments "${_arguments_options[@]}" : \ +'--chain=[Chain to use]:CHAIN: ' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; +(contract) +_arguments "${_arguments_options[@]}" : \ +'--chain=[Chain to use]:CHAIN: ' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; +(prettier) +_arguments "${_arguments_options[@]}" : \ +'*-t+[]:TARGETS:(md sol js ts rs contracts autocompletion)' \ +'*--targets=[]:TARGETS:(md sol js ts rs contracts autocompletion)' \ +'--chain=[Chain to use]:CHAIN: ' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; +(help) +_arguments "${_arguments_options[@]}" : \ +":: :_zkstack__dev__fmt__help_commands" \ +"*::: :->help" \ +&& ret=0 + + case $state in + (help) + words=($line[1] "${words[@]}") + (( CURRENT += 1 )) + curcontext="${curcontext%:*:*}:zkstack-dev-fmt-help-command-$line[1]:" + case $line[1] in + (rustfmt) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(contract) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(prettier) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(help) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; + esac + ;; +esac +;; + esac + ;; +esac +;; +(prover) +_arguments "${_arguments_options[@]}" : \ +'--chain=[Chain to use]:CHAIN: ' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help]' \ +'--help[Print help]' \ +":: :_zkstack__dev__prover_commands" \ +"*::: :->prover" \ +&& ret=0 + + case $state in + (prover) + words=($line[1] "${words[@]}") + (( CURRENT += 1 )) + curcontext="${curcontext%:*:*}:zkstack-dev-prover-command-$line[1]:" + case $line[1] in + (info) +_arguments "${_arguments_options[@]}" : \ +'--chain=[Chain to use]:CHAIN: ' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; +(insert-batch) +_arguments "${_arguments_options[@]}" : \ +'--number=[]:NUMBER: ' \ +'--version=[]:VERSION: ' \ +'--chain=[Chain to use]:CHAIN: ' \ +'--default[]' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; +(insert-version) +_arguments "${_arguments_options[@]}" : \ +'--version=[]:VERSION: ' \ +'--snark-wrapper=[]:SNARK_WRAPPER: ' \ +'--chain=[Chain to use]:CHAIN: ' \ +'--default[]' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; +(help) +_arguments "${_arguments_options[@]}" : \ +":: :_zkstack__dev__prover__help_commands" \ +"*::: :->help" \ +&& ret=0 + + case $state in + (help) + words=($line[1] "${words[@]}") + (( CURRENT += 1 )) + curcontext="${curcontext%:*:*}:zkstack-dev-prover-help-command-$line[1]:" + case $line[1] in + (info) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(insert-batch) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(insert-version) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(help) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; + esac + ;; +esac +;; + esac + ;; +esac +;; +(contracts) +_arguments "${_arguments_options[@]}" : \ +'--l1-contracts=[Build L1 contracts]' \ +'--l2-contracts=[Build L2 contracts]' \ +'--system-contracts=[Build system contracts]' \ +'--test-contracts=[Build test contracts]' \ +'--chain=[Chain to use]:CHAIN: ' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; +(config-writer) +_arguments "${_arguments_options[@]}" : \ +'-p+[Path to the config file to override]:PATH: ' \ +'--path=[Path to the config file to override]:PATH: ' \ +'--chain=[Chain to use]:CHAIN: ' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; +(send-transactions) +_arguments "${_arguments_options[@]}" : \ +'--file=[]:FILE:_files' \ +'--private-key=[]:PRIVATE_KEY: ' \ +'--l1-rpc-url=[]:L1_RPC_URL: ' \ +'--confirmations=[]:CONFIRMATIONS: ' \ +'--chain=[Chain to use]:CHAIN: ' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; +(status) +_arguments "${_arguments_options[@]}" : \ +'-u+[URL of the health check endpoint]:URL: ' \ +'--url=[URL of the health check endpoint]:URL: ' \ +'--chain=[Chain to use]:CHAIN: ' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help]' \ +'--help[Print help]' \ +":: :_zkstack__dev__status_commands" \ +"*::: :->status" \ +&& ret=0 + + case $state in + (status) + words=($line[1] "${words[@]}") + (( CURRENT += 1 )) + curcontext="${curcontext%:*:*}:zkstack-dev-status-command-$line[1]:" + case $line[1] in + (ports) +_arguments "${_arguments_options[@]}" : \ +'--chain=[Chain to use]:CHAIN: ' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; +(help) +_arguments "${_arguments_options[@]}" : \ +":: :_zkstack__dev__status__help_commands" \ +"*::: :->help" \ +&& ret=0 + + case $state in + (help) + words=($line[1] "${words[@]}") + (( CURRENT += 1 )) + curcontext="${curcontext%:*:*}:zkstack-dev-status-help-command-$line[1]:" + case $line[1] in + (ports) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(help) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; + esac + ;; +esac +;; + esac + ;; +esac +;; +(generate-genesis) +_arguments "${_arguments_options[@]}" : \ +'--chain=[Chain to use]:CHAIN: ' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; +(help) +_arguments "${_arguments_options[@]}" : \ +":: :_zkstack__dev__help_commands" \ +"*::: :->help" \ +&& ret=0 + + case $state in + (help) + words=($line[1] "${words[@]}") + (( CURRENT += 1 )) + curcontext="${curcontext%:*:*}:zkstack-dev-help-command-$line[1]:" + case $line[1] in + (database) +_arguments "${_arguments_options[@]}" : \ +":: :_zkstack__dev__help__database_commands" \ +"*::: :->database" \ +&& ret=0 + + case $state in + (database) + words=($line[1] "${words[@]}") + (( CURRENT += 1 )) + curcontext="${curcontext%:*:*}:zkstack-dev-help-database-command-$line[1]:" + case $line[1] in + (check-sqlx-data) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(drop) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(migrate) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(new-migration) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(prepare) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(reset) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(setup) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; + esac + ;; +esac +;; +(test) +_arguments "${_arguments_options[@]}" : \ +":: :_zkstack__dev__help__test_commands" \ +"*::: :->test" \ +&& ret=0 + + case $state in + (test) + words=($line[1] "${words[@]}") + (( CURRENT += 1 )) + curcontext="${curcontext%:*:*}:zkstack-dev-help-test-command-$line[1]:" + case $line[1] in + (integration) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(fees) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(revert) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(recovery) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(upgrade) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(build) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(rust) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(l1-contracts) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(prover) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(wallet) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(loadtest) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; + esac + ;; +esac +;; +(clean) +_arguments "${_arguments_options[@]}" : \ +":: :_zkstack__dev__help__clean_commands" \ +"*::: :->clean" \ +&& ret=0 + + case $state in + (clean) + words=($line[1] "${words[@]}") + (( CURRENT += 1 )) + curcontext="${curcontext%:*:*}:zkstack-dev-help-clean-command-$line[1]:" + case $line[1] in + (all) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(containers) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(contracts-cache) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; + esac + ;; +esac +;; +(snapshot) +_arguments "${_arguments_options[@]}" : \ +":: :_zkstack__dev__help__snapshot_commands" \ +"*::: :->snapshot" \ +&& ret=0 + + case $state in + (snapshot) + words=($line[1] "${words[@]}") + (( CURRENT += 1 )) + curcontext="${curcontext%:*:*}:zkstack-dev-help-snapshot-command-$line[1]:" + case $line[1] in + (create) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; + esac + ;; +esac +;; +(lint) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(fmt) +_arguments "${_arguments_options[@]}" : \ +":: :_zkstack__dev__help__fmt_commands" \ +"*::: :->fmt" \ +&& ret=0 + + case $state in + (fmt) + words=($line[1] "${words[@]}") + (( CURRENT += 1 )) + curcontext="${curcontext%:*:*}:zkstack-dev-help-fmt-command-$line[1]:" + case $line[1] in + (rustfmt) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(contract) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(prettier) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; + esac + ;; +esac +;; +(prover) +_arguments "${_arguments_options[@]}" : \ +":: :_zkstack__dev__help__prover_commands" \ +"*::: :->prover" \ +&& ret=0 + + case $state in + (prover) + words=($line[1] "${words[@]}") + (( CURRENT += 1 )) + curcontext="${curcontext%:*:*}:zkstack-dev-help-prover-command-$line[1]:" + case $line[1] in + (info) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(insert-batch) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(insert-version) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; + esac + ;; +esac +;; +(contracts) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(config-writer) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(send-transactions) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(status) +_arguments "${_arguments_options[@]}" : \ +":: :_zkstack__dev__help__status_commands" \ +"*::: :->status" \ +&& ret=0 + + case $state in + (status) + words=($line[1] "${words[@]}") + (( CURRENT += 1 )) + curcontext="${curcontext%:*:*}:zkstack-dev-help-status-command-$line[1]:" + case $line[1] in + (ports) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; + esac + ;; +esac +;; +(generate-genesis) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(help) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; + esac + ;; +esac +;; + esac + ;; +esac +;; +(prover) +_arguments "${_arguments_options[@]}" : \ +'--chain=[Chain to use]:CHAIN: ' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help]' \ +'--help[Print help]' \ +":: :_zkstack__prover_commands" \ +"*::: :->prover" \ +&& ret=0 + + case $state in + (prover) + words=($line[1] "${words[@]}") + (( CURRENT += 1 )) + curcontext="${curcontext%:*:*}:zkstack-prover-command-$line[1]:" + case $line[1] in + (init) +_arguments "${_arguments_options[@]}" : \ +'--proof-store-dir=[]:PROOF_STORE_DIR: ' \ +'--bucket-base-url=[]:BUCKET_BASE_URL: ' \ +'--credentials-file=[]:CREDENTIALS_FILE: ' \ +'--bucket-name=[]:BUCKET_NAME: ' \ +'--location=[]:LOCATION: ' \ +'--project-id=[]:PROJECT_ID: ' \ +'--shall-save-to-public-bucket=[]:SHALL_SAVE_TO_PUBLIC_BUCKET:(true false)' \ +'--public-store-dir=[]:PUBLIC_STORE_DIR: ' \ +'--public-bucket-base-url=[]:PUBLIC_BUCKET_BASE_URL: ' \ +'--public-credentials-file=[]:PUBLIC_CREDENTIALS_FILE: ' \ +'--public-bucket-name=[]:PUBLIC_BUCKET_NAME: ' \ +'--public-location=[]:PUBLIC_LOCATION: ' \ +'--public-project-id=[]:PUBLIC_PROJECT_ID: ' \ +'(--clone)--bellman-cuda-dir=[]:BELLMAN_CUDA_DIR: ' \ +'--bellman-cuda=[]' \ +'--setup-compressor-key=[]' \ +'--path=[]:PATH: ' \ +'--region=[]:REGION:(us europe asia)' \ +'--mode=[]:MODE:(download generate)' \ +'--setup-keys=[]' \ +'--setup-database=[]:SETUP_DATABASE:(true false)' \ +'--prover-db-url=[Prover database url without database name]:PROVER_DB_URL: ' \ +'--prover-db-name=[Prover database name]:PROVER_DB_NAME: ' \ +'-u+[Use default database urls and names]:USE_DEFAULT:(true false)' \ +'--use-default=[Use default database urls and names]:USE_DEFAULT:(true false)' \ +'-d+[]:DONT_DROP:(true false)' \ +'--dont-drop=[]:DONT_DROP:(true false)' \ +'--cloud-type=[]:CLOUD_TYPE:(gcp local)' \ +'--chain=[Chain to use]:CHAIN: ' \ +'--dev[]' \ +'(--bellman-cuda-dir)--clone[]' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; +(setup-keys) +_arguments "${_arguments_options[@]}" : \ +'--region=[]:REGION:(us europe asia)' \ +'--mode=[]:MODE:(download generate)' \ +'--chain=[Chain to use]:CHAIN: ' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; +(run) +_arguments "${_arguments_options[@]}" : \ +'--component=[]:COMPONENT:(gateway witness-generator witness-vector-generator prover circuit-prover compressor prover-job-monitor)' \ +'--round=[]:ROUND:(all-rounds basic-circuits leaf-aggregation node-aggregation recursion-tip scheduler)' \ +'--threads=[]:THREADS: ' \ +'--max-allocation=[Memory allocation limit in bytes (for prover component)]:MAX_ALLOCATION: ' \ +'--witness-vector-generator-count=[]:WITNESS_VECTOR_GENERATOR_COUNT: ' \ +'--max-allocation=[]:MAX_ALLOCATION: ' \ +'--docker=[]:DOCKER:(true false)' \ +'--tag=[]:TAG: ' \ +'--chain=[Chain to use]:CHAIN: ' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; +(init-bellman-cuda) +_arguments "${_arguments_options[@]}" : \ +'(--clone)--bellman-cuda-dir=[]:BELLMAN_CUDA_DIR: ' \ +'--chain=[Chain to use]:CHAIN: ' \ +'(--bellman-cuda-dir)--clone[]' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; +(compressor-keys) +_arguments "${_arguments_options[@]}" : \ +'--path=[]:PATH: ' \ +'--chain=[Chain to use]:CHAIN: ' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; +(help) +_arguments "${_arguments_options[@]}" : \ +":: :_zkstack__prover__help_commands" \ +"*::: :->help" \ +&& ret=0 + + case $state in + (help) + words=($line[1] "${words[@]}") + (( CURRENT += 1 )) + curcontext="${curcontext%:*:*}:zkstack-prover-help-command-$line[1]:" + case $line[1] in + (init) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(setup-keys) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(run) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(init-bellman-cuda) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(compressor-keys) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(help) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; + esac + ;; +esac +;; + esac + ;; +esac +;; +(server) +_arguments "${_arguments_options[@]}" : \ +'*--components=[Components of server to run]:COMPONENTS: ' \ +'*-a+[Additional arguments that can be passed through the CLI]:ADDITIONAL_ARGS: ' \ +'*--additional-args=[Additional arguments that can be passed through the CLI]:ADDITIONAL_ARGS: ' \ +'--chain=[Chain to use]:CHAIN: ' \ +'--genesis[Run server in genesis mode]' \ +'--build[Build server but don'\''t run it]' \ +'--uring[Enables uring support for RocksDB]' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; +(external-node) +_arguments "${_arguments_options[@]}" : \ +'--chain=[Chain to use]:CHAIN: ' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help]' \ +'--help[Print help]' \ +":: :_zkstack__external-node_commands" \ +"*::: :->external-node" \ +&& ret=0 + + case $state in + (external-node) + words=($line[1] "${words[@]}") + (( CURRENT += 1 )) + curcontext="${curcontext%:*:*}:zkstack-external-node-command-$line[1]:" + case $line[1] in + (configs) +_arguments "${_arguments_options[@]}" : \ +'--db-url=[]:DB_URL: ' \ +'--db-name=[]:DB_NAME: ' \ +'--l1-rpc-url=[]:L1_RPC_URL: ' \ +'--chain=[Chain to use]:CHAIN: ' \ +'-u[Use default database urls and names]' \ +'--use-default[Use default database urls and names]' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; +(init) +_arguments "${_arguments_options[@]}" : \ +'--chain=[Chain to use]:CHAIN: ' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; +(run) +_arguments "${_arguments_options[@]}" : \ +'*--components=[Components of server to run]:COMPONENTS: ' \ +'--enable-consensus=[Enable consensus]' \ +'*-a+[Additional arguments that can be passed through the CLI]:ADDITIONAL_ARGS: ' \ +'*--additional-args=[Additional arguments that can be passed through the CLI]:ADDITIONAL_ARGS: ' \ +'--chain=[Chain to use]:CHAIN: ' \ +'--reinit[]' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; +(help) +_arguments "${_arguments_options[@]}" : \ +":: :_zkstack__external-node__help_commands" \ +"*::: :->help" \ +&& ret=0 + + case $state in + (help) + words=($line[1] "${words[@]}") + (( CURRENT += 1 )) + curcontext="${curcontext%:*:*}:zkstack-external-node-help-command-$line[1]:" + case $line[1] in + (configs) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(init) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(run) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(help) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; + esac + ;; +esac +;; + esac + ;; +esac +;; +(containers) +_arguments "${_arguments_options[@]}" : \ +'-o+[Enable Grafana]' \ +'--observability=[Enable Grafana]' \ +'--chain=[Chain to use]:CHAIN: ' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; +(contract-verifier) +_arguments "${_arguments_options[@]}" : \ +'--chain=[Chain to use]:CHAIN: ' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help]' \ +'--help[Print help]' \ +":: :_zkstack__contract-verifier_commands" \ +"*::: :->contract-verifier" \ +&& ret=0 + + case $state in + (contract-verifier) + words=($line[1] "${words[@]}") + (( CURRENT += 1 )) + curcontext="${curcontext%:*:*}:zkstack-contract-verifier-command-$line[1]:" + case $line[1] in + (run) +_arguments "${_arguments_options[@]}" : \ +'--chain=[Chain to use]:CHAIN: ' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; +(init) +_arguments "${_arguments_options[@]}" : \ +'--zksolc-version=[Version of zksolc to install]:ZKSOLC_VERSION: ' \ +'--zkvyper-version=[Version of zkvyper to install]:ZKVYPER_VERSION: ' \ +'--solc-version=[Version of solc to install]:SOLC_VERSION: ' \ +'--era-vm-solc-version=[Version of era vm solc to install]:ERA_VM_SOLC_VERSION: ' \ +'--vyper-version=[Version of vyper to install]:VYPER_VERSION: ' \ +'--chain=[Chain to use]:CHAIN: ' \ +'--only[Install only provided compilers]' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; +(help) +_arguments "${_arguments_options[@]}" : \ +":: :_zkstack__contract-verifier__help_commands" \ +"*::: :->help" \ +&& ret=0 + + case $state in + (help) + words=($line[1] "${words[@]}") + (( CURRENT += 1 )) + curcontext="${curcontext%:*:*}:zkstack-contract-verifier-help-command-$line[1]:" + case $line[1] in + (run) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(init) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(help) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; + esac + ;; +esac +;; + esac + ;; +esac +;; +(portal) +_arguments "${_arguments_options[@]}" : \ +'--chain=[Chain to use]:CHAIN: ' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; +(explorer) +_arguments "${_arguments_options[@]}" : \ +'--chain=[Chain to use]:CHAIN: ' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help]' \ +'--help[Print help]' \ +":: :_zkstack__explorer_commands" \ +"*::: :->explorer" \ +&& ret=0 + + case $state in + (explorer) + words=($line[1] "${words[@]}") + (( CURRENT += 1 )) + curcontext="${curcontext%:*:*}:zkstack-explorer-command-$line[1]:" + case $line[1] in + (init) +_arguments "${_arguments_options[@]}" : \ +'--chain=[Chain to use]:CHAIN: ' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; +(run-backend) +_arguments "${_arguments_options[@]}" : \ +'--chain=[Chain to use]:CHAIN: ' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; +(run) +_arguments "${_arguments_options[@]}" : \ +'--chain=[Chain to use]:CHAIN: ' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; +(help) +_arguments "${_arguments_options[@]}" : \ +":: :_zkstack__explorer__help_commands" \ +"*::: :->help" \ +&& ret=0 + + case $state in + (help) + words=($line[1] "${words[@]}") + (( CURRENT += 1 )) + curcontext="${curcontext%:*:*}:zkstack-explorer-help-command-$line[1]:" + case $line[1] in + (init) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(run-backend) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(run) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(help) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; + esac + ;; +esac +;; + esac + ;; +esac +;; +(consensus) +_arguments "${_arguments_options[@]}" : \ +'--chain=[Chain to use]:CHAIN: ' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help]' \ +'--help[Print help]' \ +":: :_zkstack__consensus_commands" \ +"*::: :->consensus" \ +&& ret=0 + + case $state in + (consensus) + words=($line[1] "${words[@]}") + (( CURRENT += 1 )) + curcontext="${curcontext%:*:*}:zkstack-consensus-command-$line[1]:" + case $line[1] in + (set-attester-committee) +_arguments "${_arguments_options[@]}" : \ +'--from-file=[Sets the attester committee in the consensus registry contract to the committee in the yaml file. File format is definied in \`commands/consensus/proto/mod.proto\`]:FROM_FILE:_files' \ +'--chain=[Chain to use]:CHAIN: ' \ +'--from-genesis[Sets the attester committee in the consensus registry contract to \`consensus.genesis_spec.attesters\` in general.yaml]' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; +(get-attester-committee) +_arguments "${_arguments_options[@]}" : \ +'--chain=[Chain to use]:CHAIN: ' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; +(help) +_arguments "${_arguments_options[@]}" : \ +":: :_zkstack__consensus__help_commands" \ +"*::: :->help" \ +&& ret=0 + + case $state in + (help) + words=($line[1] "${words[@]}") + (( CURRENT += 1 )) + curcontext="${curcontext%:*:*}:zkstack-consensus-help-command-$line[1]:" + case $line[1] in + (set-attester-committee) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(get-attester-committee) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(help) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; + esac + ;; +esac +;; + esac + ;; +esac +;; +(update) +_arguments "${_arguments_options[@]}" : \ +'--chain=[Chain to use]:CHAIN: ' \ +'-c[Update only the config files]' \ +'--only-config[Update only the config files]' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; +(markdown) +_arguments "${_arguments_options[@]}" : \ +'--chain=[Chain to use]:CHAIN: ' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; +(help) +_arguments "${_arguments_options[@]}" : \ +":: :_zkstack__help_commands" \ +"*::: :->help" \ +&& ret=0 + + case $state in + (help) + words=($line[1] "${words[@]}") + (( CURRENT += 1 )) + curcontext="${curcontext%:*:*}:zkstack-help-command-$line[1]:" + case $line[1] in + (autocomplete) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(ecosystem) +_arguments "${_arguments_options[@]}" : \ +":: :_zkstack__help__ecosystem_commands" \ +"*::: :->ecosystem" \ +&& ret=0 + + case $state in + (ecosystem) + words=($line[1] "${words[@]}") + (( CURRENT += 1 )) + curcontext="${curcontext%:*:*}:zkstack-help-ecosystem-command-$line[1]:" + case $line[1] in + (create) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(build-transactions) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(init) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(change-default-chain) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(setup-observability) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; + esac + ;; +esac +;; +(chain) +_arguments "${_arguments_options[@]}" : \ +":: :_zkstack__help__chain_commands" \ +"*::: :->chain" \ +&& ret=0 + + case $state in + (chain) + words=($line[1] "${words[@]}") + (( CURRENT += 1 )) + curcontext="${curcontext%:*:*}:zkstack-help-chain-command-$line[1]:" + case $line[1] in + (create) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(build-transactions) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(init) +_arguments "${_arguments_options[@]}" : \ +":: :_zkstack__help__chain__init_commands" \ +"*::: :->init" \ +&& ret=0 + + case $state in + (init) + words=($line[1] "${words[@]}") + (( CURRENT += 1 )) + curcontext="${curcontext%:*:*}:zkstack-help-chain-init-command-$line[1]:" + case $line[1] in + (configs) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; + esac + ;; +esac +;; +(genesis) +_arguments "${_arguments_options[@]}" : \ +":: :_zkstack__help__chain__genesis_commands" \ +"*::: :->genesis" \ +&& ret=0 + + case $state in + (genesis) + words=($line[1] "${words[@]}") + (( CURRENT += 1 )) + curcontext="${curcontext%:*:*}:zkstack-help-chain-genesis-command-$line[1]:" + case $line[1] in + (init-database) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(server) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; + esac + ;; +esac +;; +(register-chain) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(deploy-l2-contracts) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(accept-chain-ownership) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(initialize-bridges) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(deploy-consensus-registry) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(deploy-multicall3) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(deploy-upgrader) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(deploy-paymaster) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(update-token-multiplier-setter) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; + esac + ;; +esac +;; +(dev) +_arguments "${_arguments_options[@]}" : \ +":: :_zkstack__help__dev_commands" \ +"*::: :->dev" \ +&& ret=0 + + case $state in + (dev) + words=($line[1] "${words[@]}") + (( CURRENT += 1 )) + curcontext="${curcontext%:*:*}:zkstack-help-dev-command-$line[1]:" + case $line[1] in + (database) +_arguments "${_arguments_options[@]}" : \ +":: :_zkstack__help__dev__database_commands" \ +"*::: :->database" \ +&& ret=0 + + case $state in + (database) + words=($line[1] "${words[@]}") + (( CURRENT += 1 )) + curcontext="${curcontext%:*:*}:zkstack-help-dev-database-command-$line[1]:" + case $line[1] in + (check-sqlx-data) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(drop) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(migrate) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(new-migration) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(prepare) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(reset) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(setup) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; + esac + ;; +esac +;; +(test) +_arguments "${_arguments_options[@]}" : \ +":: :_zkstack__help__dev__test_commands" \ +"*::: :->test" \ +&& ret=0 + + case $state in + (test) + words=($line[1] "${words[@]}") + (( CURRENT += 1 )) + curcontext="${curcontext%:*:*}:zkstack-help-dev-test-command-$line[1]:" + case $line[1] in + (integration) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(fees) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(revert) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(recovery) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(upgrade) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(build) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(rust) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(l1-contracts) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(prover) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(wallet) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(loadtest) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; + esac + ;; +esac +;; +(clean) +_arguments "${_arguments_options[@]}" : \ +":: :_zkstack__help__dev__clean_commands" \ +"*::: :->clean" \ +&& ret=0 + + case $state in + (clean) + words=($line[1] "${words[@]}") + (( CURRENT += 1 )) + curcontext="${curcontext%:*:*}:zkstack-help-dev-clean-command-$line[1]:" + case $line[1] in + (all) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(containers) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(contracts-cache) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; + esac + ;; +esac +;; +(snapshot) +_arguments "${_arguments_options[@]}" : \ +":: :_zkstack__help__dev__snapshot_commands" \ +"*::: :->snapshot" \ +&& ret=0 + + case $state in + (snapshot) + words=($line[1] "${words[@]}") + (( CURRENT += 1 )) + curcontext="${curcontext%:*:*}:zkstack-help-dev-snapshot-command-$line[1]:" + case $line[1] in + (create) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; + esac + ;; +esac +;; +(lint) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(fmt) +_arguments "${_arguments_options[@]}" : \ +":: :_zkstack__help__dev__fmt_commands" \ +"*::: :->fmt" \ +&& ret=0 + + case $state in + (fmt) + words=($line[1] "${words[@]}") + (( CURRENT += 1 )) + curcontext="${curcontext%:*:*}:zkstack-help-dev-fmt-command-$line[1]:" + case $line[1] in + (rustfmt) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(contract) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(prettier) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; + esac + ;; +esac +;; +(prover) +_arguments "${_arguments_options[@]}" : \ +":: :_zkstack__help__dev__prover_commands" \ +"*::: :->prover" \ +&& ret=0 + + case $state in + (prover) + words=($line[1] "${words[@]}") + (( CURRENT += 1 )) + curcontext="${curcontext%:*:*}:zkstack-help-dev-prover-command-$line[1]:" + case $line[1] in + (info) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(insert-batch) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(insert-version) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; + esac + ;; +esac +;; +(contracts) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(config-writer) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(send-transactions) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(status) +_arguments "${_arguments_options[@]}" : \ +":: :_zkstack__help__dev__status_commands" \ +"*::: :->status" \ +&& ret=0 + + case $state in + (status) + words=($line[1] "${words[@]}") + (( CURRENT += 1 )) + curcontext="${curcontext%:*:*}:zkstack-help-dev-status-command-$line[1]:" + case $line[1] in + (ports) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; + esac + ;; +esac +;; +(generate-genesis) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; + esac + ;; +esac +;; +(prover) +_arguments "${_arguments_options[@]}" : \ +":: :_zkstack__help__prover_commands" \ +"*::: :->prover" \ +&& ret=0 + + case $state in + (prover) + words=($line[1] "${words[@]}") + (( CURRENT += 1 )) + curcontext="${curcontext%:*:*}:zkstack-help-prover-command-$line[1]:" + case $line[1] in + (init) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(setup-keys) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(run) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(init-bellman-cuda) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(compressor-keys) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; + esac + ;; +esac +;; +(server) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(external-node) +_arguments "${_arguments_options[@]}" : \ +":: :_zkstack__help__external-node_commands" \ +"*::: :->external-node" \ +&& ret=0 + + case $state in + (external-node) + words=($line[1] "${words[@]}") + (( CURRENT += 1 )) + curcontext="${curcontext%:*:*}:zkstack-help-external-node-command-$line[1]:" + case $line[1] in + (configs) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(init) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(run) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; + esac + ;; +esac +;; +(containers) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(contract-verifier) +_arguments "${_arguments_options[@]}" : \ +":: :_zkstack__help__contract-verifier_commands" \ +"*::: :->contract-verifier" \ +&& ret=0 + + case $state in + (contract-verifier) + words=($line[1] "${words[@]}") + (( CURRENT += 1 )) + curcontext="${curcontext%:*:*}:zkstack-help-contract-verifier-command-$line[1]:" + case $line[1] in + (run) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(init) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; + esac + ;; +esac +;; +(portal) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(explorer) +_arguments "${_arguments_options[@]}" : \ +":: :_zkstack__help__explorer_commands" \ +"*::: :->explorer" \ +&& ret=0 + + case $state in + (explorer) + words=($line[1] "${words[@]}") + (( CURRENT += 1 )) + curcontext="${curcontext%:*:*}:zkstack-help-explorer-command-$line[1]:" + case $line[1] in + (init) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(run-backend) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(run) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; + esac + ;; +esac +;; +(consensus) +_arguments "${_arguments_options[@]}" : \ +":: :_zkstack__help__consensus_commands" \ +"*::: :->consensus" \ +&& ret=0 + + case $state in + (consensus) + words=($line[1] "${words[@]}") + (( CURRENT += 1 )) + curcontext="${curcontext%:*:*}:zkstack-help-consensus-command-$line[1]:" + case $line[1] in + (set-attester-committee) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(get-attester-committee) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; + esac + ;; +esac +;; +(update) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(markdown) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(help) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; + esac + ;; +esac +;; + esac + ;; +esac +} + +(( $+functions[_zkstack_commands] )) || +_zkstack_commands() { + local commands; commands=( +'autocomplete:Create shell autocompletion files' \ +'ecosystem:Ecosystem related commands' \ +'chain:Chain related commands' \ +'dev:Supervisor related commands' \ +'prover:Prover related commands' \ +'server:Run server' \ +'external-node:External Node related commands' \ +'containers:Run containers for local development' \ +'contract-verifier:Run contract verifier' \ +'portal:Run dapp-portal' \ +'explorer:Run block-explorer' \ +'consensus:Consensus utilities' \ +'update:Update ZKsync' \ +'markdown:Print markdown help' \ +'help:Print this message or the help of the given subcommand(s)' \ + ) + _describe -t commands 'zkstack commands' commands "$@" +} +(( $+functions[_zkstack__autocomplete_commands] )) || +_zkstack__autocomplete_commands() { + local commands; commands=() + _describe -t commands 'zkstack autocomplete commands' commands "$@" +} +(( $+functions[_zkstack__chain_commands] )) || +_zkstack__chain_commands() { + local commands; commands=( +'create:Create a new chain, setting the necessary configurations for later initialization' \ +'build-transactions:Create unsigned transactions for chain deployment' \ +'init:Initialize chain, deploying necessary contracts and performing on-chain operations' \ +'genesis:Run server genesis' \ +'register-chain:Register a new chain on L1 (executed by L1 governor). This command deploys and configures Governance, ChainAdmin, and DiamondProxy contracts, registers chain with BridgeHub and sets pending admin for DiamondProxy. Note\: After completion, L2 governor can accept ownership by running \`accept-chain-ownership\`' \ +'deploy-l2-contracts:Deploy all L2 contracts (executed by L1 governor)' \ +'accept-chain-ownership:Accept ownership of L2 chain (executed by L2 governor). This command should be run after \`register-chain\` to accept ownership of newly created DiamondProxy contract' \ +'initialize-bridges:Initialize bridges on L2' \ +'deploy-consensus-registry:Deploy L2 consensus registry' \ +'deploy-multicall3:Deploy L2 multicall3' \ +'deploy-upgrader:Deploy Default Upgrader' \ +'deploy-paymaster:Deploy paymaster smart contract' \ +'update-token-multiplier-setter:Update Token Multiplier Setter address on L1' \ +'help:Print this message or the help of the given subcommand(s)' \ + ) + _describe -t commands 'zkstack chain commands' commands "$@" +} +(( $+functions[_zkstack__chain__accept-chain-ownership_commands] )) || +_zkstack__chain__accept-chain-ownership_commands() { + local commands; commands=() + _describe -t commands 'zkstack chain accept-chain-ownership commands' commands "$@" +} +(( $+functions[_zkstack__chain__build-transactions_commands] )) || +_zkstack__chain__build-transactions_commands() { + local commands; commands=() + _describe -t commands 'zkstack chain build-transactions commands' commands "$@" +} +(( $+functions[_zkstack__chain__create_commands] )) || +_zkstack__chain__create_commands() { + local commands; commands=() + _describe -t commands 'zkstack chain create commands' commands "$@" +} +(( $+functions[_zkstack__chain__deploy-consensus-registry_commands] )) || +_zkstack__chain__deploy-consensus-registry_commands() { + local commands; commands=() + _describe -t commands 'zkstack chain deploy-consensus-registry commands' commands "$@" +} +(( $+functions[_zkstack__chain__deploy-l2-contracts_commands] )) || +_zkstack__chain__deploy-l2-contracts_commands() { + local commands; commands=() + _describe -t commands 'zkstack chain deploy-l2-contracts commands' commands "$@" +} +(( $+functions[_zkstack__chain__deploy-multicall3_commands] )) || +_zkstack__chain__deploy-multicall3_commands() { + local commands; commands=() + _describe -t commands 'zkstack chain deploy-multicall3 commands' commands "$@" +} +(( $+functions[_zkstack__chain__deploy-paymaster_commands] )) || +_zkstack__chain__deploy-paymaster_commands() { + local commands; commands=() + _describe -t commands 'zkstack chain deploy-paymaster commands' commands "$@" +} +(( $+functions[_zkstack__chain__deploy-upgrader_commands] )) || +_zkstack__chain__deploy-upgrader_commands() { + local commands; commands=() + _describe -t commands 'zkstack chain deploy-upgrader commands' commands "$@" +} +(( $+functions[_zkstack__chain__genesis_commands] )) || +_zkstack__chain__genesis_commands() { + local commands; commands=( +'init-database:Initialize databases' \ +'server:Runs server genesis' \ +'help:Print this message or the help of the given subcommand(s)' \ + ) + _describe -t commands 'zkstack chain genesis commands' commands "$@" +} +(( $+functions[_zkstack__chain__genesis__help_commands] )) || +_zkstack__chain__genesis__help_commands() { + local commands; commands=( +'init-database:Initialize databases' \ +'server:Runs server genesis' \ +'help:Print this message or the help of the given subcommand(s)' \ + ) + _describe -t commands 'zkstack chain genesis help commands' commands "$@" +} +(( $+functions[_zkstack__chain__genesis__help__help_commands] )) || +_zkstack__chain__genesis__help__help_commands() { + local commands; commands=() + _describe -t commands 'zkstack chain genesis help help commands' commands "$@" +} +(( $+functions[_zkstack__chain__genesis__help__init-database_commands] )) || +_zkstack__chain__genesis__help__init-database_commands() { + local commands; commands=() + _describe -t commands 'zkstack chain genesis help init-database commands' commands "$@" +} +(( $+functions[_zkstack__chain__genesis__help__server_commands] )) || +_zkstack__chain__genesis__help__server_commands() { + local commands; commands=() + _describe -t commands 'zkstack chain genesis help server commands' commands "$@" +} +(( $+functions[_zkstack__chain__genesis__init-database_commands] )) || +_zkstack__chain__genesis__init-database_commands() { + local commands; commands=() + _describe -t commands 'zkstack chain genesis init-database commands' commands "$@" +} +(( $+functions[_zkstack__chain__genesis__server_commands] )) || +_zkstack__chain__genesis__server_commands() { + local commands; commands=() + _describe -t commands 'zkstack chain genesis server commands' commands "$@" +} +(( $+functions[_zkstack__chain__help_commands] )) || +_zkstack__chain__help_commands() { + local commands; commands=( +'create:Create a new chain, setting the necessary configurations for later initialization' \ +'build-transactions:Create unsigned transactions for chain deployment' \ +'init:Initialize chain, deploying necessary contracts and performing on-chain operations' \ +'genesis:Run server genesis' \ +'register-chain:Register a new chain on L1 (executed by L1 governor). This command deploys and configures Governance, ChainAdmin, and DiamondProxy contracts, registers chain with BridgeHub and sets pending admin for DiamondProxy. Note\: After completion, L2 governor can accept ownership by running \`accept-chain-ownership\`' \ +'deploy-l2-contracts:Deploy all L2 contracts (executed by L1 governor)' \ +'accept-chain-ownership:Accept ownership of L2 chain (executed by L2 governor). This command should be run after \`register-chain\` to accept ownership of newly created DiamondProxy contract' \ +'initialize-bridges:Initialize bridges on L2' \ +'deploy-consensus-registry:Deploy L2 consensus registry' \ +'deploy-multicall3:Deploy L2 multicall3' \ +'deploy-upgrader:Deploy Default Upgrader' \ +'deploy-paymaster:Deploy paymaster smart contract' \ +'update-token-multiplier-setter:Update Token Multiplier Setter address on L1' \ +'help:Print this message or the help of the given subcommand(s)' \ + ) + _describe -t commands 'zkstack chain help commands' commands "$@" +} +(( $+functions[_zkstack__chain__help__accept-chain-ownership_commands] )) || +_zkstack__chain__help__accept-chain-ownership_commands() { + local commands; commands=() + _describe -t commands 'zkstack chain help accept-chain-ownership commands' commands "$@" +} +(( $+functions[_zkstack__chain__help__build-transactions_commands] )) || +_zkstack__chain__help__build-transactions_commands() { + local commands; commands=() + _describe -t commands 'zkstack chain help build-transactions commands' commands "$@" +} +(( $+functions[_zkstack__chain__help__create_commands] )) || +_zkstack__chain__help__create_commands() { + local commands; commands=() + _describe -t commands 'zkstack chain help create commands' commands "$@" +} +(( $+functions[_zkstack__chain__help__deploy-consensus-registry_commands] )) || +_zkstack__chain__help__deploy-consensus-registry_commands() { + local commands; commands=() + _describe -t commands 'zkstack chain help deploy-consensus-registry commands' commands "$@" +} +(( $+functions[_zkstack__chain__help__deploy-l2-contracts_commands] )) || +_zkstack__chain__help__deploy-l2-contracts_commands() { + local commands; commands=() + _describe -t commands 'zkstack chain help deploy-l2-contracts commands' commands "$@" +} +(( $+functions[_zkstack__chain__help__deploy-multicall3_commands] )) || +_zkstack__chain__help__deploy-multicall3_commands() { + local commands; commands=() + _describe -t commands 'zkstack chain help deploy-multicall3 commands' commands "$@" +} +(( $+functions[_zkstack__chain__help__deploy-paymaster_commands] )) || +_zkstack__chain__help__deploy-paymaster_commands() { + local commands; commands=() + _describe -t commands 'zkstack chain help deploy-paymaster commands' commands "$@" +} +(( $+functions[_zkstack__chain__help__deploy-upgrader_commands] )) || +_zkstack__chain__help__deploy-upgrader_commands() { + local commands; commands=() + _describe -t commands 'zkstack chain help deploy-upgrader commands' commands "$@" +} +(( $+functions[_zkstack__chain__help__genesis_commands] )) || +_zkstack__chain__help__genesis_commands() { + local commands; commands=( +'init-database:Initialize databases' \ +'server:Runs server genesis' \ + ) + _describe -t commands 'zkstack chain help genesis commands' commands "$@" +} +(( $+functions[_zkstack__chain__help__genesis__init-database_commands] )) || +_zkstack__chain__help__genesis__init-database_commands() { + local commands; commands=() + _describe -t commands 'zkstack chain help genesis init-database commands' commands "$@" +} +(( $+functions[_zkstack__chain__help__genesis__server_commands] )) || +_zkstack__chain__help__genesis__server_commands() { + local commands; commands=() + _describe -t commands 'zkstack chain help genesis server commands' commands "$@" +} +(( $+functions[_zkstack__chain__help__help_commands] )) || +_zkstack__chain__help__help_commands() { + local commands; commands=() + _describe -t commands 'zkstack chain help help commands' commands "$@" +} +(( $+functions[_zkstack__chain__help__init_commands] )) || +_zkstack__chain__help__init_commands() { + local commands; commands=( +'configs:Initialize chain configs' \ + ) + _describe -t commands 'zkstack chain help init commands' commands "$@" +} +(( $+functions[_zkstack__chain__help__init__configs_commands] )) || +_zkstack__chain__help__init__configs_commands() { + local commands; commands=() + _describe -t commands 'zkstack chain help init configs commands' commands "$@" +} +(( $+functions[_zkstack__chain__help__initialize-bridges_commands] )) || +_zkstack__chain__help__initialize-bridges_commands() { + local commands; commands=() + _describe -t commands 'zkstack chain help initialize-bridges commands' commands "$@" +} +(( $+functions[_zkstack__chain__help__register-chain_commands] )) || +_zkstack__chain__help__register-chain_commands() { + local commands; commands=() + _describe -t commands 'zkstack chain help register-chain commands' commands "$@" +} +(( $+functions[_zkstack__chain__help__update-token-multiplier-setter_commands] )) || +_zkstack__chain__help__update-token-multiplier-setter_commands() { + local commands; commands=() + _describe -t commands 'zkstack chain help update-token-multiplier-setter commands' commands "$@" +} +(( $+functions[_zkstack__chain__init_commands] )) || +_zkstack__chain__init_commands() { + local commands; commands=( +'configs:Initialize chain configs' \ +'help:Print this message or the help of the given subcommand(s)' \ + ) + _describe -t commands 'zkstack chain init commands' commands "$@" +} +(( $+functions[_zkstack__chain__init__configs_commands] )) || +_zkstack__chain__init__configs_commands() { + local commands; commands=() + _describe -t commands 'zkstack chain init configs commands' commands "$@" +} +(( $+functions[_zkstack__chain__init__help_commands] )) || +_zkstack__chain__init__help_commands() { + local commands; commands=( +'configs:Initialize chain configs' \ +'help:Print this message or the help of the given subcommand(s)' \ + ) + _describe -t commands 'zkstack chain init help commands' commands "$@" +} +(( $+functions[_zkstack__chain__init__help__configs_commands] )) || +_zkstack__chain__init__help__configs_commands() { + local commands; commands=() + _describe -t commands 'zkstack chain init help configs commands' commands "$@" +} +(( $+functions[_zkstack__chain__init__help__help_commands] )) || +_zkstack__chain__init__help__help_commands() { + local commands; commands=() + _describe -t commands 'zkstack chain init help help commands' commands "$@" +} +(( $+functions[_zkstack__chain__initialize-bridges_commands] )) || +_zkstack__chain__initialize-bridges_commands() { + local commands; commands=() + _describe -t commands 'zkstack chain initialize-bridges commands' commands "$@" +} +(( $+functions[_zkstack__chain__register-chain_commands] )) || +_zkstack__chain__register-chain_commands() { + local commands; commands=() + _describe -t commands 'zkstack chain register-chain commands' commands "$@" +} +(( $+functions[_zkstack__chain__update-token-multiplier-setter_commands] )) || +_zkstack__chain__update-token-multiplier-setter_commands() { + local commands; commands=() + _describe -t commands 'zkstack chain update-token-multiplier-setter commands' commands "$@" +} +(( $+functions[_zkstack__consensus_commands] )) || +_zkstack__consensus_commands() { + local commands; commands=( +'set-attester-committee:Sets the attester committee in the consensus registry contract to \`consensus.genesis_spec.attesters\` in general.yaml' \ +'get-attester-committee:Fetches the attester committee from the consensus registry contract' \ +'help:Print this message or the help of the given subcommand(s)' \ + ) + _describe -t commands 'zkstack consensus commands' commands "$@" +} +(( $+functions[_zkstack__consensus__get-attester-committee_commands] )) || +_zkstack__consensus__get-attester-committee_commands() { + local commands; commands=() + _describe -t commands 'zkstack consensus get-attester-committee commands' commands "$@" +} +(( $+functions[_zkstack__consensus__help_commands] )) || +_zkstack__consensus__help_commands() { + local commands; commands=( +'set-attester-committee:Sets the attester committee in the consensus registry contract to \`consensus.genesis_spec.attesters\` in general.yaml' \ +'get-attester-committee:Fetches the attester committee from the consensus registry contract' \ +'help:Print this message or the help of the given subcommand(s)' \ + ) + _describe -t commands 'zkstack consensus help commands' commands "$@" +} +(( $+functions[_zkstack__consensus__help__get-attester-committee_commands] )) || +_zkstack__consensus__help__get-attester-committee_commands() { + local commands; commands=() + _describe -t commands 'zkstack consensus help get-attester-committee commands' commands "$@" +} +(( $+functions[_zkstack__consensus__help__help_commands] )) || +_zkstack__consensus__help__help_commands() { + local commands; commands=() + _describe -t commands 'zkstack consensus help help commands' commands "$@" +} +(( $+functions[_zkstack__consensus__help__set-attester-committee_commands] )) || +_zkstack__consensus__help__set-attester-committee_commands() { + local commands; commands=() + _describe -t commands 'zkstack consensus help set-attester-committee commands' commands "$@" +} +(( $+functions[_zkstack__consensus__set-attester-committee_commands] )) || +_zkstack__consensus__set-attester-committee_commands() { + local commands; commands=() + _describe -t commands 'zkstack consensus set-attester-committee commands' commands "$@" +} +(( $+functions[_zkstack__containers_commands] )) || +_zkstack__containers_commands() { + local commands; commands=() + _describe -t commands 'zkstack containers commands' commands "$@" +} +(( $+functions[_zkstack__contract-verifier_commands] )) || +_zkstack__contract-verifier_commands() { + local commands; commands=( +'run:Run contract verifier' \ +'init:Download required binaries for contract verifier' \ +'help:Print this message or the help of the given subcommand(s)' \ + ) + _describe -t commands 'zkstack contract-verifier commands' commands "$@" +} +(( $+functions[_zkstack__contract-verifier__help_commands] )) || +_zkstack__contract-verifier__help_commands() { + local commands; commands=( +'run:Run contract verifier' \ +'init:Download required binaries for contract verifier' \ +'help:Print this message or the help of the given subcommand(s)' \ + ) + _describe -t commands 'zkstack contract-verifier help commands' commands "$@" +} +(( $+functions[_zkstack__contract-verifier__help__help_commands] )) || +_zkstack__contract-verifier__help__help_commands() { + local commands; commands=() + _describe -t commands 'zkstack contract-verifier help help commands' commands "$@" +} +(( $+functions[_zkstack__contract-verifier__help__init_commands] )) || +_zkstack__contract-verifier__help__init_commands() { + local commands; commands=() + _describe -t commands 'zkstack contract-verifier help init commands' commands "$@" +} +(( $+functions[_zkstack__contract-verifier__help__run_commands] )) || +_zkstack__contract-verifier__help__run_commands() { + local commands; commands=() + _describe -t commands 'zkstack contract-verifier help run commands' commands "$@" +} +(( $+functions[_zkstack__contract-verifier__init_commands] )) || +_zkstack__contract-verifier__init_commands() { + local commands; commands=() + _describe -t commands 'zkstack contract-verifier init commands' commands "$@" +} +(( $+functions[_zkstack__contract-verifier__run_commands] )) || +_zkstack__contract-verifier__run_commands() { + local commands; commands=() + _describe -t commands 'zkstack contract-verifier run commands' commands "$@" +} +(( $+functions[_zkstack__dev_commands] )) || +_zkstack__dev_commands() { + local commands; commands=( +'database:Database related commands' \ +'test:Run tests' \ +'clean:Clean artifacts' \ +'snapshot:Snapshots creator' \ +'lint:Lint code' \ +'fmt:Format code' \ +'prover:Protocol version used by provers' \ +'contracts:Build contracts' \ +'config-writer:Overwrite general config' \ +'send-transactions:Send transactions from file' \ +'status:Get status of the server' \ +'generate-genesis:Generate new genesis file based on current contracts' \ +'help:Print this message or the help of the given subcommand(s)' \ + ) + _describe -t commands 'zkstack dev commands' commands "$@" +} +(( $+functions[_zkstack__dev__clean_commands] )) || +_zkstack__dev__clean_commands() { + local commands; commands=( +'all:Remove containers and contracts cache' \ +'containers:Remove containers and docker volumes' \ +'contracts-cache:Remove contracts caches' \ +'help:Print this message or the help of the given subcommand(s)' \ + ) + _describe -t commands 'zkstack dev clean commands' commands "$@" +} +(( $+functions[_zkstack__dev__clean__all_commands] )) || +_zkstack__dev__clean__all_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev clean all commands' commands "$@" +} +(( $+functions[_zkstack__dev__clean__containers_commands] )) || +_zkstack__dev__clean__containers_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev clean containers commands' commands "$@" +} +(( $+functions[_zkstack__dev__clean__contracts-cache_commands] )) || +_zkstack__dev__clean__contracts-cache_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev clean contracts-cache commands' commands "$@" +} +(( $+functions[_zkstack__dev__clean__help_commands] )) || +_zkstack__dev__clean__help_commands() { + local commands; commands=( +'all:Remove containers and contracts cache' \ +'containers:Remove containers and docker volumes' \ +'contracts-cache:Remove contracts caches' \ +'help:Print this message or the help of the given subcommand(s)' \ + ) + _describe -t commands 'zkstack dev clean help commands' commands "$@" +} +(( $+functions[_zkstack__dev__clean__help__all_commands] )) || +_zkstack__dev__clean__help__all_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev clean help all commands' commands "$@" +} +(( $+functions[_zkstack__dev__clean__help__containers_commands] )) || +_zkstack__dev__clean__help__containers_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev clean help containers commands' commands "$@" +} +(( $+functions[_zkstack__dev__clean__help__contracts-cache_commands] )) || +_zkstack__dev__clean__help__contracts-cache_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev clean help contracts-cache commands' commands "$@" +} +(( $+functions[_zkstack__dev__clean__help__help_commands] )) || +_zkstack__dev__clean__help__help_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev clean help help commands' commands "$@" +} +(( $+functions[_zkstack__dev__config-writer_commands] )) || +_zkstack__dev__config-writer_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev config-writer commands' commands "$@" +} +(( $+functions[_zkstack__dev__contracts_commands] )) || +_zkstack__dev__contracts_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev contracts commands' commands "$@" +} +(( $+functions[_zkstack__dev__database_commands] )) || +_zkstack__dev__database_commands() { + local commands; commands=( +'check-sqlx-data:Check sqlx-data.json is up to date. If no databases are selected, all databases will be checked.' \ +'drop:Drop databases. If no databases are selected, all databases will be dropped.' \ +'migrate:Migrate databases. If no databases are selected, all databases will be migrated.' \ +'new-migration:Create new migration' \ +'prepare:Prepare sqlx-data.json. If no databases are selected, all databases will be prepared.' \ +'reset:Reset databases. If no databases are selected, all databases will be reset.' \ +'setup:Setup databases. If no databases are selected, all databases will be setup.' \ +'help:Print this message or the help of the given subcommand(s)' \ + ) + _describe -t commands 'zkstack dev database commands' commands "$@" +} +(( $+functions[_zkstack__dev__database__check-sqlx-data_commands] )) || +_zkstack__dev__database__check-sqlx-data_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev database check-sqlx-data commands' commands "$@" +} +(( $+functions[_zkstack__dev__database__drop_commands] )) || +_zkstack__dev__database__drop_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev database drop commands' commands "$@" +} +(( $+functions[_zkstack__dev__database__help_commands] )) || +_zkstack__dev__database__help_commands() { + local commands; commands=( +'check-sqlx-data:Check sqlx-data.json is up to date. If no databases are selected, all databases will be checked.' \ +'drop:Drop databases. If no databases are selected, all databases will be dropped.' \ +'migrate:Migrate databases. If no databases are selected, all databases will be migrated.' \ +'new-migration:Create new migration' \ +'prepare:Prepare sqlx-data.json. If no databases are selected, all databases will be prepared.' \ +'reset:Reset databases. If no databases are selected, all databases will be reset.' \ +'setup:Setup databases. If no databases are selected, all databases will be setup.' \ +'help:Print this message or the help of the given subcommand(s)' \ + ) + _describe -t commands 'zkstack dev database help commands' commands "$@" +} +(( $+functions[_zkstack__dev__database__help__check-sqlx-data_commands] )) || +_zkstack__dev__database__help__check-sqlx-data_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev database help check-sqlx-data commands' commands "$@" +} +(( $+functions[_zkstack__dev__database__help__drop_commands] )) || +_zkstack__dev__database__help__drop_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev database help drop commands' commands "$@" +} +(( $+functions[_zkstack__dev__database__help__help_commands] )) || +_zkstack__dev__database__help__help_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev database help help commands' commands "$@" +} +(( $+functions[_zkstack__dev__database__help__migrate_commands] )) || +_zkstack__dev__database__help__migrate_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev database help migrate commands' commands "$@" +} +(( $+functions[_zkstack__dev__database__help__new-migration_commands] )) || +_zkstack__dev__database__help__new-migration_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev database help new-migration commands' commands "$@" +} +(( $+functions[_zkstack__dev__database__help__prepare_commands] )) || +_zkstack__dev__database__help__prepare_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev database help prepare commands' commands "$@" +} +(( $+functions[_zkstack__dev__database__help__reset_commands] )) || +_zkstack__dev__database__help__reset_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev database help reset commands' commands "$@" +} +(( $+functions[_zkstack__dev__database__help__setup_commands] )) || +_zkstack__dev__database__help__setup_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev database help setup commands' commands "$@" +} +(( $+functions[_zkstack__dev__database__migrate_commands] )) || +_zkstack__dev__database__migrate_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev database migrate commands' commands "$@" +} +(( $+functions[_zkstack__dev__database__new-migration_commands] )) || +_zkstack__dev__database__new-migration_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev database new-migration commands' commands "$@" +} +(( $+functions[_zkstack__dev__database__prepare_commands] )) || +_zkstack__dev__database__prepare_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev database prepare commands' commands "$@" +} +(( $+functions[_zkstack__dev__database__reset_commands] )) || +_zkstack__dev__database__reset_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev database reset commands' commands "$@" +} +(( $+functions[_zkstack__dev__database__setup_commands] )) || +_zkstack__dev__database__setup_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev database setup commands' commands "$@" +} +(( $+functions[_zkstack__dev__fmt_commands] )) || +_zkstack__dev__fmt_commands() { + local commands; commands=( +'rustfmt:' \ +'contract:' \ +'prettier:' \ +'help:Print this message or the help of the given subcommand(s)' \ + ) + _describe -t commands 'zkstack dev fmt commands' commands "$@" +} +(( $+functions[_zkstack__dev__fmt__contract_commands] )) || +_zkstack__dev__fmt__contract_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev fmt contract commands' commands "$@" +} +(( $+functions[_zkstack__dev__fmt__help_commands] )) || +_zkstack__dev__fmt__help_commands() { + local commands; commands=( +'rustfmt:' \ +'contract:' \ +'prettier:' \ +'help:Print this message or the help of the given subcommand(s)' \ + ) + _describe -t commands 'zkstack dev fmt help commands' commands "$@" +} +(( $+functions[_zkstack__dev__fmt__help__contract_commands] )) || +_zkstack__dev__fmt__help__contract_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev fmt help contract commands' commands "$@" +} +(( $+functions[_zkstack__dev__fmt__help__help_commands] )) || +_zkstack__dev__fmt__help__help_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev fmt help help commands' commands "$@" +} +(( $+functions[_zkstack__dev__fmt__help__prettier_commands] )) || +_zkstack__dev__fmt__help__prettier_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev fmt help prettier commands' commands "$@" +} +(( $+functions[_zkstack__dev__fmt__help__rustfmt_commands] )) || +_zkstack__dev__fmt__help__rustfmt_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev fmt help rustfmt commands' commands "$@" +} +(( $+functions[_zkstack__dev__fmt__prettier_commands] )) || +_zkstack__dev__fmt__prettier_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev fmt prettier commands' commands "$@" +} +(( $+functions[_zkstack__dev__fmt__rustfmt_commands] )) || +_zkstack__dev__fmt__rustfmt_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev fmt rustfmt commands' commands "$@" +} +(( $+functions[_zkstack__dev__generate-genesis_commands] )) || +_zkstack__dev__generate-genesis_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev generate-genesis commands' commands "$@" +} +(( $+functions[_zkstack__dev__help_commands] )) || +_zkstack__dev__help_commands() { + local commands; commands=( +'database:Database related commands' \ +'test:Run tests' \ +'clean:Clean artifacts' \ +'snapshot:Snapshots creator' \ +'lint:Lint code' \ +'fmt:Format code' \ +'prover:Protocol version used by provers' \ +'contracts:Build contracts' \ +'config-writer:Overwrite general config' \ +'send-transactions:Send transactions from file' \ +'status:Get status of the server' \ +'generate-genesis:Generate new genesis file based on current contracts' \ +'help:Print this message or the help of the given subcommand(s)' \ + ) + _describe -t commands 'zkstack dev help commands' commands "$@" +} +(( $+functions[_zkstack__dev__help__clean_commands] )) || +_zkstack__dev__help__clean_commands() { + local commands; commands=( +'all:Remove containers and contracts cache' \ +'containers:Remove containers and docker volumes' \ +'contracts-cache:Remove contracts caches' \ + ) + _describe -t commands 'zkstack dev help clean commands' commands "$@" +} +(( $+functions[_zkstack__dev__help__clean__all_commands] )) || +_zkstack__dev__help__clean__all_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev help clean all commands' commands "$@" +} +(( $+functions[_zkstack__dev__help__clean__containers_commands] )) || +_zkstack__dev__help__clean__containers_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev help clean containers commands' commands "$@" +} +(( $+functions[_zkstack__dev__help__clean__contracts-cache_commands] )) || +_zkstack__dev__help__clean__contracts-cache_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev help clean contracts-cache commands' commands "$@" +} +(( $+functions[_zkstack__dev__help__config-writer_commands] )) || +_zkstack__dev__help__config-writer_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev help config-writer commands' commands "$@" +} +(( $+functions[_zkstack__dev__help__contracts_commands] )) || +_zkstack__dev__help__contracts_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev help contracts commands' commands "$@" +} +(( $+functions[_zkstack__dev__help__database_commands] )) || +_zkstack__dev__help__database_commands() { + local commands; commands=( +'check-sqlx-data:Check sqlx-data.json is up to date. If no databases are selected, all databases will be checked.' \ +'drop:Drop databases. If no databases are selected, all databases will be dropped.' \ +'migrate:Migrate databases. If no databases are selected, all databases will be migrated.' \ +'new-migration:Create new migration' \ +'prepare:Prepare sqlx-data.json. If no databases are selected, all databases will be prepared.' \ +'reset:Reset databases. If no databases are selected, all databases will be reset.' \ +'setup:Setup databases. If no databases are selected, all databases will be setup.' \ + ) + _describe -t commands 'zkstack dev help database commands' commands "$@" +} +(( $+functions[_zkstack__dev__help__database__check-sqlx-data_commands] )) || +_zkstack__dev__help__database__check-sqlx-data_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev help database check-sqlx-data commands' commands "$@" +} +(( $+functions[_zkstack__dev__help__database__drop_commands] )) || +_zkstack__dev__help__database__drop_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev help database drop commands' commands "$@" +} +(( $+functions[_zkstack__dev__help__database__migrate_commands] )) || +_zkstack__dev__help__database__migrate_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev help database migrate commands' commands "$@" +} +(( $+functions[_zkstack__dev__help__database__new-migration_commands] )) || +_zkstack__dev__help__database__new-migration_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev help database new-migration commands' commands "$@" +} +(( $+functions[_zkstack__dev__help__database__prepare_commands] )) || +_zkstack__dev__help__database__prepare_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev help database prepare commands' commands "$@" +} +(( $+functions[_zkstack__dev__help__database__reset_commands] )) || +_zkstack__dev__help__database__reset_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev help database reset commands' commands "$@" +} +(( $+functions[_zkstack__dev__help__database__setup_commands] )) || +_zkstack__dev__help__database__setup_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev help database setup commands' commands "$@" +} +(( $+functions[_zkstack__dev__help__fmt_commands] )) || +_zkstack__dev__help__fmt_commands() { + local commands; commands=( +'rustfmt:' \ +'contract:' \ +'prettier:' \ + ) + _describe -t commands 'zkstack dev help fmt commands' commands "$@" +} +(( $+functions[_zkstack__dev__help__fmt__contract_commands] )) || +_zkstack__dev__help__fmt__contract_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev help fmt contract commands' commands "$@" +} +(( $+functions[_zkstack__dev__help__fmt__prettier_commands] )) || +_zkstack__dev__help__fmt__prettier_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev help fmt prettier commands' commands "$@" +} +(( $+functions[_zkstack__dev__help__fmt__rustfmt_commands] )) || +_zkstack__dev__help__fmt__rustfmt_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev help fmt rustfmt commands' commands "$@" +} +(( $+functions[_zkstack__dev__help__generate-genesis_commands] )) || +_zkstack__dev__help__generate-genesis_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev help generate-genesis commands' commands "$@" +} +(( $+functions[_zkstack__dev__help__help_commands] )) || +_zkstack__dev__help__help_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev help help commands' commands "$@" +} +(( $+functions[_zkstack__dev__help__lint_commands] )) || +_zkstack__dev__help__lint_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev help lint commands' commands "$@" +} +(( $+functions[_zkstack__dev__help__prover_commands] )) || +_zkstack__dev__help__prover_commands() { + local commands; commands=( +'info:' \ +'insert-batch:' \ +'insert-version:' \ + ) + _describe -t commands 'zkstack dev help prover commands' commands "$@" +} +(( $+functions[_zkstack__dev__help__prover__info_commands] )) || +_zkstack__dev__help__prover__info_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev help prover info commands' commands "$@" +} +(( $+functions[_zkstack__dev__help__prover__insert-batch_commands] )) || +_zkstack__dev__help__prover__insert-batch_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev help prover insert-batch commands' commands "$@" +} +(( $+functions[_zkstack__dev__help__prover__insert-version_commands] )) || +_zkstack__dev__help__prover__insert-version_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev help prover insert-version commands' commands "$@" +} +(( $+functions[_zkstack__dev__help__send-transactions_commands] )) || +_zkstack__dev__help__send-transactions_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev help send-transactions commands' commands "$@" +} +(( $+functions[_zkstack__dev__help__snapshot_commands] )) || +_zkstack__dev__help__snapshot_commands() { + local commands; commands=( +'create:' \ + ) + _describe -t commands 'zkstack dev help snapshot commands' commands "$@" +} +(( $+functions[_zkstack__dev__help__snapshot__create_commands] )) || +_zkstack__dev__help__snapshot__create_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev help snapshot create commands' commands "$@" +} +(( $+functions[_zkstack__dev__help__status_commands] )) || +_zkstack__dev__help__status_commands() { + local commands; commands=( +'ports:Show used ports' \ + ) + _describe -t commands 'zkstack dev help status commands' commands "$@" +} +(( $+functions[_zkstack__dev__help__status__ports_commands] )) || +_zkstack__dev__help__status__ports_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev help status ports commands' commands "$@" +} +(( $+functions[_zkstack__dev__help__test_commands] )) || +_zkstack__dev__help__test_commands() { + local commands; commands=( +'integration:Run integration tests' \ +'fees:Run fees test' \ +'revert:Run revert tests' \ +'recovery:Run recovery tests' \ +'upgrade:Run upgrade tests' \ +'build:Build all test dependencies' \ +'rust:Run unit-tests, accepts optional cargo test flags' \ +'l1-contracts:Run L1 contracts tests' \ +'prover:Run prover tests' \ +'wallet:Print test wallets information' \ +'loadtest:Run loadtest' \ + ) + _describe -t commands 'zkstack dev help test commands' commands "$@" +} +(( $+functions[_zkstack__dev__help__test__build_commands] )) || +_zkstack__dev__help__test__build_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev help test build commands' commands "$@" +} +(( $+functions[_zkstack__dev__help__test__fees_commands] )) || +_zkstack__dev__help__test__fees_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev help test fees commands' commands "$@" +} +(( $+functions[_zkstack__dev__help__test__integration_commands] )) || +_zkstack__dev__help__test__integration_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev help test integration commands' commands "$@" +} +(( $+functions[_zkstack__dev__help__test__l1-contracts_commands] )) || +_zkstack__dev__help__test__l1-contracts_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev help test l1-contracts commands' commands "$@" +} +(( $+functions[_zkstack__dev__help__test__loadtest_commands] )) || +_zkstack__dev__help__test__loadtest_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev help test loadtest commands' commands "$@" +} +(( $+functions[_zkstack__dev__help__test__prover_commands] )) || +_zkstack__dev__help__test__prover_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev help test prover commands' commands "$@" +} +(( $+functions[_zkstack__dev__help__test__recovery_commands] )) || +_zkstack__dev__help__test__recovery_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev help test recovery commands' commands "$@" +} +(( $+functions[_zkstack__dev__help__test__revert_commands] )) || +_zkstack__dev__help__test__revert_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev help test revert commands' commands "$@" +} +(( $+functions[_zkstack__dev__help__test__rust_commands] )) || +_zkstack__dev__help__test__rust_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev help test rust commands' commands "$@" +} +(( $+functions[_zkstack__dev__help__test__upgrade_commands] )) || +_zkstack__dev__help__test__upgrade_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev help test upgrade commands' commands "$@" +} +(( $+functions[_zkstack__dev__help__test__wallet_commands] )) || +_zkstack__dev__help__test__wallet_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev help test wallet commands' commands "$@" +} +(( $+functions[_zkstack__dev__lint_commands] )) || +_zkstack__dev__lint_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev lint commands' commands "$@" +} +(( $+functions[_zkstack__dev__prover_commands] )) || +_zkstack__dev__prover_commands() { + local commands; commands=( +'info:' \ +'insert-batch:' \ +'insert-version:' \ +'help:Print this message or the help of the given subcommand(s)' \ + ) + _describe -t commands 'zkstack dev prover commands' commands "$@" +} +(( $+functions[_zkstack__dev__prover__help_commands] )) || +_zkstack__dev__prover__help_commands() { + local commands; commands=( +'info:' \ +'insert-batch:' \ +'insert-version:' \ +'help:Print this message or the help of the given subcommand(s)' \ + ) + _describe -t commands 'zkstack dev prover help commands' commands "$@" +} +(( $+functions[_zkstack__dev__prover__help__help_commands] )) || +_zkstack__dev__prover__help__help_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev prover help help commands' commands "$@" +} +(( $+functions[_zkstack__dev__prover__help__info_commands] )) || +_zkstack__dev__prover__help__info_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev prover help info commands' commands "$@" +} +(( $+functions[_zkstack__dev__prover__help__insert-batch_commands] )) || +_zkstack__dev__prover__help__insert-batch_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev prover help insert-batch commands' commands "$@" +} +(( $+functions[_zkstack__dev__prover__help__insert-version_commands] )) || +_zkstack__dev__prover__help__insert-version_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev prover help insert-version commands' commands "$@" +} +(( $+functions[_zkstack__dev__prover__info_commands] )) || +_zkstack__dev__prover__info_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev prover info commands' commands "$@" +} +(( $+functions[_zkstack__dev__prover__insert-batch_commands] )) || +_zkstack__dev__prover__insert-batch_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev prover insert-batch commands' commands "$@" +} +(( $+functions[_zkstack__dev__prover__insert-version_commands] )) || +_zkstack__dev__prover__insert-version_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev prover insert-version commands' commands "$@" +} +(( $+functions[_zkstack__dev__send-transactions_commands] )) || +_zkstack__dev__send-transactions_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev send-transactions commands' commands "$@" +} +(( $+functions[_zkstack__dev__snapshot_commands] )) || +_zkstack__dev__snapshot_commands() { + local commands; commands=( +'create:' \ +'help:Print this message or the help of the given subcommand(s)' \ + ) + _describe -t commands 'zkstack dev snapshot commands' commands "$@" +} +(( $+functions[_zkstack__dev__snapshot__create_commands] )) || +_zkstack__dev__snapshot__create_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev snapshot create commands' commands "$@" +} +(( $+functions[_zkstack__dev__snapshot__help_commands] )) || +_zkstack__dev__snapshot__help_commands() { + local commands; commands=( +'create:' \ +'help:Print this message or the help of the given subcommand(s)' \ + ) + _describe -t commands 'zkstack dev snapshot help commands' commands "$@" +} +(( $+functions[_zkstack__dev__snapshot__help__create_commands] )) || +_zkstack__dev__snapshot__help__create_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev snapshot help create commands' commands "$@" +} +(( $+functions[_zkstack__dev__snapshot__help__help_commands] )) || +_zkstack__dev__snapshot__help__help_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev snapshot help help commands' commands "$@" +} +(( $+functions[_zkstack__dev__status_commands] )) || +_zkstack__dev__status_commands() { + local commands; commands=( +'ports:Show used ports' \ +'help:Print this message or the help of the given subcommand(s)' \ + ) + _describe -t commands 'zkstack dev status commands' commands "$@" +} +(( $+functions[_zkstack__dev__status__help_commands] )) || +_zkstack__dev__status__help_commands() { + local commands; commands=( +'ports:Show used ports' \ +'help:Print this message or the help of the given subcommand(s)' \ + ) + _describe -t commands 'zkstack dev status help commands' commands "$@" +} +(( $+functions[_zkstack__dev__status__help__help_commands] )) || +_zkstack__dev__status__help__help_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev status help help commands' commands "$@" +} +(( $+functions[_zkstack__dev__status__help__ports_commands] )) || +_zkstack__dev__status__help__ports_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev status help ports commands' commands "$@" +} +(( $+functions[_zkstack__dev__status__ports_commands] )) || +_zkstack__dev__status__ports_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev status ports commands' commands "$@" +} +(( $+functions[_zkstack__dev__test_commands] )) || +_zkstack__dev__test_commands() { + local commands; commands=( +'integration:Run integration tests' \ +'fees:Run fees test' \ +'revert:Run revert tests' \ +'recovery:Run recovery tests' \ +'upgrade:Run upgrade tests' \ +'build:Build all test dependencies' \ +'rust:Run unit-tests, accepts optional cargo test flags' \ +'l1-contracts:Run L1 contracts tests' \ +'prover:Run prover tests' \ +'wallet:Print test wallets information' \ +'loadtest:Run loadtest' \ +'help:Print this message or the help of the given subcommand(s)' \ + ) + _describe -t commands 'zkstack dev test commands' commands "$@" +} +(( $+functions[_zkstack__dev__test__build_commands] )) || +_zkstack__dev__test__build_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev test build commands' commands "$@" +} +(( $+functions[_zkstack__dev__test__fees_commands] )) || +_zkstack__dev__test__fees_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev test fees commands' commands "$@" +} +(( $+functions[_zkstack__dev__test__help_commands] )) || +_zkstack__dev__test__help_commands() { + local commands; commands=( +'integration:Run integration tests' \ +'fees:Run fees test' \ +'revert:Run revert tests' \ +'recovery:Run recovery tests' \ +'upgrade:Run upgrade tests' \ +'build:Build all test dependencies' \ +'rust:Run unit-tests, accepts optional cargo test flags' \ +'l1-contracts:Run L1 contracts tests' \ +'prover:Run prover tests' \ +'wallet:Print test wallets information' \ +'loadtest:Run loadtest' \ +'help:Print this message or the help of the given subcommand(s)' \ + ) + _describe -t commands 'zkstack dev test help commands' commands "$@" +} +(( $+functions[_zkstack__dev__test__help__build_commands] )) || +_zkstack__dev__test__help__build_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev test help build commands' commands "$@" +} +(( $+functions[_zkstack__dev__test__help__fees_commands] )) || +_zkstack__dev__test__help__fees_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev test help fees commands' commands "$@" +} +(( $+functions[_zkstack__dev__test__help__help_commands] )) || +_zkstack__dev__test__help__help_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev test help help commands' commands "$@" +} +(( $+functions[_zkstack__dev__test__help__integration_commands] )) || +_zkstack__dev__test__help__integration_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev test help integration commands' commands "$@" +} +(( $+functions[_zkstack__dev__test__help__l1-contracts_commands] )) || +_zkstack__dev__test__help__l1-contracts_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev test help l1-contracts commands' commands "$@" +} +(( $+functions[_zkstack__dev__test__help__loadtest_commands] )) || +_zkstack__dev__test__help__loadtest_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev test help loadtest commands' commands "$@" +} +(( $+functions[_zkstack__dev__test__help__prover_commands] )) || +_zkstack__dev__test__help__prover_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev test help prover commands' commands "$@" +} +(( $+functions[_zkstack__dev__test__help__recovery_commands] )) || +_zkstack__dev__test__help__recovery_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev test help recovery commands' commands "$@" +} +(( $+functions[_zkstack__dev__test__help__revert_commands] )) || +_zkstack__dev__test__help__revert_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev test help revert commands' commands "$@" +} +(( $+functions[_zkstack__dev__test__help__rust_commands] )) || +_zkstack__dev__test__help__rust_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev test help rust commands' commands "$@" +} +(( $+functions[_zkstack__dev__test__help__upgrade_commands] )) || +_zkstack__dev__test__help__upgrade_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev test help upgrade commands' commands "$@" +} +(( $+functions[_zkstack__dev__test__help__wallet_commands] )) || +_zkstack__dev__test__help__wallet_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev test help wallet commands' commands "$@" +} +(( $+functions[_zkstack__dev__test__integration_commands] )) || +_zkstack__dev__test__integration_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev test integration commands' commands "$@" +} +(( $+functions[_zkstack__dev__test__l1-contracts_commands] )) || +_zkstack__dev__test__l1-contracts_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev test l1-contracts commands' commands "$@" +} +(( $+functions[_zkstack__dev__test__loadtest_commands] )) || +_zkstack__dev__test__loadtest_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev test loadtest commands' commands "$@" +} +(( $+functions[_zkstack__dev__test__prover_commands] )) || +_zkstack__dev__test__prover_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev test prover commands' commands "$@" +} +(( $+functions[_zkstack__dev__test__recovery_commands] )) || +_zkstack__dev__test__recovery_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev test recovery commands' commands "$@" +} +(( $+functions[_zkstack__dev__test__revert_commands] )) || +_zkstack__dev__test__revert_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev test revert commands' commands "$@" +} +(( $+functions[_zkstack__dev__test__rust_commands] )) || +_zkstack__dev__test__rust_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev test rust commands' commands "$@" +} +(( $+functions[_zkstack__dev__test__upgrade_commands] )) || +_zkstack__dev__test__upgrade_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev test upgrade commands' commands "$@" +} +(( $+functions[_zkstack__dev__test__wallet_commands] )) || +_zkstack__dev__test__wallet_commands() { + local commands; commands=() + _describe -t commands 'zkstack dev test wallet commands' commands "$@" +} +(( $+functions[_zkstack__ecosystem_commands] )) || +_zkstack__ecosystem_commands() { + local commands; commands=( +'create:Create a new ecosystem and chain, setting necessary configurations for later initialization' \ +'build-transactions:Create transactions to build ecosystem contracts' \ +'init:Initialize ecosystem and chain, deploying necessary contracts and performing on-chain operations' \ +'change-default-chain:Change the default chain' \ +'setup-observability:Setup observability for the ecosystem, downloading Grafana dashboards from the era-observability repo' \ +'help:Print this message or the help of the given subcommand(s)' \ + ) + _describe -t commands 'zkstack ecosystem commands' commands "$@" +} +(( $+functions[_zkstack__ecosystem__build-transactions_commands] )) || +_zkstack__ecosystem__build-transactions_commands() { + local commands; commands=() + _describe -t commands 'zkstack ecosystem build-transactions commands' commands "$@" +} +(( $+functions[_zkstack__ecosystem__change-default-chain_commands] )) || +_zkstack__ecosystem__change-default-chain_commands() { + local commands; commands=() + _describe -t commands 'zkstack ecosystem change-default-chain commands' commands "$@" +} +(( $+functions[_zkstack__ecosystem__create_commands] )) || +_zkstack__ecosystem__create_commands() { + local commands; commands=() + _describe -t commands 'zkstack ecosystem create commands' commands "$@" +} +(( $+functions[_zkstack__ecosystem__help_commands] )) || +_zkstack__ecosystem__help_commands() { + local commands; commands=( +'create:Create a new ecosystem and chain, setting necessary configurations for later initialization' \ +'build-transactions:Create transactions to build ecosystem contracts' \ +'init:Initialize ecosystem and chain, deploying necessary contracts and performing on-chain operations' \ +'change-default-chain:Change the default chain' \ +'setup-observability:Setup observability for the ecosystem, downloading Grafana dashboards from the era-observability repo' \ +'help:Print this message or the help of the given subcommand(s)' \ + ) + _describe -t commands 'zkstack ecosystem help commands' commands "$@" +} +(( $+functions[_zkstack__ecosystem__help__build-transactions_commands] )) || +_zkstack__ecosystem__help__build-transactions_commands() { + local commands; commands=() + _describe -t commands 'zkstack ecosystem help build-transactions commands' commands "$@" +} +(( $+functions[_zkstack__ecosystem__help__change-default-chain_commands] )) || +_zkstack__ecosystem__help__change-default-chain_commands() { + local commands; commands=() + _describe -t commands 'zkstack ecosystem help change-default-chain commands' commands "$@" +} +(( $+functions[_zkstack__ecosystem__help__create_commands] )) || +_zkstack__ecosystem__help__create_commands() { + local commands; commands=() + _describe -t commands 'zkstack ecosystem help create commands' commands "$@" +} +(( $+functions[_zkstack__ecosystem__help__help_commands] )) || +_zkstack__ecosystem__help__help_commands() { + local commands; commands=() + _describe -t commands 'zkstack ecosystem help help commands' commands "$@" +} +(( $+functions[_zkstack__ecosystem__help__init_commands] )) || +_zkstack__ecosystem__help__init_commands() { + local commands; commands=() + _describe -t commands 'zkstack ecosystem help init commands' commands "$@" +} +(( $+functions[_zkstack__ecosystem__help__setup-observability_commands] )) || +_zkstack__ecosystem__help__setup-observability_commands() { + local commands; commands=() + _describe -t commands 'zkstack ecosystem help setup-observability commands' commands "$@" +} +(( $+functions[_zkstack__ecosystem__init_commands] )) || +_zkstack__ecosystem__init_commands() { + local commands; commands=() + _describe -t commands 'zkstack ecosystem init commands' commands "$@" +} +(( $+functions[_zkstack__ecosystem__setup-observability_commands] )) || +_zkstack__ecosystem__setup-observability_commands() { + local commands; commands=() + _describe -t commands 'zkstack ecosystem setup-observability commands' commands "$@" +} +(( $+functions[_zkstack__explorer_commands] )) || +_zkstack__explorer_commands() { + local commands; commands=( +'init:Initialize explorer (create database to store explorer data and generate docker compose file with explorer services). Runs for all chains, unless --chain is passed' \ +'run-backend:Start explorer backend services (api, data_fetcher, worker) for a given chain. Uses default chain, unless --chain is passed' \ +'run:Run explorer app' \ +'help:Print this message or the help of the given subcommand(s)' \ + ) + _describe -t commands 'zkstack explorer commands' commands "$@" +} +(( $+functions[_zkstack__explorer__help_commands] )) || +_zkstack__explorer__help_commands() { + local commands; commands=( +'init:Initialize explorer (create database to store explorer data and generate docker compose file with explorer services). Runs for all chains, unless --chain is passed' \ +'run-backend:Start explorer backend services (api, data_fetcher, worker) for a given chain. Uses default chain, unless --chain is passed' \ +'run:Run explorer app' \ +'help:Print this message or the help of the given subcommand(s)' \ + ) + _describe -t commands 'zkstack explorer help commands' commands "$@" +} +(( $+functions[_zkstack__explorer__help__help_commands] )) || +_zkstack__explorer__help__help_commands() { + local commands; commands=() + _describe -t commands 'zkstack explorer help help commands' commands "$@" +} +(( $+functions[_zkstack__explorer__help__init_commands] )) || +_zkstack__explorer__help__init_commands() { + local commands; commands=() + _describe -t commands 'zkstack explorer help init commands' commands "$@" +} +(( $+functions[_zkstack__explorer__help__run_commands] )) || +_zkstack__explorer__help__run_commands() { + local commands; commands=() + _describe -t commands 'zkstack explorer help run commands' commands "$@" +} +(( $+functions[_zkstack__explorer__help__run-backend_commands] )) || +_zkstack__explorer__help__run-backend_commands() { + local commands; commands=() + _describe -t commands 'zkstack explorer help run-backend commands' commands "$@" +} +(( $+functions[_zkstack__explorer__init_commands] )) || +_zkstack__explorer__init_commands() { + local commands; commands=() + _describe -t commands 'zkstack explorer init commands' commands "$@" +} +(( $+functions[_zkstack__explorer__run_commands] )) || +_zkstack__explorer__run_commands() { + local commands; commands=() + _describe -t commands 'zkstack explorer run commands' commands "$@" +} +(( $+functions[_zkstack__explorer__run-backend_commands] )) || +_zkstack__explorer__run-backend_commands() { + local commands; commands=() + _describe -t commands 'zkstack explorer run-backend commands' commands "$@" +} +(( $+functions[_zkstack__external-node_commands] )) || +_zkstack__external-node_commands() { + local commands; commands=( +'configs:Prepare configs for EN' \ +'init:Init databases' \ +'run:Run external node' \ +'help:Print this message or the help of the given subcommand(s)' \ + ) + _describe -t commands 'zkstack external-node commands' commands "$@" +} +(( $+functions[_zkstack__external-node__configs_commands] )) || +_zkstack__external-node__configs_commands() { + local commands; commands=() + _describe -t commands 'zkstack external-node configs commands' commands "$@" +} +(( $+functions[_zkstack__external-node__help_commands] )) || +_zkstack__external-node__help_commands() { + local commands; commands=( +'configs:Prepare configs for EN' \ +'init:Init databases' \ +'run:Run external node' \ +'help:Print this message or the help of the given subcommand(s)' \ + ) + _describe -t commands 'zkstack external-node help commands' commands "$@" +} +(( $+functions[_zkstack__external-node__help__configs_commands] )) || +_zkstack__external-node__help__configs_commands() { + local commands; commands=() + _describe -t commands 'zkstack external-node help configs commands' commands "$@" +} +(( $+functions[_zkstack__external-node__help__help_commands] )) || +_zkstack__external-node__help__help_commands() { + local commands; commands=() + _describe -t commands 'zkstack external-node help help commands' commands "$@" +} +(( $+functions[_zkstack__external-node__help__init_commands] )) || +_zkstack__external-node__help__init_commands() { + local commands; commands=() + _describe -t commands 'zkstack external-node help init commands' commands "$@" +} +(( $+functions[_zkstack__external-node__help__run_commands] )) || +_zkstack__external-node__help__run_commands() { + local commands; commands=() + _describe -t commands 'zkstack external-node help run commands' commands "$@" +} +(( $+functions[_zkstack__external-node__init_commands] )) || +_zkstack__external-node__init_commands() { + local commands; commands=() + _describe -t commands 'zkstack external-node init commands' commands "$@" +} +(( $+functions[_zkstack__external-node__run_commands] )) || +_zkstack__external-node__run_commands() { + local commands; commands=() + _describe -t commands 'zkstack external-node run commands' commands "$@" +} +(( $+functions[_zkstack__help_commands] )) || +_zkstack__help_commands() { + local commands; commands=( +'autocomplete:Create shell autocompletion files' \ +'ecosystem:Ecosystem related commands' \ +'chain:Chain related commands' \ +'dev:Supervisor related commands' \ +'prover:Prover related commands' \ +'server:Run server' \ +'external-node:External Node related commands' \ +'containers:Run containers for local development' \ +'contract-verifier:Run contract verifier' \ +'portal:Run dapp-portal' \ +'explorer:Run block-explorer' \ +'consensus:Consensus utilities' \ +'update:Update ZKsync' \ +'markdown:Print markdown help' \ +'help:Print this message or the help of the given subcommand(s)' \ + ) + _describe -t commands 'zkstack help commands' commands "$@" +} +(( $+functions[_zkstack__help__autocomplete_commands] )) || +_zkstack__help__autocomplete_commands() { + local commands; commands=() + _describe -t commands 'zkstack help autocomplete commands' commands "$@" +} +(( $+functions[_zkstack__help__chain_commands] )) || +_zkstack__help__chain_commands() { + local commands; commands=( +'create:Create a new chain, setting the necessary configurations for later initialization' \ +'build-transactions:Create unsigned transactions for chain deployment' \ +'init:Initialize chain, deploying necessary contracts and performing on-chain operations' \ +'genesis:Run server genesis' \ +'register-chain:Register a new chain on L1 (executed by L1 governor). This command deploys and configures Governance, ChainAdmin, and DiamondProxy contracts, registers chain with BridgeHub and sets pending admin for DiamondProxy. Note\: After completion, L2 governor can accept ownership by running \`accept-chain-ownership\`' \ +'deploy-l2-contracts:Deploy all L2 contracts (executed by L1 governor)' \ +'accept-chain-ownership:Accept ownership of L2 chain (executed by L2 governor). This command should be run after \`register-chain\` to accept ownership of newly created DiamondProxy contract' \ +'initialize-bridges:Initialize bridges on L2' \ +'deploy-consensus-registry:Deploy L2 consensus registry' \ +'deploy-multicall3:Deploy L2 multicall3' \ +'deploy-upgrader:Deploy Default Upgrader' \ +'deploy-paymaster:Deploy paymaster smart contract' \ +'update-token-multiplier-setter:Update Token Multiplier Setter address on L1' \ + ) + _describe -t commands 'zkstack help chain commands' commands "$@" +} +(( $+functions[_zkstack__help__chain__accept-chain-ownership_commands] )) || +_zkstack__help__chain__accept-chain-ownership_commands() { + local commands; commands=() + _describe -t commands 'zkstack help chain accept-chain-ownership commands' commands "$@" +} +(( $+functions[_zkstack__help__chain__build-transactions_commands] )) || +_zkstack__help__chain__build-transactions_commands() { + local commands; commands=() + _describe -t commands 'zkstack help chain build-transactions commands' commands "$@" +} +(( $+functions[_zkstack__help__chain__create_commands] )) || +_zkstack__help__chain__create_commands() { + local commands; commands=() + _describe -t commands 'zkstack help chain create commands' commands "$@" +} +(( $+functions[_zkstack__help__chain__deploy-consensus-registry_commands] )) || +_zkstack__help__chain__deploy-consensus-registry_commands() { + local commands; commands=() + _describe -t commands 'zkstack help chain deploy-consensus-registry commands' commands "$@" +} +(( $+functions[_zkstack__help__chain__deploy-l2-contracts_commands] )) || +_zkstack__help__chain__deploy-l2-contracts_commands() { + local commands; commands=() + _describe -t commands 'zkstack help chain deploy-l2-contracts commands' commands "$@" +} +(( $+functions[_zkstack__help__chain__deploy-multicall3_commands] )) || +_zkstack__help__chain__deploy-multicall3_commands() { + local commands; commands=() + _describe -t commands 'zkstack help chain deploy-multicall3 commands' commands "$@" +} +(( $+functions[_zkstack__help__chain__deploy-paymaster_commands] )) || +_zkstack__help__chain__deploy-paymaster_commands() { + local commands; commands=() + _describe -t commands 'zkstack help chain deploy-paymaster commands' commands "$@" +} +(( $+functions[_zkstack__help__chain__deploy-upgrader_commands] )) || +_zkstack__help__chain__deploy-upgrader_commands() { + local commands; commands=() + _describe -t commands 'zkstack help chain deploy-upgrader commands' commands "$@" +} +(( $+functions[_zkstack__help__chain__genesis_commands] )) || +_zkstack__help__chain__genesis_commands() { + local commands; commands=( +'init-database:Initialize databases' \ +'server:Runs server genesis' \ + ) + _describe -t commands 'zkstack help chain genesis commands' commands "$@" +} +(( $+functions[_zkstack__help__chain__genesis__init-database_commands] )) || +_zkstack__help__chain__genesis__init-database_commands() { + local commands; commands=() + _describe -t commands 'zkstack help chain genesis init-database commands' commands "$@" +} +(( $+functions[_zkstack__help__chain__genesis__server_commands] )) || +_zkstack__help__chain__genesis__server_commands() { + local commands; commands=() + _describe -t commands 'zkstack help chain genesis server commands' commands "$@" +} +(( $+functions[_zkstack__help__chain__init_commands] )) || +_zkstack__help__chain__init_commands() { + local commands; commands=( +'configs:Initialize chain configs' \ + ) + _describe -t commands 'zkstack help chain init commands' commands "$@" +} +(( $+functions[_zkstack__help__chain__init__configs_commands] )) || +_zkstack__help__chain__init__configs_commands() { + local commands; commands=() + _describe -t commands 'zkstack help chain init configs commands' commands "$@" +} +(( $+functions[_zkstack__help__chain__initialize-bridges_commands] )) || +_zkstack__help__chain__initialize-bridges_commands() { + local commands; commands=() + _describe -t commands 'zkstack help chain initialize-bridges commands' commands "$@" +} +(( $+functions[_zkstack__help__chain__register-chain_commands] )) || +_zkstack__help__chain__register-chain_commands() { + local commands; commands=() + _describe -t commands 'zkstack help chain register-chain commands' commands "$@" +} +(( $+functions[_zkstack__help__chain__update-token-multiplier-setter_commands] )) || +_zkstack__help__chain__update-token-multiplier-setter_commands() { + local commands; commands=() + _describe -t commands 'zkstack help chain update-token-multiplier-setter commands' commands "$@" +} +(( $+functions[_zkstack__help__consensus_commands] )) || +_zkstack__help__consensus_commands() { + local commands; commands=( +'set-attester-committee:Sets the attester committee in the consensus registry contract to \`consensus.genesis_spec.attesters\` in general.yaml' \ +'get-attester-committee:Fetches the attester committee from the consensus registry contract' \ + ) + _describe -t commands 'zkstack help consensus commands' commands "$@" +} +(( $+functions[_zkstack__help__consensus__get-attester-committee_commands] )) || +_zkstack__help__consensus__get-attester-committee_commands() { + local commands; commands=() + _describe -t commands 'zkstack help consensus get-attester-committee commands' commands "$@" +} +(( $+functions[_zkstack__help__consensus__set-attester-committee_commands] )) || +_zkstack__help__consensus__set-attester-committee_commands() { + local commands; commands=() + _describe -t commands 'zkstack help consensus set-attester-committee commands' commands "$@" +} +(( $+functions[_zkstack__help__containers_commands] )) || +_zkstack__help__containers_commands() { + local commands; commands=() + _describe -t commands 'zkstack help containers commands' commands "$@" +} +(( $+functions[_zkstack__help__contract-verifier_commands] )) || +_zkstack__help__contract-verifier_commands() { + local commands; commands=( +'run:Run contract verifier' \ +'init:Download required binaries for contract verifier' \ + ) + _describe -t commands 'zkstack help contract-verifier commands' commands "$@" +} +(( $+functions[_zkstack__help__contract-verifier__init_commands] )) || +_zkstack__help__contract-verifier__init_commands() { + local commands; commands=() + _describe -t commands 'zkstack help contract-verifier init commands' commands "$@" +} +(( $+functions[_zkstack__help__contract-verifier__run_commands] )) || +_zkstack__help__contract-verifier__run_commands() { + local commands; commands=() + _describe -t commands 'zkstack help contract-verifier run commands' commands "$@" +} +(( $+functions[_zkstack__help__dev_commands] )) || +_zkstack__help__dev_commands() { + local commands; commands=( +'database:Database related commands' \ +'test:Run tests' \ +'clean:Clean artifacts' \ +'snapshot:Snapshots creator' \ +'lint:Lint code' \ +'fmt:Format code' \ +'prover:Protocol version used by provers' \ +'contracts:Build contracts' \ +'config-writer:Overwrite general config' \ +'send-transactions:Send transactions from file' \ +'status:Get status of the server' \ +'generate-genesis:Generate new genesis file based on current contracts' \ + ) + _describe -t commands 'zkstack help dev commands' commands "$@" +} +(( $+functions[_zkstack__help__dev__clean_commands] )) || +_zkstack__help__dev__clean_commands() { + local commands; commands=( +'all:Remove containers and contracts cache' \ +'containers:Remove containers and docker volumes' \ +'contracts-cache:Remove contracts caches' \ + ) + _describe -t commands 'zkstack help dev clean commands' commands "$@" +} +(( $+functions[_zkstack__help__dev__clean__all_commands] )) || +_zkstack__help__dev__clean__all_commands() { + local commands; commands=() + _describe -t commands 'zkstack help dev clean all commands' commands "$@" +} +(( $+functions[_zkstack__help__dev__clean__containers_commands] )) || +_zkstack__help__dev__clean__containers_commands() { + local commands; commands=() + _describe -t commands 'zkstack help dev clean containers commands' commands "$@" +} +(( $+functions[_zkstack__help__dev__clean__contracts-cache_commands] )) || +_zkstack__help__dev__clean__contracts-cache_commands() { + local commands; commands=() + _describe -t commands 'zkstack help dev clean contracts-cache commands' commands "$@" +} +(( $+functions[_zkstack__help__dev__config-writer_commands] )) || +_zkstack__help__dev__config-writer_commands() { + local commands; commands=() + _describe -t commands 'zkstack help dev config-writer commands' commands "$@" +} +(( $+functions[_zkstack__help__dev__contracts_commands] )) || +_zkstack__help__dev__contracts_commands() { + local commands; commands=() + _describe -t commands 'zkstack help dev contracts commands' commands "$@" +} +(( $+functions[_zkstack__help__dev__database_commands] )) || +_zkstack__help__dev__database_commands() { + local commands; commands=( +'check-sqlx-data:Check sqlx-data.json is up to date. If no databases are selected, all databases will be checked.' \ +'drop:Drop databases. If no databases are selected, all databases will be dropped.' \ +'migrate:Migrate databases. If no databases are selected, all databases will be migrated.' \ +'new-migration:Create new migration' \ +'prepare:Prepare sqlx-data.json. If no databases are selected, all databases will be prepared.' \ +'reset:Reset databases. If no databases are selected, all databases will be reset.' \ +'setup:Setup databases. If no databases are selected, all databases will be setup.' \ + ) + _describe -t commands 'zkstack help dev database commands' commands "$@" +} +(( $+functions[_zkstack__help__dev__database__check-sqlx-data_commands] )) || +_zkstack__help__dev__database__check-sqlx-data_commands() { + local commands; commands=() + _describe -t commands 'zkstack help dev database check-sqlx-data commands' commands "$@" +} +(( $+functions[_zkstack__help__dev__database__drop_commands] )) || +_zkstack__help__dev__database__drop_commands() { + local commands; commands=() + _describe -t commands 'zkstack help dev database drop commands' commands "$@" +} +(( $+functions[_zkstack__help__dev__database__migrate_commands] )) || +_zkstack__help__dev__database__migrate_commands() { + local commands; commands=() + _describe -t commands 'zkstack help dev database migrate commands' commands "$@" +} +(( $+functions[_zkstack__help__dev__database__new-migration_commands] )) || +_zkstack__help__dev__database__new-migration_commands() { + local commands; commands=() + _describe -t commands 'zkstack help dev database new-migration commands' commands "$@" +} +(( $+functions[_zkstack__help__dev__database__prepare_commands] )) || +_zkstack__help__dev__database__prepare_commands() { + local commands; commands=() + _describe -t commands 'zkstack help dev database prepare commands' commands "$@" +} +(( $+functions[_zkstack__help__dev__database__reset_commands] )) || +_zkstack__help__dev__database__reset_commands() { + local commands; commands=() + _describe -t commands 'zkstack help dev database reset commands' commands "$@" +} +(( $+functions[_zkstack__help__dev__database__setup_commands] )) || +_zkstack__help__dev__database__setup_commands() { + local commands; commands=() + _describe -t commands 'zkstack help dev database setup commands' commands "$@" +} +(( $+functions[_zkstack__help__dev__fmt_commands] )) || +_zkstack__help__dev__fmt_commands() { + local commands; commands=( +'rustfmt:' \ +'contract:' \ +'prettier:' \ + ) + _describe -t commands 'zkstack help dev fmt commands' commands "$@" +} +(( $+functions[_zkstack__help__dev__fmt__contract_commands] )) || +_zkstack__help__dev__fmt__contract_commands() { + local commands; commands=() + _describe -t commands 'zkstack help dev fmt contract commands' commands "$@" +} +(( $+functions[_zkstack__help__dev__fmt__prettier_commands] )) || +_zkstack__help__dev__fmt__prettier_commands() { + local commands; commands=() + _describe -t commands 'zkstack help dev fmt prettier commands' commands "$@" +} +(( $+functions[_zkstack__help__dev__fmt__rustfmt_commands] )) || +_zkstack__help__dev__fmt__rustfmt_commands() { + local commands; commands=() + _describe -t commands 'zkstack help dev fmt rustfmt commands' commands "$@" +} +(( $+functions[_zkstack__help__dev__generate-genesis_commands] )) || +_zkstack__help__dev__generate-genesis_commands() { + local commands; commands=() + _describe -t commands 'zkstack help dev generate-genesis commands' commands "$@" +} +(( $+functions[_zkstack__help__dev__lint_commands] )) || +_zkstack__help__dev__lint_commands() { + local commands; commands=() + _describe -t commands 'zkstack help dev lint commands' commands "$@" +} +(( $+functions[_zkstack__help__dev__prover_commands] )) || +_zkstack__help__dev__prover_commands() { + local commands; commands=( +'info:' \ +'insert-batch:' \ +'insert-version:' \ + ) + _describe -t commands 'zkstack help dev prover commands' commands "$@" +} +(( $+functions[_zkstack__help__dev__prover__info_commands] )) || +_zkstack__help__dev__prover__info_commands() { + local commands; commands=() + _describe -t commands 'zkstack help dev prover info commands' commands "$@" +} +(( $+functions[_zkstack__help__dev__prover__insert-batch_commands] )) || +_zkstack__help__dev__prover__insert-batch_commands() { + local commands; commands=() + _describe -t commands 'zkstack help dev prover insert-batch commands' commands "$@" +} +(( $+functions[_zkstack__help__dev__prover__insert-version_commands] )) || +_zkstack__help__dev__prover__insert-version_commands() { + local commands; commands=() + _describe -t commands 'zkstack help dev prover insert-version commands' commands "$@" +} +(( $+functions[_zkstack__help__dev__send-transactions_commands] )) || +_zkstack__help__dev__send-transactions_commands() { + local commands; commands=() + _describe -t commands 'zkstack help dev send-transactions commands' commands "$@" +} +(( $+functions[_zkstack__help__dev__snapshot_commands] )) || +_zkstack__help__dev__snapshot_commands() { + local commands; commands=( +'create:' \ + ) + _describe -t commands 'zkstack help dev snapshot commands' commands "$@" +} +(( $+functions[_zkstack__help__dev__snapshot__create_commands] )) || +_zkstack__help__dev__snapshot__create_commands() { + local commands; commands=() + _describe -t commands 'zkstack help dev snapshot create commands' commands "$@" +} +(( $+functions[_zkstack__help__dev__status_commands] )) || +_zkstack__help__dev__status_commands() { + local commands; commands=( +'ports:Show used ports' \ + ) + _describe -t commands 'zkstack help dev status commands' commands "$@" +} +(( $+functions[_zkstack__help__dev__status__ports_commands] )) || +_zkstack__help__dev__status__ports_commands() { + local commands; commands=() + _describe -t commands 'zkstack help dev status ports commands' commands "$@" +} +(( $+functions[_zkstack__help__dev__test_commands] )) || +_zkstack__help__dev__test_commands() { + local commands; commands=( +'integration:Run integration tests' \ +'fees:Run fees test' \ +'revert:Run revert tests' \ +'recovery:Run recovery tests' \ +'upgrade:Run upgrade tests' \ +'build:Build all test dependencies' \ +'rust:Run unit-tests, accepts optional cargo test flags' \ +'l1-contracts:Run L1 contracts tests' \ +'prover:Run prover tests' \ +'wallet:Print test wallets information' \ +'loadtest:Run loadtest' \ + ) + _describe -t commands 'zkstack help dev test commands' commands "$@" +} +(( $+functions[_zkstack__help__dev__test__build_commands] )) || +_zkstack__help__dev__test__build_commands() { + local commands; commands=() + _describe -t commands 'zkstack help dev test build commands' commands "$@" +} +(( $+functions[_zkstack__help__dev__test__fees_commands] )) || +_zkstack__help__dev__test__fees_commands() { + local commands; commands=() + _describe -t commands 'zkstack help dev test fees commands' commands "$@" +} +(( $+functions[_zkstack__help__dev__test__integration_commands] )) || +_zkstack__help__dev__test__integration_commands() { + local commands; commands=() + _describe -t commands 'zkstack help dev test integration commands' commands "$@" +} +(( $+functions[_zkstack__help__dev__test__l1-contracts_commands] )) || +_zkstack__help__dev__test__l1-contracts_commands() { + local commands; commands=() + _describe -t commands 'zkstack help dev test l1-contracts commands' commands "$@" +} +(( $+functions[_zkstack__help__dev__test__loadtest_commands] )) || +_zkstack__help__dev__test__loadtest_commands() { + local commands; commands=() + _describe -t commands 'zkstack help dev test loadtest commands' commands "$@" +} +(( $+functions[_zkstack__help__dev__test__prover_commands] )) || +_zkstack__help__dev__test__prover_commands() { + local commands; commands=() + _describe -t commands 'zkstack help dev test prover commands' commands "$@" +} +(( $+functions[_zkstack__help__dev__test__recovery_commands] )) || +_zkstack__help__dev__test__recovery_commands() { + local commands; commands=() + _describe -t commands 'zkstack help dev test recovery commands' commands "$@" +} +(( $+functions[_zkstack__help__dev__test__revert_commands] )) || +_zkstack__help__dev__test__revert_commands() { + local commands; commands=() + _describe -t commands 'zkstack help dev test revert commands' commands "$@" +} +(( $+functions[_zkstack__help__dev__test__rust_commands] )) || +_zkstack__help__dev__test__rust_commands() { + local commands; commands=() + _describe -t commands 'zkstack help dev test rust commands' commands "$@" +} +(( $+functions[_zkstack__help__dev__test__upgrade_commands] )) || +_zkstack__help__dev__test__upgrade_commands() { + local commands; commands=() + _describe -t commands 'zkstack help dev test upgrade commands' commands "$@" +} +(( $+functions[_zkstack__help__dev__test__wallet_commands] )) || +_zkstack__help__dev__test__wallet_commands() { + local commands; commands=() + _describe -t commands 'zkstack help dev test wallet commands' commands "$@" +} +(( $+functions[_zkstack__help__ecosystem_commands] )) || +_zkstack__help__ecosystem_commands() { + local commands; commands=( +'create:Create a new ecosystem and chain, setting necessary configurations for later initialization' \ +'build-transactions:Create transactions to build ecosystem contracts' \ +'init:Initialize ecosystem and chain, deploying necessary contracts and performing on-chain operations' \ +'change-default-chain:Change the default chain' \ +'setup-observability:Setup observability for the ecosystem, downloading Grafana dashboards from the era-observability repo' \ + ) + _describe -t commands 'zkstack help ecosystem commands' commands "$@" +} +(( $+functions[_zkstack__help__ecosystem__build-transactions_commands] )) || +_zkstack__help__ecosystem__build-transactions_commands() { + local commands; commands=() + _describe -t commands 'zkstack help ecosystem build-transactions commands' commands "$@" +} +(( $+functions[_zkstack__help__ecosystem__change-default-chain_commands] )) || +_zkstack__help__ecosystem__change-default-chain_commands() { + local commands; commands=() + _describe -t commands 'zkstack help ecosystem change-default-chain commands' commands "$@" +} +(( $+functions[_zkstack__help__ecosystem__create_commands] )) || +_zkstack__help__ecosystem__create_commands() { + local commands; commands=() + _describe -t commands 'zkstack help ecosystem create commands' commands "$@" +} +(( $+functions[_zkstack__help__ecosystem__init_commands] )) || +_zkstack__help__ecosystem__init_commands() { + local commands; commands=() + _describe -t commands 'zkstack help ecosystem init commands' commands "$@" +} +(( $+functions[_zkstack__help__ecosystem__setup-observability_commands] )) || +_zkstack__help__ecosystem__setup-observability_commands() { + local commands; commands=() + _describe -t commands 'zkstack help ecosystem setup-observability commands' commands "$@" +} +(( $+functions[_zkstack__help__explorer_commands] )) || +_zkstack__help__explorer_commands() { + local commands; commands=( +'init:Initialize explorer (create database to store explorer data and generate docker compose file with explorer services). Runs for all chains, unless --chain is passed' \ +'run-backend:Start explorer backend services (api, data_fetcher, worker) for a given chain. Uses default chain, unless --chain is passed' \ +'run:Run explorer app' \ + ) + _describe -t commands 'zkstack help explorer commands' commands "$@" +} +(( $+functions[_zkstack__help__explorer__init_commands] )) || +_zkstack__help__explorer__init_commands() { + local commands; commands=() + _describe -t commands 'zkstack help explorer init commands' commands "$@" +} +(( $+functions[_zkstack__help__explorer__run_commands] )) || +_zkstack__help__explorer__run_commands() { + local commands; commands=() + _describe -t commands 'zkstack help explorer run commands' commands "$@" +} +(( $+functions[_zkstack__help__explorer__run-backend_commands] )) || +_zkstack__help__explorer__run-backend_commands() { + local commands; commands=() + _describe -t commands 'zkstack help explorer run-backend commands' commands "$@" +} +(( $+functions[_zkstack__help__external-node_commands] )) || +_zkstack__help__external-node_commands() { + local commands; commands=( +'configs:Prepare configs for EN' \ +'init:Init databases' \ +'run:Run external node' \ + ) + _describe -t commands 'zkstack help external-node commands' commands "$@" +} +(( $+functions[_zkstack__help__external-node__configs_commands] )) || +_zkstack__help__external-node__configs_commands() { + local commands; commands=() + _describe -t commands 'zkstack help external-node configs commands' commands "$@" +} +(( $+functions[_zkstack__help__external-node__init_commands] )) || +_zkstack__help__external-node__init_commands() { + local commands; commands=() + _describe -t commands 'zkstack help external-node init commands' commands "$@" +} +(( $+functions[_zkstack__help__external-node__run_commands] )) || +_zkstack__help__external-node__run_commands() { + local commands; commands=() + _describe -t commands 'zkstack help external-node run commands' commands "$@" +} +(( $+functions[_zkstack__help__help_commands] )) || +_zkstack__help__help_commands() { + local commands; commands=() + _describe -t commands 'zkstack help help commands' commands "$@" +} +(( $+functions[_zkstack__help__markdown_commands] )) || +_zkstack__help__markdown_commands() { + local commands; commands=() + _describe -t commands 'zkstack help markdown commands' commands "$@" +} +(( $+functions[_zkstack__help__portal_commands] )) || +_zkstack__help__portal_commands() { + local commands; commands=() + _describe -t commands 'zkstack help portal commands' commands "$@" +} +(( $+functions[_zkstack__help__prover_commands] )) || +_zkstack__help__prover_commands() { + local commands; commands=( +'init:Initialize prover' \ +'setup-keys:Generate setup keys' \ +'run:Run prover' \ +'init-bellman-cuda:Initialize bellman-cuda' \ +'compressor-keys:Download compressor keys' \ + ) + _describe -t commands 'zkstack help prover commands' commands "$@" +} +(( $+functions[_zkstack__help__prover__compressor-keys_commands] )) || +_zkstack__help__prover__compressor-keys_commands() { + local commands; commands=() + _describe -t commands 'zkstack help prover compressor-keys commands' commands "$@" +} +(( $+functions[_zkstack__help__prover__init_commands] )) || +_zkstack__help__prover__init_commands() { + local commands; commands=() + _describe -t commands 'zkstack help prover init commands' commands "$@" +} +(( $+functions[_zkstack__help__prover__init-bellman-cuda_commands] )) || +_zkstack__help__prover__init-bellman-cuda_commands() { + local commands; commands=() + _describe -t commands 'zkstack help prover init-bellman-cuda commands' commands "$@" +} +(( $+functions[_zkstack__help__prover__run_commands] )) || +_zkstack__help__prover__run_commands() { + local commands; commands=() + _describe -t commands 'zkstack help prover run commands' commands "$@" +} +(( $+functions[_zkstack__help__prover__setup-keys_commands] )) || +_zkstack__help__prover__setup-keys_commands() { + local commands; commands=() + _describe -t commands 'zkstack help prover setup-keys commands' commands "$@" +} +(( $+functions[_zkstack__help__server_commands] )) || +_zkstack__help__server_commands() { + local commands; commands=() + _describe -t commands 'zkstack help server commands' commands "$@" +} +(( $+functions[_zkstack__help__update_commands] )) || +_zkstack__help__update_commands() { + local commands; commands=() + _describe -t commands 'zkstack help update commands' commands "$@" +} +(( $+functions[_zkstack__markdown_commands] )) || +_zkstack__markdown_commands() { + local commands; commands=() + _describe -t commands 'zkstack markdown commands' commands "$@" +} +(( $+functions[_zkstack__portal_commands] )) || +_zkstack__portal_commands() { + local commands; commands=() + _describe -t commands 'zkstack portal commands' commands "$@" +} +(( $+functions[_zkstack__prover_commands] )) || +_zkstack__prover_commands() { + local commands; commands=( +'init:Initialize prover' \ +'setup-keys:Generate setup keys' \ +'run:Run prover' \ +'init-bellman-cuda:Initialize bellman-cuda' \ +'compressor-keys:Download compressor keys' \ +'help:Print this message or the help of the given subcommand(s)' \ + ) + _describe -t commands 'zkstack prover commands' commands "$@" +} +(( $+functions[_zkstack__prover__compressor-keys_commands] )) || +_zkstack__prover__compressor-keys_commands() { + local commands; commands=() + _describe -t commands 'zkstack prover compressor-keys commands' commands "$@" +} +(( $+functions[_zkstack__prover__help_commands] )) || +_zkstack__prover__help_commands() { + local commands; commands=( +'init:Initialize prover' \ +'setup-keys:Generate setup keys' \ +'run:Run prover' \ +'init-bellman-cuda:Initialize bellman-cuda' \ +'compressor-keys:Download compressor keys' \ +'help:Print this message or the help of the given subcommand(s)' \ + ) + _describe -t commands 'zkstack prover help commands' commands "$@" +} +(( $+functions[_zkstack__prover__help__compressor-keys_commands] )) || +_zkstack__prover__help__compressor-keys_commands() { + local commands; commands=() + _describe -t commands 'zkstack prover help compressor-keys commands' commands "$@" +} +(( $+functions[_zkstack__prover__help__help_commands] )) || +_zkstack__prover__help__help_commands() { + local commands; commands=() + _describe -t commands 'zkstack prover help help commands' commands "$@" +} +(( $+functions[_zkstack__prover__help__init_commands] )) || +_zkstack__prover__help__init_commands() { + local commands; commands=() + _describe -t commands 'zkstack prover help init commands' commands "$@" +} +(( $+functions[_zkstack__prover__help__init-bellman-cuda_commands] )) || +_zkstack__prover__help__init-bellman-cuda_commands() { + local commands; commands=() + _describe -t commands 'zkstack prover help init-bellman-cuda commands' commands "$@" +} +(( $+functions[_zkstack__prover__help__run_commands] )) || +_zkstack__prover__help__run_commands() { + local commands; commands=() + _describe -t commands 'zkstack prover help run commands' commands "$@" +} +(( $+functions[_zkstack__prover__help__setup-keys_commands] )) || +_zkstack__prover__help__setup-keys_commands() { + local commands; commands=() + _describe -t commands 'zkstack prover help setup-keys commands' commands "$@" +} +(( $+functions[_zkstack__prover__init_commands] )) || +_zkstack__prover__init_commands() { + local commands; commands=() + _describe -t commands 'zkstack prover init commands' commands "$@" +} +(( $+functions[_zkstack__prover__init-bellman-cuda_commands] )) || +_zkstack__prover__init-bellman-cuda_commands() { + local commands; commands=() + _describe -t commands 'zkstack prover init-bellman-cuda commands' commands "$@" +} +(( $+functions[_zkstack__prover__run_commands] )) || +_zkstack__prover__run_commands() { + local commands; commands=() + _describe -t commands 'zkstack prover run commands' commands "$@" +} +(( $+functions[_zkstack__prover__setup-keys_commands] )) || +_zkstack__prover__setup-keys_commands() { + local commands; commands=() + _describe -t commands 'zkstack prover setup-keys commands' commands "$@" +} +(( $+functions[_zkstack__server_commands] )) || +_zkstack__server_commands() { + local commands; commands=() + _describe -t commands 'zkstack server commands' commands "$@" +} +(( $+functions[_zkstack__update_commands] )) || +_zkstack__update_commands() { + local commands; commands=() + _describe -t commands 'zkstack update commands' commands "$@" +} + +if [ "$funcstack[1]" = "_zkstack" ]; then + _zkstack "$@" +else + compdef _zkstack zkstack +fi diff --git a/zkstack_cli/crates/zkstack/completion/zkstack.fish b/zkstack_cli/crates/zkstack/completion/zkstack.fish new file mode 100644 index 000000000000..d490085e6154 --- /dev/null +++ b/zkstack_cli/crates/zkstack/completion/zkstack.fish @@ -0,0 +1,701 @@ +# Print an optspec for argparse to handle cmd's options that are independent of any subcommand. +function __fish_zkstack_global_optspecs + string join \n v/verbose chain= ignore-prerequisites h/help V/version +end + +function __fish_zkstack_needs_command + # Figure out if the current invocation already has a command. + set -l cmd (commandline -opc) + set -e cmd[1] + argparse -s (__fish_zkstack_global_optspecs) -- $cmd 2>/dev/null + or return + if set -q argv[1] + # Also print the command, so this can be used to figure out what it is. + echo $argv[1] + return 1 + end + return 0 +end + +function __fish_zkstack_using_subcommand + set -l cmd (__fish_zkstack_needs_command) + test -z "$cmd" + and return 1 + contains -- $cmd[1] $argv +end + +complete -c zkstack -n "__fish_zkstack_needs_command" -l chain -d 'Chain to use' -r +complete -c zkstack -n "__fish_zkstack_needs_command" -s v -l verbose -d 'Verbose mode' +complete -c zkstack -n "__fish_zkstack_needs_command" -l ignore-prerequisites -d 'Ignores prerequisites checks' +complete -c zkstack -n "__fish_zkstack_needs_command" -s h -l help -d 'Print help' +complete -c zkstack -n "__fish_zkstack_needs_command" -s V -l version -d 'Print version' +complete -c zkstack -n "__fish_zkstack_needs_command" -f -a "autocomplete" -d 'Create shell autocompletion files' +complete -c zkstack -n "__fish_zkstack_needs_command" -f -a "ecosystem" -d 'Ecosystem related commands' +complete -c zkstack -n "__fish_zkstack_needs_command" -f -a "chain" -d 'Chain related commands' +complete -c zkstack -n "__fish_zkstack_needs_command" -f -a "dev" -d 'Supervisor related commands' +complete -c zkstack -n "__fish_zkstack_needs_command" -f -a "prover" -d 'Prover related commands' +complete -c zkstack -n "__fish_zkstack_needs_command" -f -a "server" -d 'Run server' +complete -c zkstack -n "__fish_zkstack_needs_command" -f -a "external-node" -d 'External Node related commands' +complete -c zkstack -n "__fish_zkstack_needs_command" -f -a "containers" -d 'Run containers for local development' +complete -c zkstack -n "__fish_zkstack_needs_command" -f -a "contract-verifier" -d 'Run contract verifier' +complete -c zkstack -n "__fish_zkstack_needs_command" -f -a "portal" -d 'Run dapp-portal' +complete -c zkstack -n "__fish_zkstack_needs_command" -f -a "explorer" -d 'Run block-explorer' +complete -c zkstack -n "__fish_zkstack_needs_command" -f -a "consensus" -d 'Consensus utilities' +complete -c zkstack -n "__fish_zkstack_needs_command" -f -a "update" -d 'Update ZKsync' +complete -c zkstack -n "__fish_zkstack_needs_command" -f -a "markdown" -d 'Print markdown help' +complete -c zkstack -n "__fish_zkstack_needs_command" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' +complete -c zkstack -n "__fish_zkstack_using_subcommand autocomplete" -l generate -d 'The shell to generate the autocomplete script for' -r -f -a "{bash\t'',elvish\t'',fish\t'',powershell\t'',zsh\t''}" +complete -c zkstack -n "__fish_zkstack_using_subcommand autocomplete" -s o -l out -d 'The out directory to write the autocomplete script to' -r -F +complete -c zkstack -n "__fish_zkstack_using_subcommand autocomplete" -l chain -d 'Chain to use' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand autocomplete" -s v -l verbose -d 'Verbose mode' +complete -c zkstack -n "__fish_zkstack_using_subcommand autocomplete" -l ignore-prerequisites -d 'Ignores prerequisites checks' +complete -c zkstack -n "__fish_zkstack_using_subcommand autocomplete" -s h -l help -d 'Print help' +complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and not __fish_seen_subcommand_from create build-transactions init change-default-chain setup-observability help" -l chain -d 'Chain to use' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and not __fish_seen_subcommand_from create build-transactions init change-default-chain setup-observability help" -s v -l verbose -d 'Verbose mode' +complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and not __fish_seen_subcommand_from create build-transactions init change-default-chain setup-observability help" -l ignore-prerequisites -d 'Ignores prerequisites checks' +complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and not __fish_seen_subcommand_from create build-transactions init change-default-chain setup-observability help" -s h -l help -d 'Print help' +complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and not __fish_seen_subcommand_from create build-transactions init change-default-chain setup-observability help" -f -a "create" -d 'Create a new ecosystem and chain, setting necessary configurations for later initialization' +complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and not __fish_seen_subcommand_from create build-transactions init change-default-chain setup-observability help" -f -a "build-transactions" -d 'Create transactions to build ecosystem contracts' +complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and not __fish_seen_subcommand_from create build-transactions init change-default-chain setup-observability help" -f -a "init" -d 'Initialize ecosystem and chain, deploying necessary contracts and performing on-chain operations' +complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and not __fish_seen_subcommand_from create build-transactions init change-default-chain setup-observability help" -f -a "change-default-chain" -d 'Change the default chain' +complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and not __fish_seen_subcommand_from create build-transactions init change-default-chain setup-observability help" -f -a "setup-observability" -d 'Setup observability for the ecosystem, downloading Grafana dashboards from the era-observability repo' +complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and not __fish_seen_subcommand_from create build-transactions init change-default-chain setup-observability help" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' +complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and __fish_seen_subcommand_from create" -l ecosystem-name -r +complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and __fish_seen_subcommand_from create" -l l1-network -d 'L1 Network' -r -f -a "{localhost\t'',sepolia\t'',holesky\t'',mainnet\t''}" +complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and __fish_seen_subcommand_from create" -l link-to-code -d 'Code link' -r -f -a "(__fish_complete_directories)" +complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and __fish_seen_subcommand_from create" -l chain-name -r +complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and __fish_seen_subcommand_from create" -l chain-id -d 'Chain ID' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and __fish_seen_subcommand_from create" -l prover-mode -d 'Prover options' -r -f -a "{no-proofs\t'',gpu\t''}" +complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and __fish_seen_subcommand_from create" -l wallet-creation -d 'Wallet options' -r -f -a "{localhost\t'Load wallets from localhost mnemonic, they are funded for localhost env',random\t'Generate random wallets',empty\t'Generate placeholder wallets',in-file\t'Specify file with wallets'}" +complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and __fish_seen_subcommand_from create" -l wallet-path -d 'Wallet path' -r -F +complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and __fish_seen_subcommand_from create" -l l1-batch-commit-data-generator-mode -d 'Commit data generation mode' -r -f -a "{rollup\t'',validium\t''}" +complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and __fish_seen_subcommand_from create" -l base-token-address -d 'Base token address' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and __fish_seen_subcommand_from create" -l base-token-price-nominator -d 'Base token nominator' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and __fish_seen_subcommand_from create" -l base-token-price-denominator -d 'Base token denominator' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and __fish_seen_subcommand_from create" -l set-as-default -d 'Set as default chain' -r -f -a "{true\t'',false\t''}" +complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and __fish_seen_subcommand_from create" -l start-containers -d 'Start reth and postgres containers after creation' -r -f -a "{true\t'',false\t''}" +complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and __fish_seen_subcommand_from create" -l chain -d 'Chain to use' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and __fish_seen_subcommand_from create" -l legacy-bridge +complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and __fish_seen_subcommand_from create" -s v -l verbose -d 'Verbose mode' +complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and __fish_seen_subcommand_from create" -l ignore-prerequisites -d 'Ignores prerequisites checks' +complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and __fish_seen_subcommand_from create" -s h -l help -d 'Print help (see more with \'--help\')' +complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and __fish_seen_subcommand_from build-transactions" -l sender -d 'Address of the transaction sender' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and __fish_seen_subcommand_from build-transactions" -l l1-rpc-url -d 'L1 RPC URL' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and __fish_seen_subcommand_from build-transactions" -s o -l out -d 'Output directory for the generated files' -r -F +complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and __fish_seen_subcommand_from build-transactions" -l verify -d 'Verify deployed contracts' -r -f -a "{true\t'',false\t''}" +complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and __fish_seen_subcommand_from build-transactions" -l verifier -d 'Verifier to use' -r -f -a "{etherscan\t'',sourcify\t'',blockscout\t'',oklink\t''}" +complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and __fish_seen_subcommand_from build-transactions" -l verifier-url -d 'Verifier URL, if using a custom provider' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and __fish_seen_subcommand_from build-transactions" -l verifier-api-key -d 'Verifier API key' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and __fish_seen_subcommand_from build-transactions" -s a -l additional-args -d 'List of additional arguments that can be passed through the CLI' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and __fish_seen_subcommand_from build-transactions" -l chain -d 'Chain to use' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and __fish_seen_subcommand_from build-transactions" -l resume +complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and __fish_seen_subcommand_from build-transactions" -s v -l verbose -d 'Verbose mode' +complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and __fish_seen_subcommand_from build-transactions" -l ignore-prerequisites -d 'Ignores prerequisites checks' +complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and __fish_seen_subcommand_from build-transactions" -s h -l help -d 'Print help (see more with \'--help\')' +complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and __fish_seen_subcommand_from init" -l deploy-erc20 -d 'Deploy ERC20 contracts' -r -f -a "{true\t'',false\t''}" +complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and __fish_seen_subcommand_from init" -l deploy-ecosystem -d 'Deploy ecosystem contracts' -r -f -a "{true\t'',false\t''}" +complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and __fish_seen_subcommand_from init" -l ecosystem-contracts-path -d 'Path to ecosystem contracts' -r -F +complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and __fish_seen_subcommand_from init" -l l1-rpc-url -d 'L1 RPC URL' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and __fish_seen_subcommand_from init" -l verify -d 'Verify deployed contracts' -r -f -a "{true\t'',false\t''}" +complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and __fish_seen_subcommand_from init" -l verifier -d 'Verifier to use' -r -f -a "{etherscan\t'',sourcify\t'',blockscout\t'',oklink\t''}" +complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and __fish_seen_subcommand_from init" -l verifier-url -d 'Verifier URL, if using a custom provider' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and __fish_seen_subcommand_from init" -l verifier-api-key -d 'Verifier API key' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and __fish_seen_subcommand_from init" -s a -l additional-args -d 'List of additional arguments that can be passed through the CLI' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and __fish_seen_subcommand_from init" -l deploy-paymaster -d 'Deploy Paymaster contract' -r -f -a "{true\t'',false\t''}" +complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and __fish_seen_subcommand_from init" -l server-db-url -d 'Server database url without database name' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and __fish_seen_subcommand_from init" -l server-db-name -d 'Server database name' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and __fish_seen_subcommand_from init" -s o -l observability -d 'Enable Grafana' -r -f -a "{true\t'',false\t''}" +complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and __fish_seen_subcommand_from init" -l chain -d 'Chain to use' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and __fish_seen_subcommand_from init" -l resume +complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and __fish_seen_subcommand_from init" -s u -l use-default -d 'Use default database urls and names' +complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and __fish_seen_subcommand_from init" -s d -l dont-drop +complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and __fish_seen_subcommand_from init" -l ecosystem-only -d 'Initialize ecosystem only and skip chain initialization (chain can be initialized later with `chain init` subcommand)' +complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and __fish_seen_subcommand_from init" -l dev -d 'Deploy ecosystem using all defaults. Suitable for local development' +complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and __fish_seen_subcommand_from init" -l no-port-reallocation -d 'Do not reallocate ports' +complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and __fish_seen_subcommand_from init" -s v -l verbose -d 'Verbose mode' +complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and __fish_seen_subcommand_from init" -l ignore-prerequisites -d 'Ignores prerequisites checks' +complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and __fish_seen_subcommand_from init" -s h -l help -d 'Print help (see more with \'--help\')' +complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and __fish_seen_subcommand_from change-default-chain" -l chain -d 'Chain to use' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and __fish_seen_subcommand_from change-default-chain" -s v -l verbose -d 'Verbose mode' +complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and __fish_seen_subcommand_from change-default-chain" -l ignore-prerequisites -d 'Ignores prerequisites checks' +complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and __fish_seen_subcommand_from change-default-chain" -s h -l help -d 'Print help' +complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and __fish_seen_subcommand_from setup-observability" -l chain -d 'Chain to use' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and __fish_seen_subcommand_from setup-observability" -s v -l verbose -d 'Verbose mode' +complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and __fish_seen_subcommand_from setup-observability" -l ignore-prerequisites -d 'Ignores prerequisites checks' +complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and __fish_seen_subcommand_from setup-observability" -s h -l help -d 'Print help' +complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and __fish_seen_subcommand_from help" -f -a "create" -d 'Create a new ecosystem and chain, setting necessary configurations for later initialization' +complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and __fish_seen_subcommand_from help" -f -a "build-transactions" -d 'Create transactions to build ecosystem contracts' +complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and __fish_seen_subcommand_from help" -f -a "init" -d 'Initialize ecosystem and chain, deploying necessary contracts and performing on-chain operations' +complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and __fish_seen_subcommand_from help" -f -a "change-default-chain" -d 'Change the default chain' +complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and __fish_seen_subcommand_from help" -f -a "setup-observability" -d 'Setup observability for the ecosystem, downloading Grafana dashboards from the era-observability repo' +complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and __fish_seen_subcommand_from help" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and not __fish_seen_subcommand_from create build-transactions init genesis register-chain deploy-l2-contracts accept-chain-ownership initialize-bridges deploy-consensus-registry deploy-multicall3 deploy-upgrader deploy-paymaster update-token-multiplier-setter help" -l chain -d 'Chain to use' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and not __fish_seen_subcommand_from create build-transactions init genesis register-chain deploy-l2-contracts accept-chain-ownership initialize-bridges deploy-consensus-registry deploy-multicall3 deploy-upgrader deploy-paymaster update-token-multiplier-setter help" -s v -l verbose -d 'Verbose mode' +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and not __fish_seen_subcommand_from create build-transactions init genesis register-chain deploy-l2-contracts accept-chain-ownership initialize-bridges deploy-consensus-registry deploy-multicall3 deploy-upgrader deploy-paymaster update-token-multiplier-setter help" -l ignore-prerequisites -d 'Ignores prerequisites checks' +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and not __fish_seen_subcommand_from create build-transactions init genesis register-chain deploy-l2-contracts accept-chain-ownership initialize-bridges deploy-consensus-registry deploy-multicall3 deploy-upgrader deploy-paymaster update-token-multiplier-setter help" -s h -l help -d 'Print help' +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and not __fish_seen_subcommand_from create build-transactions init genesis register-chain deploy-l2-contracts accept-chain-ownership initialize-bridges deploy-consensus-registry deploy-multicall3 deploy-upgrader deploy-paymaster update-token-multiplier-setter help" -f -a "create" -d 'Create a new chain, setting the necessary configurations for later initialization' +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and not __fish_seen_subcommand_from create build-transactions init genesis register-chain deploy-l2-contracts accept-chain-ownership initialize-bridges deploy-consensus-registry deploy-multicall3 deploy-upgrader deploy-paymaster update-token-multiplier-setter help" -f -a "build-transactions" -d 'Create unsigned transactions for chain deployment' +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and not __fish_seen_subcommand_from create build-transactions init genesis register-chain deploy-l2-contracts accept-chain-ownership initialize-bridges deploy-consensus-registry deploy-multicall3 deploy-upgrader deploy-paymaster update-token-multiplier-setter help" -f -a "init" -d 'Initialize chain, deploying necessary contracts and performing on-chain operations' +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and not __fish_seen_subcommand_from create build-transactions init genesis register-chain deploy-l2-contracts accept-chain-ownership initialize-bridges deploy-consensus-registry deploy-multicall3 deploy-upgrader deploy-paymaster update-token-multiplier-setter help" -f -a "genesis" -d 'Run server genesis' +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and not __fish_seen_subcommand_from create build-transactions init genesis register-chain deploy-l2-contracts accept-chain-ownership initialize-bridges deploy-consensus-registry deploy-multicall3 deploy-upgrader deploy-paymaster update-token-multiplier-setter help" -f -a "register-chain" -d 'Register a new chain on L1 (executed by L1 governor). This command deploys and configures Governance, ChainAdmin, and DiamondProxy contracts, registers chain with BridgeHub and sets pending admin for DiamondProxy. Note: After completion, L2 governor can accept ownership by running `accept-chain-ownership`' +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and not __fish_seen_subcommand_from create build-transactions init genesis register-chain deploy-l2-contracts accept-chain-ownership initialize-bridges deploy-consensus-registry deploy-multicall3 deploy-upgrader deploy-paymaster update-token-multiplier-setter help" -f -a "deploy-l2-contracts" -d 'Deploy all L2 contracts (executed by L1 governor)' +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and not __fish_seen_subcommand_from create build-transactions init genesis register-chain deploy-l2-contracts accept-chain-ownership initialize-bridges deploy-consensus-registry deploy-multicall3 deploy-upgrader deploy-paymaster update-token-multiplier-setter help" -f -a "accept-chain-ownership" -d 'Accept ownership of L2 chain (executed by L2 governor). This command should be run after `register-chain` to accept ownership of newly created DiamondProxy contract' +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and not __fish_seen_subcommand_from create build-transactions init genesis register-chain deploy-l2-contracts accept-chain-ownership initialize-bridges deploy-consensus-registry deploy-multicall3 deploy-upgrader deploy-paymaster update-token-multiplier-setter help" -f -a "initialize-bridges" -d 'Initialize bridges on L2' +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and not __fish_seen_subcommand_from create build-transactions init genesis register-chain deploy-l2-contracts accept-chain-ownership initialize-bridges deploy-consensus-registry deploy-multicall3 deploy-upgrader deploy-paymaster update-token-multiplier-setter help" -f -a "deploy-consensus-registry" -d 'Deploy L2 consensus registry' +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and not __fish_seen_subcommand_from create build-transactions init genesis register-chain deploy-l2-contracts accept-chain-ownership initialize-bridges deploy-consensus-registry deploy-multicall3 deploy-upgrader deploy-paymaster update-token-multiplier-setter help" -f -a "deploy-multicall3" -d 'Deploy L2 multicall3' +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and not __fish_seen_subcommand_from create build-transactions init genesis register-chain deploy-l2-contracts accept-chain-ownership initialize-bridges deploy-consensus-registry deploy-multicall3 deploy-upgrader deploy-paymaster update-token-multiplier-setter help" -f -a "deploy-upgrader" -d 'Deploy Default Upgrader' +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and not __fish_seen_subcommand_from create build-transactions init genesis register-chain deploy-l2-contracts accept-chain-ownership initialize-bridges deploy-consensus-registry deploy-multicall3 deploy-upgrader deploy-paymaster update-token-multiplier-setter help" -f -a "deploy-paymaster" -d 'Deploy paymaster smart contract' +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and not __fish_seen_subcommand_from create build-transactions init genesis register-chain deploy-l2-contracts accept-chain-ownership initialize-bridges deploy-consensus-registry deploy-multicall3 deploy-upgrader deploy-paymaster update-token-multiplier-setter help" -f -a "update-token-multiplier-setter" -d 'Update Token Multiplier Setter address on L1' +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and not __fish_seen_subcommand_from create build-transactions init genesis register-chain deploy-l2-contracts accept-chain-ownership initialize-bridges deploy-consensus-registry deploy-multicall3 deploy-upgrader deploy-paymaster update-token-multiplier-setter help" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from create" -l chain-name -r +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from create" -l chain-id -d 'Chain ID' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from create" -l prover-mode -d 'Prover options' -r -f -a "{no-proofs\t'',gpu\t''}" +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from create" -l wallet-creation -d 'Wallet options' -r -f -a "{localhost\t'Load wallets from localhost mnemonic, they are funded for localhost env',random\t'Generate random wallets',empty\t'Generate placeholder wallets',in-file\t'Specify file with wallets'}" +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from create" -l wallet-path -d 'Wallet path' -r -F +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from create" -l l1-batch-commit-data-generator-mode -d 'Commit data generation mode' -r -f -a "{rollup\t'',validium\t''}" +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from create" -l base-token-address -d 'Base token address' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from create" -l base-token-price-nominator -d 'Base token nominator' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from create" -l base-token-price-denominator -d 'Base token denominator' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from create" -l set-as-default -d 'Set as default chain' -r -f -a "{true\t'',false\t''}" +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from create" -l chain -d 'Chain to use' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from create" -l legacy-bridge +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from create" -s v -l verbose -d 'Verbose mode' +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from create" -l ignore-prerequisites -d 'Ignores prerequisites checks' +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from create" -s h -l help -d 'Print help (see more with \'--help\')' +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from build-transactions" -s o -l out -d 'Output directory for the generated files' -r -F +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from build-transactions" -l verify -d 'Verify deployed contracts' -r -f -a "{true\t'',false\t''}" +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from build-transactions" -l verifier -d 'Verifier to use' -r -f -a "{etherscan\t'',sourcify\t'',blockscout\t'',oklink\t''}" +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from build-transactions" -l verifier-url -d 'Verifier URL, if using a custom provider' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from build-transactions" -l verifier-api-key -d 'Verifier API key' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from build-transactions" -s a -l additional-args -d 'List of additional arguments that can be passed through the CLI' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from build-transactions" -l l1-rpc-url -d 'L1 RPC URL' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from build-transactions" -l chain -d 'Chain to use' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from build-transactions" -l resume +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from build-transactions" -s v -l verbose -d 'Verbose mode' +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from build-transactions" -l ignore-prerequisites -d 'Ignores prerequisites checks' +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from build-transactions" -s h -l help -d 'Print help (see more with \'--help\')' +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from init" -l verify -d 'Verify deployed contracts' -r -f -a "{true\t'',false\t''}" +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from init" -l verifier -d 'Verifier to use' -r -f -a "{etherscan\t'',sourcify\t'',blockscout\t'',oklink\t''}" +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from init" -l verifier-url -d 'Verifier URL, if using a custom provider' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from init" -l verifier-api-key -d 'Verifier API key' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from init" -s a -l additional-args -d 'List of additional arguments that can be passed through the CLI' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from init" -l server-db-url -d 'Server database url without database name' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from init" -l server-db-name -d 'Server database name' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from init" -l deploy-paymaster -r -f -a "{true\t'',false\t''}" +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from init" -l l1-rpc-url -d 'L1 RPC URL' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from init" -l chain -d 'Chain to use' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from init" -l resume +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from init" -s u -l use-default -d 'Use default database urls and names' +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from init" -s d -l dont-drop +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from init" -l no-port-reallocation -d 'Do not reallocate ports' +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from init" -s v -l verbose -d 'Verbose mode' +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from init" -l ignore-prerequisites -d 'Ignores prerequisites checks' +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from init" -s h -l help -d 'Print help (see more with \'--help\')' +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from init" -f -a "configs" -d 'Initialize chain configs' +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from init" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from genesis" -l server-db-url -d 'Server database url without database name' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from genesis" -l server-db-name -d 'Server database name' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from genesis" -l chain -d 'Chain to use' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from genesis" -s u -l use-default -d 'Use default database urls and names' +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from genesis" -s d -l dont-drop +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from genesis" -s v -l verbose -d 'Verbose mode' +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from genesis" -l ignore-prerequisites -d 'Ignores prerequisites checks' +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from genesis" -s h -l help -d 'Print help' +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from genesis" -f -a "init-database" -d 'Initialize databases' +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from genesis" -f -a "server" -d 'Runs server genesis' +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from genesis" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from register-chain" -l verify -d 'Verify deployed contracts' -r -f -a "{true\t'',false\t''}" +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from register-chain" -l verifier -d 'Verifier to use' -r -f -a "{etherscan\t'',sourcify\t'',blockscout\t'',oklink\t''}" +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from register-chain" -l verifier-url -d 'Verifier URL, if using a custom provider' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from register-chain" -l verifier-api-key -d 'Verifier API key' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from register-chain" -s a -l additional-args -d 'List of additional arguments that can be passed through the CLI' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from register-chain" -l chain -d 'Chain to use' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from register-chain" -l resume +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from register-chain" -s v -l verbose -d 'Verbose mode' +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from register-chain" -l ignore-prerequisites -d 'Ignores prerequisites checks' +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from register-chain" -s h -l help -d 'Print help (see more with \'--help\')' +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from deploy-l2-contracts" -l verify -d 'Verify deployed contracts' -r -f -a "{true\t'',false\t''}" +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from deploy-l2-contracts" -l verifier -d 'Verifier to use' -r -f -a "{etherscan\t'',sourcify\t'',blockscout\t'',oklink\t''}" +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from deploy-l2-contracts" -l verifier-url -d 'Verifier URL, if using a custom provider' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from deploy-l2-contracts" -l verifier-api-key -d 'Verifier API key' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from deploy-l2-contracts" -s a -l additional-args -d 'List of additional arguments that can be passed through the CLI' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from deploy-l2-contracts" -l chain -d 'Chain to use' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from deploy-l2-contracts" -l resume +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from deploy-l2-contracts" -s v -l verbose -d 'Verbose mode' +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from deploy-l2-contracts" -l ignore-prerequisites -d 'Ignores prerequisites checks' +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from deploy-l2-contracts" -s h -l help -d 'Print help (see more with \'--help\')' +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from accept-chain-ownership" -l verify -d 'Verify deployed contracts' -r -f -a "{true\t'',false\t''}" +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from accept-chain-ownership" -l verifier -d 'Verifier to use' -r -f -a "{etherscan\t'',sourcify\t'',blockscout\t'',oklink\t''}" +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from accept-chain-ownership" -l verifier-url -d 'Verifier URL, if using a custom provider' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from accept-chain-ownership" -l verifier-api-key -d 'Verifier API key' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from accept-chain-ownership" -s a -l additional-args -d 'List of additional arguments that can be passed through the CLI' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from accept-chain-ownership" -l chain -d 'Chain to use' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from accept-chain-ownership" -l resume +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from accept-chain-ownership" -s v -l verbose -d 'Verbose mode' +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from accept-chain-ownership" -l ignore-prerequisites -d 'Ignores prerequisites checks' +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from accept-chain-ownership" -s h -l help -d 'Print help (see more with \'--help\')' +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from initialize-bridges" -l verify -d 'Verify deployed contracts' -r -f -a "{true\t'',false\t''}" +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from initialize-bridges" -l verifier -d 'Verifier to use' -r -f -a "{etherscan\t'',sourcify\t'',blockscout\t'',oklink\t''}" +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from initialize-bridges" -l verifier-url -d 'Verifier URL, if using a custom provider' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from initialize-bridges" -l verifier-api-key -d 'Verifier API key' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from initialize-bridges" -s a -l additional-args -d 'List of additional arguments that can be passed through the CLI' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from initialize-bridges" -l chain -d 'Chain to use' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from initialize-bridges" -l resume +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from initialize-bridges" -s v -l verbose -d 'Verbose mode' +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from initialize-bridges" -l ignore-prerequisites -d 'Ignores prerequisites checks' +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from initialize-bridges" -s h -l help -d 'Print help (see more with \'--help\')' +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from deploy-consensus-registry" -l verify -d 'Verify deployed contracts' -r -f -a "{true\t'',false\t''}" +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from deploy-consensus-registry" -l verifier -d 'Verifier to use' -r -f -a "{etherscan\t'',sourcify\t'',blockscout\t'',oklink\t''}" +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from deploy-consensus-registry" -l verifier-url -d 'Verifier URL, if using a custom provider' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from deploy-consensus-registry" -l verifier-api-key -d 'Verifier API key' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from deploy-consensus-registry" -s a -l additional-args -d 'List of additional arguments that can be passed through the CLI' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from deploy-consensus-registry" -l chain -d 'Chain to use' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from deploy-consensus-registry" -l resume +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from deploy-consensus-registry" -s v -l verbose -d 'Verbose mode' +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from deploy-consensus-registry" -l ignore-prerequisites -d 'Ignores prerequisites checks' +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from deploy-consensus-registry" -s h -l help -d 'Print help (see more with \'--help\')' +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from deploy-multicall3" -l verify -d 'Verify deployed contracts' -r -f -a "{true\t'',false\t''}" +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from deploy-multicall3" -l verifier -d 'Verifier to use' -r -f -a "{etherscan\t'',sourcify\t'',blockscout\t'',oklink\t''}" +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from deploy-multicall3" -l verifier-url -d 'Verifier URL, if using a custom provider' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from deploy-multicall3" -l verifier-api-key -d 'Verifier API key' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from deploy-multicall3" -s a -l additional-args -d 'List of additional arguments that can be passed through the CLI' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from deploy-multicall3" -l chain -d 'Chain to use' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from deploy-multicall3" -l resume +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from deploy-multicall3" -s v -l verbose -d 'Verbose mode' +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from deploy-multicall3" -l ignore-prerequisites -d 'Ignores prerequisites checks' +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from deploy-multicall3" -s h -l help -d 'Print help (see more with \'--help\')' +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from deploy-upgrader" -l verify -d 'Verify deployed contracts' -r -f -a "{true\t'',false\t''}" +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from deploy-upgrader" -l verifier -d 'Verifier to use' -r -f -a "{etherscan\t'',sourcify\t'',blockscout\t'',oklink\t''}" +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from deploy-upgrader" -l verifier-url -d 'Verifier URL, if using a custom provider' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from deploy-upgrader" -l verifier-api-key -d 'Verifier API key' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from deploy-upgrader" -s a -l additional-args -d 'List of additional arguments that can be passed through the CLI' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from deploy-upgrader" -l chain -d 'Chain to use' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from deploy-upgrader" -l resume +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from deploy-upgrader" -s v -l verbose -d 'Verbose mode' +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from deploy-upgrader" -l ignore-prerequisites -d 'Ignores prerequisites checks' +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from deploy-upgrader" -s h -l help -d 'Print help (see more with \'--help\')' +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from deploy-paymaster" -l verify -d 'Verify deployed contracts' -r -f -a "{true\t'',false\t''}" +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from deploy-paymaster" -l verifier -d 'Verifier to use' -r -f -a "{etherscan\t'',sourcify\t'',blockscout\t'',oklink\t''}" +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from deploy-paymaster" -l verifier-url -d 'Verifier URL, if using a custom provider' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from deploy-paymaster" -l verifier-api-key -d 'Verifier API key' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from deploy-paymaster" -s a -l additional-args -d 'List of additional arguments that can be passed through the CLI' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from deploy-paymaster" -l chain -d 'Chain to use' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from deploy-paymaster" -l resume +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from deploy-paymaster" -s v -l verbose -d 'Verbose mode' +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from deploy-paymaster" -l ignore-prerequisites -d 'Ignores prerequisites checks' +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from deploy-paymaster" -s h -l help -d 'Print help (see more with \'--help\')' +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from update-token-multiplier-setter" -l verify -d 'Verify deployed contracts' -r -f -a "{true\t'',false\t''}" +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from update-token-multiplier-setter" -l verifier -d 'Verifier to use' -r -f -a "{etherscan\t'',sourcify\t'',blockscout\t'',oklink\t''}" +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from update-token-multiplier-setter" -l verifier-url -d 'Verifier URL, if using a custom provider' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from update-token-multiplier-setter" -l verifier-api-key -d 'Verifier API key' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from update-token-multiplier-setter" -s a -l additional-args -d 'List of additional arguments that can be passed through the CLI' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from update-token-multiplier-setter" -l chain -d 'Chain to use' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from update-token-multiplier-setter" -l resume +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from update-token-multiplier-setter" -s v -l verbose -d 'Verbose mode' +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from update-token-multiplier-setter" -l ignore-prerequisites -d 'Ignores prerequisites checks' +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from update-token-multiplier-setter" -s h -l help -d 'Print help (see more with \'--help\')' +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from help" -f -a "create" -d 'Create a new chain, setting the necessary configurations for later initialization' +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from help" -f -a "build-transactions" -d 'Create unsigned transactions for chain deployment' +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from help" -f -a "init" -d 'Initialize chain, deploying necessary contracts and performing on-chain operations' +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from help" -f -a "genesis" -d 'Run server genesis' +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from help" -f -a "register-chain" -d 'Register a new chain on L1 (executed by L1 governor). This command deploys and configures Governance, ChainAdmin, and DiamondProxy contracts, registers chain with BridgeHub and sets pending admin for DiamondProxy. Note: After completion, L2 governor can accept ownership by running `accept-chain-ownership`' +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from help" -f -a "deploy-l2-contracts" -d 'Deploy all L2 contracts (executed by L1 governor)' +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from help" -f -a "accept-chain-ownership" -d 'Accept ownership of L2 chain (executed by L2 governor). This command should be run after `register-chain` to accept ownership of newly created DiamondProxy contract' +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from help" -f -a "initialize-bridges" -d 'Initialize bridges on L2' +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from help" -f -a "deploy-consensus-registry" -d 'Deploy L2 consensus registry' +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from help" -f -a "deploy-multicall3" -d 'Deploy L2 multicall3' +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from help" -f -a "deploy-upgrader" -d 'Deploy Default Upgrader' +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from help" -f -a "deploy-paymaster" -d 'Deploy paymaster smart contract' +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from help" -f -a "update-token-multiplier-setter" -d 'Update Token Multiplier Setter address on L1' +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from help" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and not __fish_seen_subcommand_from database test clean snapshot lint fmt prover contracts config-writer send-transactions status generate-genesis help" -l chain -d 'Chain to use' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and not __fish_seen_subcommand_from database test clean snapshot lint fmt prover contracts config-writer send-transactions status generate-genesis help" -s v -l verbose -d 'Verbose mode' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and not __fish_seen_subcommand_from database test clean snapshot lint fmt prover contracts config-writer send-transactions status generate-genesis help" -l ignore-prerequisites -d 'Ignores prerequisites checks' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and not __fish_seen_subcommand_from database test clean snapshot lint fmt prover contracts config-writer send-transactions status generate-genesis help" -s h -l help -d 'Print help' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and not __fish_seen_subcommand_from database test clean snapshot lint fmt prover contracts config-writer send-transactions status generate-genesis help" -f -a "database" -d 'Database related commands' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and not __fish_seen_subcommand_from database test clean snapshot lint fmt prover contracts config-writer send-transactions status generate-genesis help" -f -a "test" -d 'Run tests' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and not __fish_seen_subcommand_from database test clean snapshot lint fmt prover contracts config-writer send-transactions status generate-genesis help" -f -a "clean" -d 'Clean artifacts' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and not __fish_seen_subcommand_from database test clean snapshot lint fmt prover contracts config-writer send-transactions status generate-genesis help" -f -a "snapshot" -d 'Snapshots creator' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and not __fish_seen_subcommand_from database test clean snapshot lint fmt prover contracts config-writer send-transactions status generate-genesis help" -f -a "lint" -d 'Lint code' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and not __fish_seen_subcommand_from database test clean snapshot lint fmt prover contracts config-writer send-transactions status generate-genesis help" -f -a "fmt" -d 'Format code' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and not __fish_seen_subcommand_from database test clean snapshot lint fmt prover contracts config-writer send-transactions status generate-genesis help" -f -a "prover" -d 'Protocol version used by provers' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and not __fish_seen_subcommand_from database test clean snapshot lint fmt prover contracts config-writer send-transactions status generate-genesis help" -f -a "contracts" -d 'Build contracts' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and not __fish_seen_subcommand_from database test clean snapshot lint fmt prover contracts config-writer send-transactions status generate-genesis help" -f -a "config-writer" -d 'Overwrite general config' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and not __fish_seen_subcommand_from database test clean snapshot lint fmt prover contracts config-writer send-transactions status generate-genesis help" -f -a "send-transactions" -d 'Send transactions from file' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and not __fish_seen_subcommand_from database test clean snapshot lint fmt prover contracts config-writer send-transactions status generate-genesis help" -f -a "status" -d 'Get status of the server' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and not __fish_seen_subcommand_from database test clean snapshot lint fmt prover contracts config-writer send-transactions status generate-genesis help" -f -a "generate-genesis" -d 'Generate new genesis file based on current contracts' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and not __fish_seen_subcommand_from database test clean snapshot lint fmt prover contracts config-writer send-transactions status generate-genesis help" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from database" -l chain -d 'Chain to use' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from database" -s v -l verbose -d 'Verbose mode' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from database" -l ignore-prerequisites -d 'Ignores prerequisites checks' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from database" -s h -l help -d 'Print help' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from database" -f -a "check-sqlx-data" -d 'Check sqlx-data.json is up to date. If no databases are selected, all databases will be checked.' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from database" -f -a "drop" -d 'Drop databases. If no databases are selected, all databases will be dropped.' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from database" -f -a "migrate" -d 'Migrate databases. If no databases are selected, all databases will be migrated.' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from database" -f -a "new-migration" -d 'Create new migration' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from database" -f -a "prepare" -d 'Prepare sqlx-data.json. If no databases are selected, all databases will be prepared.' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from database" -f -a "reset" -d 'Reset databases. If no databases are selected, all databases will be reset.' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from database" -f -a "setup" -d 'Setup databases. If no databases are selected, all databases will be setup.' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from database" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from test" -l chain -d 'Chain to use' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from test" -s v -l verbose -d 'Verbose mode' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from test" -l ignore-prerequisites -d 'Ignores prerequisites checks' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from test" -s h -l help -d 'Print help' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from test" -f -a "integration" -d 'Run integration tests' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from test" -f -a "fees" -d 'Run fees test' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from test" -f -a "revert" -d 'Run revert tests' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from test" -f -a "recovery" -d 'Run recovery tests' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from test" -f -a "upgrade" -d 'Run upgrade tests' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from test" -f -a "build" -d 'Build all test dependencies' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from test" -f -a "rust" -d 'Run unit-tests, accepts optional cargo test flags' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from test" -f -a "l1-contracts" -d 'Run L1 contracts tests' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from test" -f -a "prover" -d 'Run prover tests' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from test" -f -a "wallet" -d 'Print test wallets information' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from test" -f -a "loadtest" -d 'Run loadtest' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from test" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from clean" -l chain -d 'Chain to use' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from clean" -s v -l verbose -d 'Verbose mode' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from clean" -l ignore-prerequisites -d 'Ignores prerequisites checks' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from clean" -s h -l help -d 'Print help' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from clean" -f -a "all" -d 'Remove containers and contracts cache' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from clean" -f -a "containers" -d 'Remove containers and docker volumes' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from clean" -f -a "contracts-cache" -d 'Remove contracts caches' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from clean" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from snapshot" -l chain -d 'Chain to use' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from snapshot" -s v -l verbose -d 'Verbose mode' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from snapshot" -l ignore-prerequisites -d 'Ignores prerequisites checks' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from snapshot" -s h -l help -d 'Print help' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from snapshot" -f -a "create" +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from snapshot" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from lint" -s t -l targets -r -f -a "{md\t'',sol\t'',js\t'',ts\t'',rs\t'',contracts\t'',autocompletion\t''}" +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from lint" -l chain -d 'Chain to use' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from lint" -s c -l check +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from lint" -s v -l verbose -d 'Verbose mode' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from lint" -l ignore-prerequisites -d 'Ignores prerequisites checks' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from lint" -s h -l help -d 'Print help' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from fmt" -l chain -d 'Chain to use' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from fmt" -s c -l check +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from fmt" -s v -l verbose -d 'Verbose mode' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from fmt" -l ignore-prerequisites -d 'Ignores prerequisites checks' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from fmt" -s h -l help -d 'Print help' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from fmt" -f -a "rustfmt" +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from fmt" -f -a "contract" +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from fmt" -f -a "prettier" +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from fmt" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from prover" -l chain -d 'Chain to use' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from prover" -s v -l verbose -d 'Verbose mode' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from prover" -l ignore-prerequisites -d 'Ignores prerequisites checks' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from prover" -s h -l help -d 'Print help' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from prover" -f -a "info" +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from prover" -f -a "insert-batch" +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from prover" -f -a "insert-version" +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from prover" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from contracts" -l l1-contracts -d 'Build L1 contracts' -r -f -a "{true\t'',false\t''}" +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from contracts" -l l2-contracts -d 'Build L2 contracts' -r -f -a "{true\t'',false\t''}" +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from contracts" -l system-contracts -d 'Build system contracts' -r -f -a "{true\t'',false\t''}" +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from contracts" -l test-contracts -d 'Build test contracts' -r -f -a "{true\t'',false\t''}" +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from contracts" -l chain -d 'Chain to use' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from contracts" -s v -l verbose -d 'Verbose mode' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from contracts" -l ignore-prerequisites -d 'Ignores prerequisites checks' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from contracts" -s h -l help -d 'Print help' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from config-writer" -s p -l path -d 'Path to the config file to override' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from config-writer" -l chain -d 'Chain to use' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from config-writer" -s v -l verbose -d 'Verbose mode' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from config-writer" -l ignore-prerequisites -d 'Ignores prerequisites checks' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from config-writer" -s h -l help -d 'Print help' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from send-transactions" -l file -r -F +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from send-transactions" -l private-key -r +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from send-transactions" -l l1-rpc-url -r +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from send-transactions" -l confirmations -r +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from send-transactions" -l chain -d 'Chain to use' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from send-transactions" -s v -l verbose -d 'Verbose mode' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from send-transactions" -l ignore-prerequisites -d 'Ignores prerequisites checks' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from send-transactions" -s h -l help -d 'Print help' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from status" -s u -l url -d 'URL of the health check endpoint' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from status" -l chain -d 'Chain to use' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from status" -s v -l verbose -d 'Verbose mode' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from status" -l ignore-prerequisites -d 'Ignores prerequisites checks' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from status" -s h -l help -d 'Print help' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from status" -f -a "ports" -d 'Show used ports' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from status" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from generate-genesis" -l chain -d 'Chain to use' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from generate-genesis" -s v -l verbose -d 'Verbose mode' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from generate-genesis" -l ignore-prerequisites -d 'Ignores prerequisites checks' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from generate-genesis" -s h -l help -d 'Print help' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from help" -f -a "database" -d 'Database related commands' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from help" -f -a "test" -d 'Run tests' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from help" -f -a "clean" -d 'Clean artifacts' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from help" -f -a "snapshot" -d 'Snapshots creator' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from help" -f -a "lint" -d 'Lint code' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from help" -f -a "fmt" -d 'Format code' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from help" -f -a "prover" -d 'Protocol version used by provers' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from help" -f -a "contracts" -d 'Build contracts' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from help" -f -a "config-writer" -d 'Overwrite general config' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from help" -f -a "send-transactions" -d 'Send transactions from file' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from help" -f -a "status" -d 'Get status of the server' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from help" -f -a "generate-genesis" -d 'Generate new genesis file based on current contracts' +complete -c zkstack -n "__fish_zkstack_using_subcommand dev; and __fish_seen_subcommand_from help" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' +complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and not __fish_seen_subcommand_from init setup-keys run init-bellman-cuda compressor-keys help" -l chain -d 'Chain to use' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and not __fish_seen_subcommand_from init setup-keys run init-bellman-cuda compressor-keys help" -s v -l verbose -d 'Verbose mode' +complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and not __fish_seen_subcommand_from init setup-keys run init-bellman-cuda compressor-keys help" -l ignore-prerequisites -d 'Ignores prerequisites checks' +complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and not __fish_seen_subcommand_from init setup-keys run init-bellman-cuda compressor-keys help" -s h -l help -d 'Print help' +complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and not __fish_seen_subcommand_from init setup-keys run init-bellman-cuda compressor-keys help" -f -a "init" -d 'Initialize prover' +complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and not __fish_seen_subcommand_from init setup-keys run init-bellman-cuda compressor-keys help" -f -a "setup-keys" -d 'Generate setup keys' +complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and not __fish_seen_subcommand_from init setup-keys run init-bellman-cuda compressor-keys help" -f -a "run" -d 'Run prover' +complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and not __fish_seen_subcommand_from init setup-keys run init-bellman-cuda compressor-keys help" -f -a "init-bellman-cuda" -d 'Initialize bellman-cuda' +complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and not __fish_seen_subcommand_from init setup-keys run init-bellman-cuda compressor-keys help" -f -a "compressor-keys" -d 'Download compressor keys' +complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and not __fish_seen_subcommand_from init setup-keys run init-bellman-cuda compressor-keys help" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' +complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_subcommand_from init" -l proof-store-dir -r +complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_subcommand_from init" -l bucket-base-url -r +complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_subcommand_from init" -l credentials-file -r +complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_subcommand_from init" -l bucket-name -r +complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_subcommand_from init" -l location -r +complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_subcommand_from init" -l project-id -r +complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_subcommand_from init" -l shall-save-to-public-bucket -r -f -a "{true\t'',false\t''}" +complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_subcommand_from init" -l public-store-dir -r +complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_subcommand_from init" -l public-bucket-base-url -r +complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_subcommand_from init" -l public-credentials-file -r +complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_subcommand_from init" -l public-bucket-name -r +complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_subcommand_from init" -l public-location -r +complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_subcommand_from init" -l public-project-id -r +complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_subcommand_from init" -l bellman-cuda-dir -r +complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_subcommand_from init" -l bellman-cuda -r -f -a "{true\t'',false\t''}" +complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_subcommand_from init" -l setup-compressor-key -r -f -a "{true\t'',false\t''}" +complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_subcommand_from init" -l path -r +complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_subcommand_from init" -l region -r -f -a "{us\t'',europe\t'',asia\t''}" +complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_subcommand_from init" -l mode -r -f -a "{download\t'',generate\t''}" +complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_subcommand_from init" -l setup-keys -r -f -a "{true\t'',false\t''}" +complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_subcommand_from init" -l setup-database -r -f -a "{true\t'',false\t''}" +complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_subcommand_from init" -l prover-db-url -d 'Prover database url without database name' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_subcommand_from init" -l prover-db-name -d 'Prover database name' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_subcommand_from init" -s u -l use-default -d 'Use default database urls and names' -r -f -a "{true\t'',false\t''}" +complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_subcommand_from init" -s d -l dont-drop -r -f -a "{true\t'',false\t''}" +complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_subcommand_from init" -l cloud-type -r -f -a "{gcp\t'',local\t''}" +complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_subcommand_from init" -l chain -d 'Chain to use' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_subcommand_from init" -l dev +complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_subcommand_from init" -l clone +complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_subcommand_from init" -s v -l verbose -d 'Verbose mode' +complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_subcommand_from init" -l ignore-prerequisites -d 'Ignores prerequisites checks' +complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_subcommand_from init" -s h -l help -d 'Print help' +complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_subcommand_from setup-keys" -l region -r -f -a "{us\t'',europe\t'',asia\t''}" +complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_subcommand_from setup-keys" -l mode -r -f -a "{download\t'',generate\t''}" +complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_subcommand_from setup-keys" -l chain -d 'Chain to use' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_subcommand_from setup-keys" -s v -l verbose -d 'Verbose mode' +complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_subcommand_from setup-keys" -l ignore-prerequisites -d 'Ignores prerequisites checks' +complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_subcommand_from setup-keys" -s h -l help -d 'Print help' +complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_subcommand_from run" -l component -r -f -a "{gateway\t'',witness-generator\t'',witness-vector-generator\t'',prover\t'',circuit-prover\t'',compressor\t'',prover-job-monitor\t''}" +complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_subcommand_from run" -l round -r -f -a "{all-rounds\t'',basic-circuits\t'',leaf-aggregation\t'',node-aggregation\t'',recursion-tip\t'',scheduler\t''}" +complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_subcommand_from run" -l threads -r +complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_subcommand_from run" -l max-allocation -d 'Memory allocation limit in bytes (for prover component)' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_subcommand_from run" -l witness-vector-generator-count -r +complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_subcommand_from run" -l max-allocation -r +complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_subcommand_from run" -l docker -r -f -a "{true\t'',false\t''}" +complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_subcommand_from run" -l tag -r +complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_subcommand_from run" -l chain -d 'Chain to use' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_subcommand_from run" -s v -l verbose -d 'Verbose mode' +complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_subcommand_from run" -l ignore-prerequisites -d 'Ignores prerequisites checks' +complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_subcommand_from run" -s h -l help -d 'Print help' +complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_subcommand_from init-bellman-cuda" -l bellman-cuda-dir -r +complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_subcommand_from init-bellman-cuda" -l chain -d 'Chain to use' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_subcommand_from init-bellman-cuda" -l clone +complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_subcommand_from init-bellman-cuda" -s v -l verbose -d 'Verbose mode' +complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_subcommand_from init-bellman-cuda" -l ignore-prerequisites -d 'Ignores prerequisites checks' +complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_subcommand_from init-bellman-cuda" -s h -l help -d 'Print help' +complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_subcommand_from compressor-keys" -l path -r +complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_subcommand_from compressor-keys" -l chain -d 'Chain to use' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_subcommand_from compressor-keys" -s v -l verbose -d 'Verbose mode' +complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_subcommand_from compressor-keys" -l ignore-prerequisites -d 'Ignores prerequisites checks' +complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_subcommand_from compressor-keys" -s h -l help -d 'Print help' +complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_subcommand_from help" -f -a "init" -d 'Initialize prover' +complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_subcommand_from help" -f -a "setup-keys" -d 'Generate setup keys' +complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_subcommand_from help" -f -a "run" -d 'Run prover' +complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_subcommand_from help" -f -a "init-bellman-cuda" -d 'Initialize bellman-cuda' +complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_subcommand_from help" -f -a "compressor-keys" -d 'Download compressor keys' +complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_subcommand_from help" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' +complete -c zkstack -n "__fish_zkstack_using_subcommand server" -l components -d 'Components of server to run' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand server" -s a -l additional-args -d 'Additional arguments that can be passed through the CLI' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand server" -l chain -d 'Chain to use' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand server" -l genesis -d 'Run server in genesis mode' +complete -c zkstack -n "__fish_zkstack_using_subcommand server" -l build -d 'Build server but don\'t run it' +complete -c zkstack -n "__fish_zkstack_using_subcommand server" -l uring -d 'Enables uring support for RocksDB' +complete -c zkstack -n "__fish_zkstack_using_subcommand server" -s v -l verbose -d 'Verbose mode' +complete -c zkstack -n "__fish_zkstack_using_subcommand server" -l ignore-prerequisites -d 'Ignores prerequisites checks' +complete -c zkstack -n "__fish_zkstack_using_subcommand server" -s h -l help -d 'Print help' +complete -c zkstack -n "__fish_zkstack_using_subcommand external-node; and not __fish_seen_subcommand_from configs init run help" -l chain -d 'Chain to use' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand external-node; and not __fish_seen_subcommand_from configs init run help" -s v -l verbose -d 'Verbose mode' +complete -c zkstack -n "__fish_zkstack_using_subcommand external-node; and not __fish_seen_subcommand_from configs init run help" -l ignore-prerequisites -d 'Ignores prerequisites checks' +complete -c zkstack -n "__fish_zkstack_using_subcommand external-node; and not __fish_seen_subcommand_from configs init run help" -s h -l help -d 'Print help' +complete -c zkstack -n "__fish_zkstack_using_subcommand external-node; and not __fish_seen_subcommand_from configs init run help" -f -a "configs" -d 'Prepare configs for EN' +complete -c zkstack -n "__fish_zkstack_using_subcommand external-node; and not __fish_seen_subcommand_from configs init run help" -f -a "init" -d 'Init databases' +complete -c zkstack -n "__fish_zkstack_using_subcommand external-node; and not __fish_seen_subcommand_from configs init run help" -f -a "run" -d 'Run external node' +complete -c zkstack -n "__fish_zkstack_using_subcommand external-node; and not __fish_seen_subcommand_from configs init run help" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' +complete -c zkstack -n "__fish_zkstack_using_subcommand external-node; and __fish_seen_subcommand_from configs" -l db-url -r +complete -c zkstack -n "__fish_zkstack_using_subcommand external-node; and __fish_seen_subcommand_from configs" -l db-name -r +complete -c zkstack -n "__fish_zkstack_using_subcommand external-node; and __fish_seen_subcommand_from configs" -l l1-rpc-url -r +complete -c zkstack -n "__fish_zkstack_using_subcommand external-node; and __fish_seen_subcommand_from configs" -l chain -d 'Chain to use' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand external-node; and __fish_seen_subcommand_from configs" -s u -l use-default -d 'Use default database urls and names' +complete -c zkstack -n "__fish_zkstack_using_subcommand external-node; and __fish_seen_subcommand_from configs" -s v -l verbose -d 'Verbose mode' +complete -c zkstack -n "__fish_zkstack_using_subcommand external-node; and __fish_seen_subcommand_from configs" -l ignore-prerequisites -d 'Ignores prerequisites checks' +complete -c zkstack -n "__fish_zkstack_using_subcommand external-node; and __fish_seen_subcommand_from configs" -s h -l help -d 'Print help' +complete -c zkstack -n "__fish_zkstack_using_subcommand external-node; and __fish_seen_subcommand_from init" -l chain -d 'Chain to use' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand external-node; and __fish_seen_subcommand_from init" -s v -l verbose -d 'Verbose mode' +complete -c zkstack -n "__fish_zkstack_using_subcommand external-node; and __fish_seen_subcommand_from init" -l ignore-prerequisites -d 'Ignores prerequisites checks' +complete -c zkstack -n "__fish_zkstack_using_subcommand external-node; and __fish_seen_subcommand_from init" -s h -l help -d 'Print help' +complete -c zkstack -n "__fish_zkstack_using_subcommand external-node; and __fish_seen_subcommand_from run" -l components -d 'Components of server to run' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand external-node; and __fish_seen_subcommand_from run" -l enable-consensus -d 'Enable consensus' -r -f -a "{true\t'',false\t''}" +complete -c zkstack -n "__fish_zkstack_using_subcommand external-node; and __fish_seen_subcommand_from run" -s a -l additional-args -d 'Additional arguments that can be passed through the CLI' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand external-node; and __fish_seen_subcommand_from run" -l chain -d 'Chain to use' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand external-node; and __fish_seen_subcommand_from run" -l reinit +complete -c zkstack -n "__fish_zkstack_using_subcommand external-node; and __fish_seen_subcommand_from run" -s v -l verbose -d 'Verbose mode' +complete -c zkstack -n "__fish_zkstack_using_subcommand external-node; and __fish_seen_subcommand_from run" -l ignore-prerequisites -d 'Ignores prerequisites checks' +complete -c zkstack -n "__fish_zkstack_using_subcommand external-node; and __fish_seen_subcommand_from run" -s h -l help -d 'Print help' +complete -c zkstack -n "__fish_zkstack_using_subcommand external-node; and __fish_seen_subcommand_from help" -f -a "configs" -d 'Prepare configs for EN' +complete -c zkstack -n "__fish_zkstack_using_subcommand external-node; and __fish_seen_subcommand_from help" -f -a "init" -d 'Init databases' +complete -c zkstack -n "__fish_zkstack_using_subcommand external-node; and __fish_seen_subcommand_from help" -f -a "run" -d 'Run external node' +complete -c zkstack -n "__fish_zkstack_using_subcommand external-node; and __fish_seen_subcommand_from help" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' +complete -c zkstack -n "__fish_zkstack_using_subcommand containers" -s o -l observability -d 'Enable Grafana' -r -f -a "{true\t'',false\t''}" +complete -c zkstack -n "__fish_zkstack_using_subcommand containers" -l chain -d 'Chain to use' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand containers" -s v -l verbose -d 'Verbose mode' +complete -c zkstack -n "__fish_zkstack_using_subcommand containers" -l ignore-prerequisites -d 'Ignores prerequisites checks' +complete -c zkstack -n "__fish_zkstack_using_subcommand containers" -s h -l help -d 'Print help' +complete -c zkstack -n "__fish_zkstack_using_subcommand contract-verifier; and not __fish_seen_subcommand_from run init help" -l chain -d 'Chain to use' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand contract-verifier; and not __fish_seen_subcommand_from run init help" -s v -l verbose -d 'Verbose mode' +complete -c zkstack -n "__fish_zkstack_using_subcommand contract-verifier; and not __fish_seen_subcommand_from run init help" -l ignore-prerequisites -d 'Ignores prerequisites checks' +complete -c zkstack -n "__fish_zkstack_using_subcommand contract-verifier; and not __fish_seen_subcommand_from run init help" -s h -l help -d 'Print help' +complete -c zkstack -n "__fish_zkstack_using_subcommand contract-verifier; and not __fish_seen_subcommand_from run init help" -f -a "run" -d 'Run contract verifier' +complete -c zkstack -n "__fish_zkstack_using_subcommand contract-verifier; and not __fish_seen_subcommand_from run init help" -f -a "init" -d 'Download required binaries for contract verifier' +complete -c zkstack -n "__fish_zkstack_using_subcommand contract-verifier; and not __fish_seen_subcommand_from run init help" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' +complete -c zkstack -n "__fish_zkstack_using_subcommand contract-verifier; and __fish_seen_subcommand_from run" -l chain -d 'Chain to use' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand contract-verifier; and __fish_seen_subcommand_from run" -s v -l verbose -d 'Verbose mode' +complete -c zkstack -n "__fish_zkstack_using_subcommand contract-verifier; and __fish_seen_subcommand_from run" -l ignore-prerequisites -d 'Ignores prerequisites checks' +complete -c zkstack -n "__fish_zkstack_using_subcommand contract-verifier; and __fish_seen_subcommand_from run" -s h -l help -d 'Print help' +complete -c zkstack -n "__fish_zkstack_using_subcommand contract-verifier; and __fish_seen_subcommand_from init" -l zksolc-version -d 'Version of zksolc to install' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand contract-verifier; and __fish_seen_subcommand_from init" -l zkvyper-version -d 'Version of zkvyper to install' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand contract-verifier; and __fish_seen_subcommand_from init" -l solc-version -d 'Version of solc to install' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand contract-verifier; and __fish_seen_subcommand_from init" -l era-vm-solc-version -d 'Version of era vm solc to install' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand contract-verifier; and __fish_seen_subcommand_from init" -l vyper-version -d 'Version of vyper to install' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand contract-verifier; and __fish_seen_subcommand_from init" -l chain -d 'Chain to use' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand contract-verifier; and __fish_seen_subcommand_from init" -l only -d 'Install only provided compilers' +complete -c zkstack -n "__fish_zkstack_using_subcommand contract-verifier; and __fish_seen_subcommand_from init" -s v -l verbose -d 'Verbose mode' +complete -c zkstack -n "__fish_zkstack_using_subcommand contract-verifier; and __fish_seen_subcommand_from init" -l ignore-prerequisites -d 'Ignores prerequisites checks' +complete -c zkstack -n "__fish_zkstack_using_subcommand contract-verifier; and __fish_seen_subcommand_from init" -s h -l help -d 'Print help' +complete -c zkstack -n "__fish_zkstack_using_subcommand contract-verifier; and __fish_seen_subcommand_from help" -f -a "run" -d 'Run contract verifier' +complete -c zkstack -n "__fish_zkstack_using_subcommand contract-verifier; and __fish_seen_subcommand_from help" -f -a "init" -d 'Download required binaries for contract verifier' +complete -c zkstack -n "__fish_zkstack_using_subcommand contract-verifier; and __fish_seen_subcommand_from help" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' +complete -c zkstack -n "__fish_zkstack_using_subcommand portal" -l chain -d 'Chain to use' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand portal" -s v -l verbose -d 'Verbose mode' +complete -c zkstack -n "__fish_zkstack_using_subcommand portal" -l ignore-prerequisites -d 'Ignores prerequisites checks' +complete -c zkstack -n "__fish_zkstack_using_subcommand portal" -s h -l help -d 'Print help' +complete -c zkstack -n "__fish_zkstack_using_subcommand explorer; and not __fish_seen_subcommand_from init run-backend run help" -l chain -d 'Chain to use' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand explorer; and not __fish_seen_subcommand_from init run-backend run help" -s v -l verbose -d 'Verbose mode' +complete -c zkstack -n "__fish_zkstack_using_subcommand explorer; and not __fish_seen_subcommand_from init run-backend run help" -l ignore-prerequisites -d 'Ignores prerequisites checks' +complete -c zkstack -n "__fish_zkstack_using_subcommand explorer; and not __fish_seen_subcommand_from init run-backend run help" -s h -l help -d 'Print help' +complete -c zkstack -n "__fish_zkstack_using_subcommand explorer; and not __fish_seen_subcommand_from init run-backend run help" -f -a "init" -d 'Initialize explorer (create database to store explorer data and generate docker compose file with explorer services). Runs for all chains, unless --chain is passed' +complete -c zkstack -n "__fish_zkstack_using_subcommand explorer; and not __fish_seen_subcommand_from init run-backend run help" -f -a "run-backend" -d 'Start explorer backend services (api, data_fetcher, worker) for a given chain. Uses default chain, unless --chain is passed' +complete -c zkstack -n "__fish_zkstack_using_subcommand explorer; and not __fish_seen_subcommand_from init run-backend run help" -f -a "run" -d 'Run explorer app' +complete -c zkstack -n "__fish_zkstack_using_subcommand explorer; and not __fish_seen_subcommand_from init run-backend run help" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' +complete -c zkstack -n "__fish_zkstack_using_subcommand explorer; and __fish_seen_subcommand_from init" -l chain -d 'Chain to use' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand explorer; and __fish_seen_subcommand_from init" -s v -l verbose -d 'Verbose mode' +complete -c zkstack -n "__fish_zkstack_using_subcommand explorer; and __fish_seen_subcommand_from init" -l ignore-prerequisites -d 'Ignores prerequisites checks' +complete -c zkstack -n "__fish_zkstack_using_subcommand explorer; and __fish_seen_subcommand_from init" -s h -l help -d 'Print help' +complete -c zkstack -n "__fish_zkstack_using_subcommand explorer; and __fish_seen_subcommand_from run-backend" -l chain -d 'Chain to use' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand explorer; and __fish_seen_subcommand_from run-backend" -s v -l verbose -d 'Verbose mode' +complete -c zkstack -n "__fish_zkstack_using_subcommand explorer; and __fish_seen_subcommand_from run-backend" -l ignore-prerequisites -d 'Ignores prerequisites checks' +complete -c zkstack -n "__fish_zkstack_using_subcommand explorer; and __fish_seen_subcommand_from run-backend" -s h -l help -d 'Print help' +complete -c zkstack -n "__fish_zkstack_using_subcommand explorer; and __fish_seen_subcommand_from run" -l chain -d 'Chain to use' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand explorer; and __fish_seen_subcommand_from run" -s v -l verbose -d 'Verbose mode' +complete -c zkstack -n "__fish_zkstack_using_subcommand explorer; and __fish_seen_subcommand_from run" -l ignore-prerequisites -d 'Ignores prerequisites checks' +complete -c zkstack -n "__fish_zkstack_using_subcommand explorer; and __fish_seen_subcommand_from run" -s h -l help -d 'Print help' +complete -c zkstack -n "__fish_zkstack_using_subcommand explorer; and __fish_seen_subcommand_from help" -f -a "init" -d 'Initialize explorer (create database to store explorer data and generate docker compose file with explorer services). Runs for all chains, unless --chain is passed' +complete -c zkstack -n "__fish_zkstack_using_subcommand explorer; and __fish_seen_subcommand_from help" -f -a "run-backend" -d 'Start explorer backend services (api, data_fetcher, worker) for a given chain. Uses default chain, unless --chain is passed' +complete -c zkstack -n "__fish_zkstack_using_subcommand explorer; and __fish_seen_subcommand_from help" -f -a "run" -d 'Run explorer app' +complete -c zkstack -n "__fish_zkstack_using_subcommand explorer; and __fish_seen_subcommand_from help" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' +complete -c zkstack -n "__fish_zkstack_using_subcommand consensus; and not __fish_seen_subcommand_from set-attester-committee get-attester-committee help" -l chain -d 'Chain to use' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand consensus; and not __fish_seen_subcommand_from set-attester-committee get-attester-committee help" -s v -l verbose -d 'Verbose mode' +complete -c zkstack -n "__fish_zkstack_using_subcommand consensus; and not __fish_seen_subcommand_from set-attester-committee get-attester-committee help" -l ignore-prerequisites -d 'Ignores prerequisites checks' +complete -c zkstack -n "__fish_zkstack_using_subcommand consensus; and not __fish_seen_subcommand_from set-attester-committee get-attester-committee help" -s h -l help -d 'Print help' +complete -c zkstack -n "__fish_zkstack_using_subcommand consensus; and not __fish_seen_subcommand_from set-attester-committee get-attester-committee help" -f -a "set-attester-committee" -d 'Sets the attester committee in the consensus registry contract to `consensus.genesis_spec.attesters` in general.yaml' +complete -c zkstack -n "__fish_zkstack_using_subcommand consensus; and not __fish_seen_subcommand_from set-attester-committee get-attester-committee help" -f -a "get-attester-committee" -d 'Fetches the attester committee from the consensus registry contract' +complete -c zkstack -n "__fish_zkstack_using_subcommand consensus; and not __fish_seen_subcommand_from set-attester-committee get-attester-committee help" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' +complete -c zkstack -n "__fish_zkstack_using_subcommand consensus; and __fish_seen_subcommand_from set-attester-committee" -l from-file -d 'Sets the attester committee in the consensus registry contract to the committee in the yaml file. File format is definied in `commands/consensus/proto/mod.proto`' -r -F +complete -c zkstack -n "__fish_zkstack_using_subcommand consensus; and __fish_seen_subcommand_from set-attester-committee" -l chain -d 'Chain to use' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand consensus; and __fish_seen_subcommand_from set-attester-committee" -l from-genesis -d 'Sets the attester committee in the consensus registry contract to `consensus.genesis_spec.attesters` in general.yaml' +complete -c zkstack -n "__fish_zkstack_using_subcommand consensus; and __fish_seen_subcommand_from set-attester-committee" -s v -l verbose -d 'Verbose mode' +complete -c zkstack -n "__fish_zkstack_using_subcommand consensus; and __fish_seen_subcommand_from set-attester-committee" -l ignore-prerequisites -d 'Ignores prerequisites checks' +complete -c zkstack -n "__fish_zkstack_using_subcommand consensus; and __fish_seen_subcommand_from set-attester-committee" -s h -l help -d 'Print help' +complete -c zkstack -n "__fish_zkstack_using_subcommand consensus; and __fish_seen_subcommand_from get-attester-committee" -l chain -d 'Chain to use' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand consensus; and __fish_seen_subcommand_from get-attester-committee" -s v -l verbose -d 'Verbose mode' +complete -c zkstack -n "__fish_zkstack_using_subcommand consensus; and __fish_seen_subcommand_from get-attester-committee" -l ignore-prerequisites -d 'Ignores prerequisites checks' +complete -c zkstack -n "__fish_zkstack_using_subcommand consensus; and __fish_seen_subcommand_from get-attester-committee" -s h -l help -d 'Print help' +complete -c zkstack -n "__fish_zkstack_using_subcommand consensus; and __fish_seen_subcommand_from help" -f -a "set-attester-committee" -d 'Sets the attester committee in the consensus registry contract to `consensus.genesis_spec.attesters` in general.yaml' +complete -c zkstack -n "__fish_zkstack_using_subcommand consensus; and __fish_seen_subcommand_from help" -f -a "get-attester-committee" -d 'Fetches the attester committee from the consensus registry contract' +complete -c zkstack -n "__fish_zkstack_using_subcommand consensus; and __fish_seen_subcommand_from help" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' +complete -c zkstack -n "__fish_zkstack_using_subcommand update" -l chain -d 'Chain to use' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand update" -s c -l only-config -d 'Update only the config files' +complete -c zkstack -n "__fish_zkstack_using_subcommand update" -s v -l verbose -d 'Verbose mode' +complete -c zkstack -n "__fish_zkstack_using_subcommand update" -l ignore-prerequisites -d 'Ignores prerequisites checks' +complete -c zkstack -n "__fish_zkstack_using_subcommand update" -s h -l help -d 'Print help' +complete -c zkstack -n "__fish_zkstack_using_subcommand markdown" -l chain -d 'Chain to use' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand markdown" -s v -l verbose -d 'Verbose mode' +complete -c zkstack -n "__fish_zkstack_using_subcommand markdown" -l ignore-prerequisites -d 'Ignores prerequisites checks' +complete -c zkstack -n "__fish_zkstack_using_subcommand markdown" -s h -l help -d 'Print help' +complete -c zkstack -n "__fish_zkstack_using_subcommand help; and not __fish_seen_subcommand_from autocomplete ecosystem chain dev prover server external-node containers contract-verifier portal explorer consensus update markdown help" -f -a "autocomplete" -d 'Create shell autocompletion files' +complete -c zkstack -n "__fish_zkstack_using_subcommand help; and not __fish_seen_subcommand_from autocomplete ecosystem chain dev prover server external-node containers contract-verifier portal explorer consensus update markdown help" -f -a "ecosystem" -d 'Ecosystem related commands' +complete -c zkstack -n "__fish_zkstack_using_subcommand help; and not __fish_seen_subcommand_from autocomplete ecosystem chain dev prover server external-node containers contract-verifier portal explorer consensus update markdown help" -f -a "chain" -d 'Chain related commands' +complete -c zkstack -n "__fish_zkstack_using_subcommand help; and not __fish_seen_subcommand_from autocomplete ecosystem chain dev prover server external-node containers contract-verifier portal explorer consensus update markdown help" -f -a "dev" -d 'Supervisor related commands' +complete -c zkstack -n "__fish_zkstack_using_subcommand help; and not __fish_seen_subcommand_from autocomplete ecosystem chain dev prover server external-node containers contract-verifier portal explorer consensus update markdown help" -f -a "prover" -d 'Prover related commands' +complete -c zkstack -n "__fish_zkstack_using_subcommand help; and not __fish_seen_subcommand_from autocomplete ecosystem chain dev prover server external-node containers contract-verifier portal explorer consensus update markdown help" -f -a "server" -d 'Run server' +complete -c zkstack -n "__fish_zkstack_using_subcommand help; and not __fish_seen_subcommand_from autocomplete ecosystem chain dev prover server external-node containers contract-verifier portal explorer consensus update markdown help" -f -a "external-node" -d 'External Node related commands' +complete -c zkstack -n "__fish_zkstack_using_subcommand help; and not __fish_seen_subcommand_from autocomplete ecosystem chain dev prover server external-node containers contract-verifier portal explorer consensus update markdown help" -f -a "containers" -d 'Run containers for local development' +complete -c zkstack -n "__fish_zkstack_using_subcommand help; and not __fish_seen_subcommand_from autocomplete ecosystem chain dev prover server external-node containers contract-verifier portal explorer consensus update markdown help" -f -a "contract-verifier" -d 'Run contract verifier' +complete -c zkstack -n "__fish_zkstack_using_subcommand help; and not __fish_seen_subcommand_from autocomplete ecosystem chain dev prover server external-node containers contract-verifier portal explorer consensus update markdown help" -f -a "portal" -d 'Run dapp-portal' +complete -c zkstack -n "__fish_zkstack_using_subcommand help; and not __fish_seen_subcommand_from autocomplete ecosystem chain dev prover server external-node containers contract-verifier portal explorer consensus update markdown help" -f -a "explorer" -d 'Run block-explorer' +complete -c zkstack -n "__fish_zkstack_using_subcommand help; and not __fish_seen_subcommand_from autocomplete ecosystem chain dev prover server external-node containers contract-verifier portal explorer consensus update markdown help" -f -a "consensus" -d 'Consensus utilities' +complete -c zkstack -n "__fish_zkstack_using_subcommand help; and not __fish_seen_subcommand_from autocomplete ecosystem chain dev prover server external-node containers contract-verifier portal explorer consensus update markdown help" -f -a "update" -d 'Update ZKsync' +complete -c zkstack -n "__fish_zkstack_using_subcommand help; and not __fish_seen_subcommand_from autocomplete ecosystem chain dev prover server external-node containers contract-verifier portal explorer consensus update markdown help" -f -a "markdown" -d 'Print markdown help' +complete -c zkstack -n "__fish_zkstack_using_subcommand help; and not __fish_seen_subcommand_from autocomplete ecosystem chain dev prover server external-node containers contract-verifier portal explorer consensus update markdown help" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' +complete -c zkstack -n "__fish_zkstack_using_subcommand help; and __fish_seen_subcommand_from ecosystem" -f -a "create" -d 'Create a new ecosystem and chain, setting necessary configurations for later initialization' +complete -c zkstack -n "__fish_zkstack_using_subcommand help; and __fish_seen_subcommand_from ecosystem" -f -a "build-transactions" -d 'Create transactions to build ecosystem contracts' +complete -c zkstack -n "__fish_zkstack_using_subcommand help; and __fish_seen_subcommand_from ecosystem" -f -a "init" -d 'Initialize ecosystem and chain, deploying necessary contracts and performing on-chain operations' +complete -c zkstack -n "__fish_zkstack_using_subcommand help; and __fish_seen_subcommand_from ecosystem" -f -a "change-default-chain" -d 'Change the default chain' +complete -c zkstack -n "__fish_zkstack_using_subcommand help; and __fish_seen_subcommand_from ecosystem" -f -a "setup-observability" -d 'Setup observability for the ecosystem, downloading Grafana dashboards from the era-observability repo' +complete -c zkstack -n "__fish_zkstack_using_subcommand help; and __fish_seen_subcommand_from chain" -f -a "create" -d 'Create a new chain, setting the necessary configurations for later initialization' +complete -c zkstack -n "__fish_zkstack_using_subcommand help; and __fish_seen_subcommand_from chain" -f -a "build-transactions" -d 'Create unsigned transactions for chain deployment' +complete -c zkstack -n "__fish_zkstack_using_subcommand help; and __fish_seen_subcommand_from chain" -f -a "init" -d 'Initialize chain, deploying necessary contracts and performing on-chain operations' +complete -c zkstack -n "__fish_zkstack_using_subcommand help; and __fish_seen_subcommand_from chain" -f -a "genesis" -d 'Run server genesis' +complete -c zkstack -n "__fish_zkstack_using_subcommand help; and __fish_seen_subcommand_from chain" -f -a "register-chain" -d 'Register a new chain on L1 (executed by L1 governor). This command deploys and configures Governance, ChainAdmin, and DiamondProxy contracts, registers chain with BridgeHub and sets pending admin for DiamondProxy. Note: After completion, L2 governor can accept ownership by running `accept-chain-ownership`' +complete -c zkstack -n "__fish_zkstack_using_subcommand help; and __fish_seen_subcommand_from chain" -f -a "deploy-l2-contracts" -d 'Deploy all L2 contracts (executed by L1 governor)' +complete -c zkstack -n "__fish_zkstack_using_subcommand help; and __fish_seen_subcommand_from chain" -f -a "accept-chain-ownership" -d 'Accept ownership of L2 chain (executed by L2 governor). This command should be run after `register-chain` to accept ownership of newly created DiamondProxy contract' +complete -c zkstack -n "__fish_zkstack_using_subcommand help; and __fish_seen_subcommand_from chain" -f -a "initialize-bridges" -d 'Initialize bridges on L2' +complete -c zkstack -n "__fish_zkstack_using_subcommand help; and __fish_seen_subcommand_from chain" -f -a "deploy-consensus-registry" -d 'Deploy L2 consensus registry' +complete -c zkstack -n "__fish_zkstack_using_subcommand help; and __fish_seen_subcommand_from chain" -f -a "deploy-multicall3" -d 'Deploy L2 multicall3' +complete -c zkstack -n "__fish_zkstack_using_subcommand help; and __fish_seen_subcommand_from chain" -f -a "deploy-upgrader" -d 'Deploy Default Upgrader' +complete -c zkstack -n "__fish_zkstack_using_subcommand help; and __fish_seen_subcommand_from chain" -f -a "deploy-paymaster" -d 'Deploy paymaster smart contract' +complete -c zkstack -n "__fish_zkstack_using_subcommand help; and __fish_seen_subcommand_from chain" -f -a "update-token-multiplier-setter" -d 'Update Token Multiplier Setter address on L1' +complete -c zkstack -n "__fish_zkstack_using_subcommand help; and __fish_seen_subcommand_from dev" -f -a "database" -d 'Database related commands' +complete -c zkstack -n "__fish_zkstack_using_subcommand help; and __fish_seen_subcommand_from dev" -f -a "test" -d 'Run tests' +complete -c zkstack -n "__fish_zkstack_using_subcommand help; and __fish_seen_subcommand_from dev" -f -a "clean" -d 'Clean artifacts' +complete -c zkstack -n "__fish_zkstack_using_subcommand help; and __fish_seen_subcommand_from dev" -f -a "snapshot" -d 'Snapshots creator' +complete -c zkstack -n "__fish_zkstack_using_subcommand help; and __fish_seen_subcommand_from dev" -f -a "lint" -d 'Lint code' +complete -c zkstack -n "__fish_zkstack_using_subcommand help; and __fish_seen_subcommand_from dev" -f -a "fmt" -d 'Format code' +complete -c zkstack -n "__fish_zkstack_using_subcommand help; and __fish_seen_subcommand_from dev" -f -a "prover" -d 'Protocol version used by provers' +complete -c zkstack -n "__fish_zkstack_using_subcommand help; and __fish_seen_subcommand_from dev" -f -a "contracts" -d 'Build contracts' +complete -c zkstack -n "__fish_zkstack_using_subcommand help; and __fish_seen_subcommand_from dev" -f -a "config-writer" -d 'Overwrite general config' +complete -c zkstack -n "__fish_zkstack_using_subcommand help; and __fish_seen_subcommand_from dev" -f -a "send-transactions" -d 'Send transactions from file' +complete -c zkstack -n "__fish_zkstack_using_subcommand help; and __fish_seen_subcommand_from dev" -f -a "status" -d 'Get status of the server' +complete -c zkstack -n "__fish_zkstack_using_subcommand help; and __fish_seen_subcommand_from dev" -f -a "generate-genesis" -d 'Generate new genesis file based on current contracts' +complete -c zkstack -n "__fish_zkstack_using_subcommand help; and __fish_seen_subcommand_from prover" -f -a "init" -d 'Initialize prover' +complete -c zkstack -n "__fish_zkstack_using_subcommand help; and __fish_seen_subcommand_from prover" -f -a "setup-keys" -d 'Generate setup keys' +complete -c zkstack -n "__fish_zkstack_using_subcommand help; and __fish_seen_subcommand_from prover" -f -a "run" -d 'Run prover' +complete -c zkstack -n "__fish_zkstack_using_subcommand help; and __fish_seen_subcommand_from prover" -f -a "init-bellman-cuda" -d 'Initialize bellman-cuda' +complete -c zkstack -n "__fish_zkstack_using_subcommand help; and __fish_seen_subcommand_from prover" -f -a "compressor-keys" -d 'Download compressor keys' +complete -c zkstack -n "__fish_zkstack_using_subcommand help; and __fish_seen_subcommand_from external-node" -f -a "configs" -d 'Prepare configs for EN' +complete -c zkstack -n "__fish_zkstack_using_subcommand help; and __fish_seen_subcommand_from external-node" -f -a "init" -d 'Init databases' +complete -c zkstack -n "__fish_zkstack_using_subcommand help; and __fish_seen_subcommand_from external-node" -f -a "run" -d 'Run external node' +complete -c zkstack -n "__fish_zkstack_using_subcommand help; and __fish_seen_subcommand_from contract-verifier" -f -a "run" -d 'Run contract verifier' +complete -c zkstack -n "__fish_zkstack_using_subcommand help; and __fish_seen_subcommand_from contract-verifier" -f -a "init" -d 'Download required binaries for contract verifier' +complete -c zkstack -n "__fish_zkstack_using_subcommand help; and __fish_seen_subcommand_from explorer" -f -a "init" -d 'Initialize explorer (create database to store explorer data and generate docker compose file with explorer services). Runs for all chains, unless --chain is passed' +complete -c zkstack -n "__fish_zkstack_using_subcommand help; and __fish_seen_subcommand_from explorer" -f -a "run-backend" -d 'Start explorer backend services (api, data_fetcher, worker) for a given chain. Uses default chain, unless --chain is passed' +complete -c zkstack -n "__fish_zkstack_using_subcommand help; and __fish_seen_subcommand_from explorer" -f -a "run" -d 'Run explorer app' +complete -c zkstack -n "__fish_zkstack_using_subcommand help; and __fish_seen_subcommand_from consensus" -f -a "set-attester-committee" -d 'Sets the attester committee in the consensus registry contract to `consensus.genesis_spec.attesters` in general.yaml' +complete -c zkstack -n "__fish_zkstack_using_subcommand help; and __fish_seen_subcommand_from consensus" -f -a "get-attester-committee" -d 'Fetches the attester committee from the consensus registry contract' diff --git a/zkstack_cli/crates/zkstack/completion/zkstack.sh b/zkstack_cli/crates/zkstack/completion/zkstack.sh new file mode 100644 index 000000000000..27639acd50be --- /dev/null +++ b/zkstack_cli/crates/zkstack/completion/zkstack.sh @@ -0,0 +1,6998 @@ +_zkstack() { + local i cur prev opts cmd + COMPREPLY=() + cur="${COMP_WORDS[COMP_CWORD]}" + prev="${COMP_WORDS[COMP_CWORD-1]}" + cmd="" + opts="" + + for i in ${COMP_WORDS[@]} + do + case "${cmd},${i}" in + ",$1") + cmd="zkstack" + ;; + zkstack,autocomplete) + cmd="zkstack__autocomplete" + ;; + zkstack,chain) + cmd="zkstack__chain" + ;; + zkstack,consensus) + cmd="zkstack__consensus" + ;; + zkstack,containers) + cmd="zkstack__containers" + ;; + zkstack,contract-verifier) + cmd="zkstack__contract__verifier" + ;; + zkstack,dev) + cmd="zkstack__dev" + ;; + zkstack,ecosystem) + cmd="zkstack__ecosystem" + ;; + zkstack,explorer) + cmd="zkstack__explorer" + ;; + zkstack,external-node) + cmd="zkstack__external__node" + ;; + zkstack,help) + cmd="zkstack__help" + ;; + zkstack,markdown) + cmd="zkstack__markdown" + ;; + zkstack,portal) + cmd="zkstack__portal" + ;; + zkstack,prover) + cmd="zkstack__prover" + ;; + zkstack,server) + cmd="zkstack__server" + ;; + zkstack,update) + cmd="zkstack__update" + ;; + zkstack__chain,accept-chain-ownership) + cmd="zkstack__chain__accept__chain__ownership" + ;; + zkstack__chain,build-transactions) + cmd="zkstack__chain__build__transactions" + ;; + zkstack__chain,create) + cmd="zkstack__chain__create" + ;; + zkstack__chain,deploy-consensus-registry) + cmd="zkstack__chain__deploy__consensus__registry" + ;; + zkstack__chain,deploy-l2-contracts) + cmd="zkstack__chain__deploy__l2__contracts" + ;; + zkstack__chain,deploy-multicall3) + cmd="zkstack__chain__deploy__multicall3" + ;; + zkstack__chain,deploy-paymaster) + cmd="zkstack__chain__deploy__paymaster" + ;; + zkstack__chain,deploy-upgrader) + cmd="zkstack__chain__deploy__upgrader" + ;; + zkstack__chain,genesis) + cmd="zkstack__chain__genesis" + ;; + zkstack__chain,help) + cmd="zkstack__chain__help" + ;; + zkstack__chain,init) + cmd="zkstack__chain__init" + ;; + zkstack__chain,initialize-bridges) + cmd="zkstack__chain__initialize__bridges" + ;; + zkstack__chain,register-chain) + cmd="zkstack__chain__register__chain" + ;; + zkstack__chain,update-token-multiplier-setter) + cmd="zkstack__chain__update__token__multiplier__setter" + ;; + zkstack__chain__genesis,help) + cmd="zkstack__chain__genesis__help" + ;; + zkstack__chain__genesis,init-database) + cmd="zkstack__chain__genesis__init__database" + ;; + zkstack__chain__genesis,server) + cmd="zkstack__chain__genesis__server" + ;; + zkstack__chain__genesis__help,help) + cmd="zkstack__chain__genesis__help__help" + ;; + zkstack__chain__genesis__help,init-database) + cmd="zkstack__chain__genesis__help__init__database" + ;; + zkstack__chain__genesis__help,server) + cmd="zkstack__chain__genesis__help__server" + ;; + zkstack__chain__help,accept-chain-ownership) + cmd="zkstack__chain__help__accept__chain__ownership" + ;; + zkstack__chain__help,build-transactions) + cmd="zkstack__chain__help__build__transactions" + ;; + zkstack__chain__help,create) + cmd="zkstack__chain__help__create" + ;; + zkstack__chain__help,deploy-consensus-registry) + cmd="zkstack__chain__help__deploy__consensus__registry" + ;; + zkstack__chain__help,deploy-l2-contracts) + cmd="zkstack__chain__help__deploy__l2__contracts" + ;; + zkstack__chain__help,deploy-multicall3) + cmd="zkstack__chain__help__deploy__multicall3" + ;; + zkstack__chain__help,deploy-paymaster) + cmd="zkstack__chain__help__deploy__paymaster" + ;; + zkstack__chain__help,deploy-upgrader) + cmd="zkstack__chain__help__deploy__upgrader" + ;; + zkstack__chain__help,genesis) + cmd="zkstack__chain__help__genesis" + ;; + zkstack__chain__help,help) + cmd="zkstack__chain__help__help" + ;; + zkstack__chain__help,init) + cmd="zkstack__chain__help__init" + ;; + zkstack__chain__help,initialize-bridges) + cmd="zkstack__chain__help__initialize__bridges" + ;; + zkstack__chain__help,register-chain) + cmd="zkstack__chain__help__register__chain" + ;; + zkstack__chain__help,update-token-multiplier-setter) + cmd="zkstack__chain__help__update__token__multiplier__setter" + ;; + zkstack__chain__help__genesis,init-database) + cmd="zkstack__chain__help__genesis__init__database" + ;; + zkstack__chain__help__genesis,server) + cmd="zkstack__chain__help__genesis__server" + ;; + zkstack__chain__help__init,configs) + cmd="zkstack__chain__help__init__configs" + ;; + zkstack__chain__init,configs) + cmd="zkstack__chain__init__configs" + ;; + zkstack__chain__init,help) + cmd="zkstack__chain__init__help" + ;; + zkstack__chain__init__help,configs) + cmd="zkstack__chain__init__help__configs" + ;; + zkstack__chain__init__help,help) + cmd="zkstack__chain__init__help__help" + ;; + zkstack__consensus,get-attester-committee) + cmd="zkstack__consensus__get__attester__committee" + ;; + zkstack__consensus,help) + cmd="zkstack__consensus__help" + ;; + zkstack__consensus,set-attester-committee) + cmd="zkstack__consensus__set__attester__committee" + ;; + zkstack__consensus__help,get-attester-committee) + cmd="zkstack__consensus__help__get__attester__committee" + ;; + zkstack__consensus__help,help) + cmd="zkstack__consensus__help__help" + ;; + zkstack__consensus__help,set-attester-committee) + cmd="zkstack__consensus__help__set__attester__committee" + ;; + zkstack__contract__verifier,help) + cmd="zkstack__contract__verifier__help" + ;; + zkstack__contract__verifier,init) + cmd="zkstack__contract__verifier__init" + ;; + zkstack__contract__verifier,run) + cmd="zkstack__contract__verifier__run" + ;; + zkstack__contract__verifier__help,help) + cmd="zkstack__contract__verifier__help__help" + ;; + zkstack__contract__verifier__help,init) + cmd="zkstack__contract__verifier__help__init" + ;; + zkstack__contract__verifier__help,run) + cmd="zkstack__contract__verifier__help__run" + ;; + zkstack__dev,clean) + cmd="zkstack__dev__clean" + ;; + zkstack__dev,config-writer) + cmd="zkstack__dev__config__writer" + ;; + zkstack__dev,contracts) + cmd="zkstack__dev__contracts" + ;; + zkstack__dev,database) + cmd="zkstack__dev__database" + ;; + zkstack__dev,fmt) + cmd="zkstack__dev__fmt" + ;; + zkstack__dev,generate-genesis) + cmd="zkstack__dev__generate__genesis" + ;; + zkstack__dev,help) + cmd="zkstack__dev__help" + ;; + zkstack__dev,lint) + cmd="zkstack__dev__lint" + ;; + zkstack__dev,prover) + cmd="zkstack__dev__prover" + ;; + zkstack__dev,send-transactions) + cmd="zkstack__dev__send__transactions" + ;; + zkstack__dev,snapshot) + cmd="zkstack__dev__snapshot" + ;; + zkstack__dev,status) + cmd="zkstack__dev__status" + ;; + zkstack__dev,test) + cmd="zkstack__dev__test" + ;; + zkstack__dev__clean,all) + cmd="zkstack__dev__clean__all" + ;; + zkstack__dev__clean,containers) + cmd="zkstack__dev__clean__containers" + ;; + zkstack__dev__clean,contracts-cache) + cmd="zkstack__dev__clean__contracts__cache" + ;; + zkstack__dev__clean,help) + cmd="zkstack__dev__clean__help" + ;; + zkstack__dev__clean__help,all) + cmd="zkstack__dev__clean__help__all" + ;; + zkstack__dev__clean__help,containers) + cmd="zkstack__dev__clean__help__containers" + ;; + zkstack__dev__clean__help,contracts-cache) + cmd="zkstack__dev__clean__help__contracts__cache" + ;; + zkstack__dev__clean__help,help) + cmd="zkstack__dev__clean__help__help" + ;; + zkstack__dev__database,check-sqlx-data) + cmd="zkstack__dev__database__check__sqlx__data" + ;; + zkstack__dev__database,drop) + cmd="zkstack__dev__database__drop" + ;; + zkstack__dev__database,help) + cmd="zkstack__dev__database__help" + ;; + zkstack__dev__database,migrate) + cmd="zkstack__dev__database__migrate" + ;; + zkstack__dev__database,new-migration) + cmd="zkstack__dev__database__new__migration" + ;; + zkstack__dev__database,prepare) + cmd="zkstack__dev__database__prepare" + ;; + zkstack__dev__database,reset) + cmd="zkstack__dev__database__reset" + ;; + zkstack__dev__database,setup) + cmd="zkstack__dev__database__setup" + ;; + zkstack__dev__database__help,check-sqlx-data) + cmd="zkstack__dev__database__help__check__sqlx__data" + ;; + zkstack__dev__database__help,drop) + cmd="zkstack__dev__database__help__drop" + ;; + zkstack__dev__database__help,help) + cmd="zkstack__dev__database__help__help" + ;; + zkstack__dev__database__help,migrate) + cmd="zkstack__dev__database__help__migrate" + ;; + zkstack__dev__database__help,new-migration) + cmd="zkstack__dev__database__help__new__migration" + ;; + zkstack__dev__database__help,prepare) + cmd="zkstack__dev__database__help__prepare" + ;; + zkstack__dev__database__help,reset) + cmd="zkstack__dev__database__help__reset" + ;; + zkstack__dev__database__help,setup) + cmd="zkstack__dev__database__help__setup" + ;; + zkstack__dev__fmt,contract) + cmd="zkstack__dev__fmt__contract" + ;; + zkstack__dev__fmt,help) + cmd="zkstack__dev__fmt__help" + ;; + zkstack__dev__fmt,prettier) + cmd="zkstack__dev__fmt__prettier" + ;; + zkstack__dev__fmt,rustfmt) + cmd="zkstack__dev__fmt__rustfmt" + ;; + zkstack__dev__fmt__help,contract) + cmd="zkstack__dev__fmt__help__contract" + ;; + zkstack__dev__fmt__help,help) + cmd="zkstack__dev__fmt__help__help" + ;; + zkstack__dev__fmt__help,prettier) + cmd="zkstack__dev__fmt__help__prettier" + ;; + zkstack__dev__fmt__help,rustfmt) + cmd="zkstack__dev__fmt__help__rustfmt" + ;; + zkstack__dev__help,clean) + cmd="zkstack__dev__help__clean" + ;; + zkstack__dev__help,config-writer) + cmd="zkstack__dev__help__config__writer" + ;; + zkstack__dev__help,contracts) + cmd="zkstack__dev__help__contracts" + ;; + zkstack__dev__help,database) + cmd="zkstack__dev__help__database" + ;; + zkstack__dev__help,fmt) + cmd="zkstack__dev__help__fmt" + ;; + zkstack__dev__help,generate-genesis) + cmd="zkstack__dev__help__generate__genesis" + ;; + zkstack__dev__help,help) + cmd="zkstack__dev__help__help" + ;; + zkstack__dev__help,lint) + cmd="zkstack__dev__help__lint" + ;; + zkstack__dev__help,prover) + cmd="zkstack__dev__help__prover" + ;; + zkstack__dev__help,send-transactions) + cmd="zkstack__dev__help__send__transactions" + ;; + zkstack__dev__help,snapshot) + cmd="zkstack__dev__help__snapshot" + ;; + zkstack__dev__help,status) + cmd="zkstack__dev__help__status" + ;; + zkstack__dev__help,test) + cmd="zkstack__dev__help__test" + ;; + zkstack__dev__help__clean,all) + cmd="zkstack__dev__help__clean__all" + ;; + zkstack__dev__help__clean,containers) + cmd="zkstack__dev__help__clean__containers" + ;; + zkstack__dev__help__clean,contracts-cache) + cmd="zkstack__dev__help__clean__contracts__cache" + ;; + zkstack__dev__help__database,check-sqlx-data) + cmd="zkstack__dev__help__database__check__sqlx__data" + ;; + zkstack__dev__help__database,drop) + cmd="zkstack__dev__help__database__drop" + ;; + zkstack__dev__help__database,migrate) + cmd="zkstack__dev__help__database__migrate" + ;; + zkstack__dev__help__database,new-migration) + cmd="zkstack__dev__help__database__new__migration" + ;; + zkstack__dev__help__database,prepare) + cmd="zkstack__dev__help__database__prepare" + ;; + zkstack__dev__help__database,reset) + cmd="zkstack__dev__help__database__reset" + ;; + zkstack__dev__help__database,setup) + cmd="zkstack__dev__help__database__setup" + ;; + zkstack__dev__help__fmt,contract) + cmd="zkstack__dev__help__fmt__contract" + ;; + zkstack__dev__help__fmt,prettier) + cmd="zkstack__dev__help__fmt__prettier" + ;; + zkstack__dev__help__fmt,rustfmt) + cmd="zkstack__dev__help__fmt__rustfmt" + ;; + zkstack__dev__help__prover,info) + cmd="zkstack__dev__help__prover__info" + ;; + zkstack__dev__help__prover,insert-batch) + cmd="zkstack__dev__help__prover__insert__batch" + ;; + zkstack__dev__help__prover,insert-version) + cmd="zkstack__dev__help__prover__insert__version" + ;; + zkstack__dev__help__snapshot,create) + cmd="zkstack__dev__help__snapshot__create" + ;; + zkstack__dev__help__status,ports) + cmd="zkstack__dev__help__status__ports" + ;; + zkstack__dev__help__test,build) + cmd="zkstack__dev__help__test__build" + ;; + zkstack__dev__help__test,fees) + cmd="zkstack__dev__help__test__fees" + ;; + zkstack__dev__help__test,integration) + cmd="zkstack__dev__help__test__integration" + ;; + zkstack__dev__help__test,l1-contracts) + cmd="zkstack__dev__help__test__l1__contracts" + ;; + zkstack__dev__help__test,loadtest) + cmd="zkstack__dev__help__test__loadtest" + ;; + zkstack__dev__help__test,prover) + cmd="zkstack__dev__help__test__prover" + ;; + zkstack__dev__help__test,recovery) + cmd="zkstack__dev__help__test__recovery" + ;; + zkstack__dev__help__test,revert) + cmd="zkstack__dev__help__test__revert" + ;; + zkstack__dev__help__test,rust) + cmd="zkstack__dev__help__test__rust" + ;; + zkstack__dev__help__test,upgrade) + cmd="zkstack__dev__help__test__upgrade" + ;; + zkstack__dev__help__test,wallet) + cmd="zkstack__dev__help__test__wallet" + ;; + zkstack__dev__prover,help) + cmd="zkstack__dev__prover__help" + ;; + zkstack__dev__prover,info) + cmd="zkstack__dev__prover__info" + ;; + zkstack__dev__prover,insert-batch) + cmd="zkstack__dev__prover__insert__batch" + ;; + zkstack__dev__prover,insert-version) + cmd="zkstack__dev__prover__insert__version" + ;; + zkstack__dev__prover__help,help) + cmd="zkstack__dev__prover__help__help" + ;; + zkstack__dev__prover__help,info) + cmd="zkstack__dev__prover__help__info" + ;; + zkstack__dev__prover__help,insert-batch) + cmd="zkstack__dev__prover__help__insert__batch" + ;; + zkstack__dev__prover__help,insert-version) + cmd="zkstack__dev__prover__help__insert__version" + ;; + zkstack__dev__snapshot,create) + cmd="zkstack__dev__snapshot__create" + ;; + zkstack__dev__snapshot,help) + cmd="zkstack__dev__snapshot__help" + ;; + zkstack__dev__snapshot__help,create) + cmd="zkstack__dev__snapshot__help__create" + ;; + zkstack__dev__snapshot__help,help) + cmd="zkstack__dev__snapshot__help__help" + ;; + zkstack__dev__status,help) + cmd="zkstack__dev__status__help" + ;; + zkstack__dev__status,ports) + cmd="zkstack__dev__status__ports" + ;; + zkstack__dev__status__help,help) + cmd="zkstack__dev__status__help__help" + ;; + zkstack__dev__status__help,ports) + cmd="zkstack__dev__status__help__ports" + ;; + zkstack__dev__test,build) + cmd="zkstack__dev__test__build" + ;; + zkstack__dev__test,fees) + cmd="zkstack__dev__test__fees" + ;; + zkstack__dev__test,help) + cmd="zkstack__dev__test__help" + ;; + zkstack__dev__test,integration) + cmd="zkstack__dev__test__integration" + ;; + zkstack__dev__test,l1-contracts) + cmd="zkstack__dev__test__l1__contracts" + ;; + zkstack__dev__test,loadtest) + cmd="zkstack__dev__test__loadtest" + ;; + zkstack__dev__test,prover) + cmd="zkstack__dev__test__prover" + ;; + zkstack__dev__test,recovery) + cmd="zkstack__dev__test__recovery" + ;; + zkstack__dev__test,revert) + cmd="zkstack__dev__test__revert" + ;; + zkstack__dev__test,rust) + cmd="zkstack__dev__test__rust" + ;; + zkstack__dev__test,upgrade) + cmd="zkstack__dev__test__upgrade" + ;; + zkstack__dev__test,wallet) + cmd="zkstack__dev__test__wallet" + ;; + zkstack__dev__test__help,build) + cmd="zkstack__dev__test__help__build" + ;; + zkstack__dev__test__help,fees) + cmd="zkstack__dev__test__help__fees" + ;; + zkstack__dev__test__help,help) + cmd="zkstack__dev__test__help__help" + ;; + zkstack__dev__test__help,integration) + cmd="zkstack__dev__test__help__integration" + ;; + zkstack__dev__test__help,l1-contracts) + cmd="zkstack__dev__test__help__l1__contracts" + ;; + zkstack__dev__test__help,loadtest) + cmd="zkstack__dev__test__help__loadtest" + ;; + zkstack__dev__test__help,prover) + cmd="zkstack__dev__test__help__prover" + ;; + zkstack__dev__test__help,recovery) + cmd="zkstack__dev__test__help__recovery" + ;; + zkstack__dev__test__help,revert) + cmd="zkstack__dev__test__help__revert" + ;; + zkstack__dev__test__help,rust) + cmd="zkstack__dev__test__help__rust" + ;; + zkstack__dev__test__help,upgrade) + cmd="zkstack__dev__test__help__upgrade" + ;; + zkstack__dev__test__help,wallet) + cmd="zkstack__dev__test__help__wallet" + ;; + zkstack__ecosystem,build-transactions) + cmd="zkstack__ecosystem__build__transactions" + ;; + zkstack__ecosystem,change-default-chain) + cmd="zkstack__ecosystem__change__default__chain" + ;; + zkstack__ecosystem,create) + cmd="zkstack__ecosystem__create" + ;; + zkstack__ecosystem,help) + cmd="zkstack__ecosystem__help" + ;; + zkstack__ecosystem,init) + cmd="zkstack__ecosystem__init" + ;; + zkstack__ecosystem,setup-observability) + cmd="zkstack__ecosystem__setup__observability" + ;; + zkstack__ecosystem__help,build-transactions) + cmd="zkstack__ecosystem__help__build__transactions" + ;; + zkstack__ecosystem__help,change-default-chain) + cmd="zkstack__ecosystem__help__change__default__chain" + ;; + zkstack__ecosystem__help,create) + cmd="zkstack__ecosystem__help__create" + ;; + zkstack__ecosystem__help,help) + cmd="zkstack__ecosystem__help__help" + ;; + zkstack__ecosystem__help,init) + cmd="zkstack__ecosystem__help__init" + ;; + zkstack__ecosystem__help,setup-observability) + cmd="zkstack__ecosystem__help__setup__observability" + ;; + zkstack__explorer,help) + cmd="zkstack__explorer__help" + ;; + zkstack__explorer,init) + cmd="zkstack__explorer__init" + ;; + zkstack__explorer,run) + cmd="zkstack__explorer__run" + ;; + zkstack__explorer,run-backend) + cmd="zkstack__explorer__run__backend" + ;; + zkstack__explorer__help,help) + cmd="zkstack__explorer__help__help" + ;; + zkstack__explorer__help,init) + cmd="zkstack__explorer__help__init" + ;; + zkstack__explorer__help,run) + cmd="zkstack__explorer__help__run" + ;; + zkstack__explorer__help,run-backend) + cmd="zkstack__explorer__help__run__backend" + ;; + zkstack__external__node,configs) + cmd="zkstack__external__node__configs" + ;; + zkstack__external__node,help) + cmd="zkstack__external__node__help" + ;; + zkstack__external__node,init) + cmd="zkstack__external__node__init" + ;; + zkstack__external__node,run) + cmd="zkstack__external__node__run" + ;; + zkstack__external__node__help,configs) + cmd="zkstack__external__node__help__configs" + ;; + zkstack__external__node__help,help) + cmd="zkstack__external__node__help__help" + ;; + zkstack__external__node__help,init) + cmd="zkstack__external__node__help__init" + ;; + zkstack__external__node__help,run) + cmd="zkstack__external__node__help__run" + ;; + zkstack__help,autocomplete) + cmd="zkstack__help__autocomplete" + ;; + zkstack__help,chain) + cmd="zkstack__help__chain" + ;; + zkstack__help,consensus) + cmd="zkstack__help__consensus" + ;; + zkstack__help,containers) + cmd="zkstack__help__containers" + ;; + zkstack__help,contract-verifier) + cmd="zkstack__help__contract__verifier" + ;; + zkstack__help,dev) + cmd="zkstack__help__dev" + ;; + zkstack__help,ecosystem) + cmd="zkstack__help__ecosystem" + ;; + zkstack__help,explorer) + cmd="zkstack__help__explorer" + ;; + zkstack__help,external-node) + cmd="zkstack__help__external__node" + ;; + zkstack__help,help) + cmd="zkstack__help__help" + ;; + zkstack__help,markdown) + cmd="zkstack__help__markdown" + ;; + zkstack__help,portal) + cmd="zkstack__help__portal" + ;; + zkstack__help,prover) + cmd="zkstack__help__prover" + ;; + zkstack__help,server) + cmd="zkstack__help__server" + ;; + zkstack__help,update) + cmd="zkstack__help__update" + ;; + zkstack__help__chain,accept-chain-ownership) + cmd="zkstack__help__chain__accept__chain__ownership" + ;; + zkstack__help__chain,build-transactions) + cmd="zkstack__help__chain__build__transactions" + ;; + zkstack__help__chain,create) + cmd="zkstack__help__chain__create" + ;; + zkstack__help__chain,deploy-consensus-registry) + cmd="zkstack__help__chain__deploy__consensus__registry" + ;; + zkstack__help__chain,deploy-l2-contracts) + cmd="zkstack__help__chain__deploy__l2__contracts" + ;; + zkstack__help__chain,deploy-multicall3) + cmd="zkstack__help__chain__deploy__multicall3" + ;; + zkstack__help__chain,deploy-paymaster) + cmd="zkstack__help__chain__deploy__paymaster" + ;; + zkstack__help__chain,deploy-upgrader) + cmd="zkstack__help__chain__deploy__upgrader" + ;; + zkstack__help__chain,genesis) + cmd="zkstack__help__chain__genesis" + ;; + zkstack__help__chain,init) + cmd="zkstack__help__chain__init" + ;; + zkstack__help__chain,initialize-bridges) + cmd="zkstack__help__chain__initialize__bridges" + ;; + zkstack__help__chain,register-chain) + cmd="zkstack__help__chain__register__chain" + ;; + zkstack__help__chain,update-token-multiplier-setter) + cmd="zkstack__help__chain__update__token__multiplier__setter" + ;; + zkstack__help__chain__genesis,init-database) + cmd="zkstack__help__chain__genesis__init__database" + ;; + zkstack__help__chain__genesis,server) + cmd="zkstack__help__chain__genesis__server" + ;; + zkstack__help__chain__init,configs) + cmd="zkstack__help__chain__init__configs" + ;; + zkstack__help__consensus,get-attester-committee) + cmd="zkstack__help__consensus__get__attester__committee" + ;; + zkstack__help__consensus,set-attester-committee) + cmd="zkstack__help__consensus__set__attester__committee" + ;; + zkstack__help__contract__verifier,init) + cmd="zkstack__help__contract__verifier__init" + ;; + zkstack__help__contract__verifier,run) + cmd="zkstack__help__contract__verifier__run" + ;; + zkstack__help__dev,clean) + cmd="zkstack__help__dev__clean" + ;; + zkstack__help__dev,config-writer) + cmd="zkstack__help__dev__config__writer" + ;; + zkstack__help__dev,contracts) + cmd="zkstack__help__dev__contracts" + ;; + zkstack__help__dev,database) + cmd="zkstack__help__dev__database" + ;; + zkstack__help__dev,fmt) + cmd="zkstack__help__dev__fmt" + ;; + zkstack__help__dev,generate-genesis) + cmd="zkstack__help__dev__generate__genesis" + ;; + zkstack__help__dev,lint) + cmd="zkstack__help__dev__lint" + ;; + zkstack__help__dev,prover) + cmd="zkstack__help__dev__prover" + ;; + zkstack__help__dev,send-transactions) + cmd="zkstack__help__dev__send__transactions" + ;; + zkstack__help__dev,snapshot) + cmd="zkstack__help__dev__snapshot" + ;; + zkstack__help__dev,status) + cmd="zkstack__help__dev__status" + ;; + zkstack__help__dev,test) + cmd="zkstack__help__dev__test" + ;; + zkstack__help__dev__clean,all) + cmd="zkstack__help__dev__clean__all" + ;; + zkstack__help__dev__clean,containers) + cmd="zkstack__help__dev__clean__containers" + ;; + zkstack__help__dev__clean,contracts-cache) + cmd="zkstack__help__dev__clean__contracts__cache" + ;; + zkstack__help__dev__database,check-sqlx-data) + cmd="zkstack__help__dev__database__check__sqlx__data" + ;; + zkstack__help__dev__database,drop) + cmd="zkstack__help__dev__database__drop" + ;; + zkstack__help__dev__database,migrate) + cmd="zkstack__help__dev__database__migrate" + ;; + zkstack__help__dev__database,new-migration) + cmd="zkstack__help__dev__database__new__migration" + ;; + zkstack__help__dev__database,prepare) + cmd="zkstack__help__dev__database__prepare" + ;; + zkstack__help__dev__database,reset) + cmd="zkstack__help__dev__database__reset" + ;; + zkstack__help__dev__database,setup) + cmd="zkstack__help__dev__database__setup" + ;; + zkstack__help__dev__fmt,contract) + cmd="zkstack__help__dev__fmt__contract" + ;; + zkstack__help__dev__fmt,prettier) + cmd="zkstack__help__dev__fmt__prettier" + ;; + zkstack__help__dev__fmt,rustfmt) + cmd="zkstack__help__dev__fmt__rustfmt" + ;; + zkstack__help__dev__prover,info) + cmd="zkstack__help__dev__prover__info" + ;; + zkstack__help__dev__prover,insert-batch) + cmd="zkstack__help__dev__prover__insert__batch" + ;; + zkstack__help__dev__prover,insert-version) + cmd="zkstack__help__dev__prover__insert__version" + ;; + zkstack__help__dev__snapshot,create) + cmd="zkstack__help__dev__snapshot__create" + ;; + zkstack__help__dev__status,ports) + cmd="zkstack__help__dev__status__ports" + ;; + zkstack__help__dev__test,build) + cmd="zkstack__help__dev__test__build" + ;; + zkstack__help__dev__test,fees) + cmd="zkstack__help__dev__test__fees" + ;; + zkstack__help__dev__test,integration) + cmd="zkstack__help__dev__test__integration" + ;; + zkstack__help__dev__test,l1-contracts) + cmd="zkstack__help__dev__test__l1__contracts" + ;; + zkstack__help__dev__test,loadtest) + cmd="zkstack__help__dev__test__loadtest" + ;; + zkstack__help__dev__test,prover) + cmd="zkstack__help__dev__test__prover" + ;; + zkstack__help__dev__test,recovery) + cmd="zkstack__help__dev__test__recovery" + ;; + zkstack__help__dev__test,revert) + cmd="zkstack__help__dev__test__revert" + ;; + zkstack__help__dev__test,rust) + cmd="zkstack__help__dev__test__rust" + ;; + zkstack__help__dev__test,upgrade) + cmd="zkstack__help__dev__test__upgrade" + ;; + zkstack__help__dev__test,wallet) + cmd="zkstack__help__dev__test__wallet" + ;; + zkstack__help__ecosystem,build-transactions) + cmd="zkstack__help__ecosystem__build__transactions" + ;; + zkstack__help__ecosystem,change-default-chain) + cmd="zkstack__help__ecosystem__change__default__chain" + ;; + zkstack__help__ecosystem,create) + cmd="zkstack__help__ecosystem__create" + ;; + zkstack__help__ecosystem,init) + cmd="zkstack__help__ecosystem__init" + ;; + zkstack__help__ecosystem,setup-observability) + cmd="zkstack__help__ecosystem__setup__observability" + ;; + zkstack__help__explorer,init) + cmd="zkstack__help__explorer__init" + ;; + zkstack__help__explorer,run) + cmd="zkstack__help__explorer__run" + ;; + zkstack__help__explorer,run-backend) + cmd="zkstack__help__explorer__run__backend" + ;; + zkstack__help__external__node,configs) + cmd="zkstack__help__external__node__configs" + ;; + zkstack__help__external__node,init) + cmd="zkstack__help__external__node__init" + ;; + zkstack__help__external__node,run) + cmd="zkstack__help__external__node__run" + ;; + zkstack__help__prover,compressor-keys) + cmd="zkstack__help__prover__compressor__keys" + ;; + zkstack__help__prover,init) + cmd="zkstack__help__prover__init" + ;; + zkstack__help__prover,init-bellman-cuda) + cmd="zkstack__help__prover__init__bellman__cuda" + ;; + zkstack__help__prover,run) + cmd="zkstack__help__prover__run" + ;; + zkstack__help__prover,setup-keys) + cmd="zkstack__help__prover__setup__keys" + ;; + zkstack__prover,compressor-keys) + cmd="zkstack__prover__compressor__keys" + ;; + zkstack__prover,help) + cmd="zkstack__prover__help" + ;; + zkstack__prover,init) + cmd="zkstack__prover__init" + ;; + zkstack__prover,init-bellman-cuda) + cmd="zkstack__prover__init__bellman__cuda" + ;; + zkstack__prover,run) + cmd="zkstack__prover__run" + ;; + zkstack__prover,setup-keys) + cmd="zkstack__prover__setup__keys" + ;; + zkstack__prover__help,compressor-keys) + cmd="zkstack__prover__help__compressor__keys" + ;; + zkstack__prover__help,help) + cmd="zkstack__prover__help__help" + ;; + zkstack__prover__help,init) + cmd="zkstack__prover__help__init" + ;; + zkstack__prover__help,init-bellman-cuda) + cmd="zkstack__prover__help__init__bellman__cuda" + ;; + zkstack__prover__help,run) + cmd="zkstack__prover__help__run" + ;; + zkstack__prover__help,setup-keys) + cmd="zkstack__prover__help__setup__keys" + ;; + *) + ;; + esac + done + + case "${cmd}" in + zkstack) + opts="-v -h -V --verbose --chain --ignore-prerequisites --help --version autocomplete ecosystem chain dev prover server external-node containers contract-verifier portal explorer consensus update markdown help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__autocomplete) + opts="-o -v -h --generate --out --verbose --chain --ignore-prerequisites --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --generate) + COMPREPLY=($(compgen -W "bash elvish fish powershell zsh" -- "${cur}")) + return 0 + ;; + --out) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + -o) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__chain) + opts="-v -h --verbose --chain --ignore-prerequisites --help create build-transactions init genesis register-chain deploy-l2-contracts accept-chain-ownership initialize-bridges deploy-consensus-registry deploy-multicall3 deploy-upgrader deploy-paymaster update-token-multiplier-setter help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__chain__accept__chain__ownership) + opts="-a -v -h --verify --verifier --verifier-url --verifier-api-key --resume --additional-args --verbose --chain --ignore-prerequisites --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --verify) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; + --verifier) + COMPREPLY=($(compgen -W "etherscan sourcify blockscout oklink" -- "${cur}")) + return 0 + ;; + --verifier-url) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --verifier-api-key) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --additional-args) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + -a) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__chain__build__transactions) + opts="-o -a -v -h --out --verify --verifier --verifier-url --verifier-api-key --resume --additional-args --l1-rpc-url --verbose --chain --ignore-prerequisites --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --out) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + -o) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --verify) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; + --verifier) + COMPREPLY=($(compgen -W "etherscan sourcify blockscout oklink" -- "${cur}")) + return 0 + ;; + --verifier-url) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --verifier-api-key) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --additional-args) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + -a) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --l1-rpc-url) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__chain__create) + opts="-v -h --chain-name --chain-id --prover-mode --wallet-creation --wallet-path --l1-batch-commit-data-generator-mode --base-token-address --base-token-price-nominator --base-token-price-denominator --set-as-default --legacy-bridge --verbose --chain --ignore-prerequisites --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --chain-name) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --chain-id) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --prover-mode) + COMPREPLY=($(compgen -W "no-proofs gpu" -- "${cur}")) + return 0 + ;; + --wallet-creation) + COMPREPLY=($(compgen -W "localhost random empty in-file" -- "${cur}")) + return 0 + ;; + --wallet-path) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' + COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi + return 0 + ;; + --l1-batch-commit-data-generator-mode) + COMPREPLY=($(compgen -W "rollup validium" -- "${cur}")) + return 0 + ;; + --base-token-address) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --base-token-price-nominator) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --base-token-price-denominator) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --set-as-default) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__chain__deploy__consensus__registry) + opts="-a -v -h --verify --verifier --verifier-url --verifier-api-key --resume --additional-args --verbose --chain --ignore-prerequisites --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --verify) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; + --verifier) + COMPREPLY=($(compgen -W "etherscan sourcify blockscout oklink" -- "${cur}")) + return 0 + ;; + --verifier-url) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --verifier-api-key) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --additional-args) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + -a) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__chain__deploy__l2__contracts) + opts="-a -v -h --verify --verifier --verifier-url --verifier-api-key --resume --additional-args --verbose --chain --ignore-prerequisites --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --verify) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; + --verifier) + COMPREPLY=($(compgen -W "etherscan sourcify blockscout oklink" -- "${cur}")) + return 0 + ;; + --verifier-url) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --verifier-api-key) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --additional-args) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + -a) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__chain__deploy__multicall3) + opts="-a -v -h --verify --verifier --verifier-url --verifier-api-key --resume --additional-args --verbose --chain --ignore-prerequisites --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --verify) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; + --verifier) + COMPREPLY=($(compgen -W "etherscan sourcify blockscout oklink" -- "${cur}")) + return 0 + ;; + --verifier-url) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --verifier-api-key) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --additional-args) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + -a) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__chain__deploy__paymaster) + opts="-a -v -h --verify --verifier --verifier-url --verifier-api-key --resume --additional-args --verbose --chain --ignore-prerequisites --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --verify) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; + --verifier) + COMPREPLY=($(compgen -W "etherscan sourcify blockscout oklink" -- "${cur}")) + return 0 + ;; + --verifier-url) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --verifier-api-key) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --additional-args) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + -a) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__chain__deploy__upgrader) + opts="-a -v -h --verify --verifier --verifier-url --verifier-api-key --resume --additional-args --verbose --chain --ignore-prerequisites --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --verify) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; + --verifier) + COMPREPLY=($(compgen -W "etherscan sourcify blockscout oklink" -- "${cur}")) + return 0 + ;; + --verifier-url) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --verifier-api-key) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --additional-args) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + -a) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__chain__genesis) + opts="-u -d -v -h --server-db-url --server-db-name --use-default --dont-drop --verbose --chain --ignore-prerequisites --help init-database server help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --server-db-url) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --server-db-name) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__chain__genesis__help) + opts="init-database server help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__chain__genesis__help__help) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__chain__genesis__help__init__database) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__chain__genesis__help__server) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__chain__genesis__init__database) + opts="-u -d -v -h --server-db-url --server-db-name --use-default --dont-drop --verbose --chain --ignore-prerequisites --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --server-db-url) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --server-db-name) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__chain__genesis__server) + opts="-v -h --verbose --chain --ignore-prerequisites --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__chain__help) + opts="create build-transactions init genesis register-chain deploy-l2-contracts accept-chain-ownership initialize-bridges deploy-consensus-registry deploy-multicall3 deploy-upgrader deploy-paymaster update-token-multiplier-setter help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__chain__help__accept__chain__ownership) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__chain__help__build__transactions) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__chain__help__create) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__chain__help__deploy__consensus__registry) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__chain__help__deploy__l2__contracts) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__chain__help__deploy__multicall3) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__chain__help__deploy__paymaster) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__chain__help__deploy__upgrader) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__chain__help__genesis) + opts="init-database server" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__chain__help__genesis__init__database) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__chain__help__genesis__server) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__chain__help__help) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__chain__help__init) + opts="configs" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__chain__help__init__configs) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__chain__help__initialize__bridges) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__chain__help__register__chain) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__chain__help__update__token__multiplier__setter) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__chain__init) + opts="-a -u -d -v -h --verify --verifier --verifier-url --verifier-api-key --resume --additional-args --server-db-url --server-db-name --use-default --dont-drop --deploy-paymaster --l1-rpc-url --no-port-reallocation --verbose --chain --ignore-prerequisites --help configs help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --verify) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; + --verifier) + COMPREPLY=($(compgen -W "etherscan sourcify blockscout oklink" -- "${cur}")) + return 0 + ;; + --verifier-url) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --verifier-api-key) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --additional-args) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + -a) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --server-db-url) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --server-db-name) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --deploy-paymaster) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; + --l1-rpc-url) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__chain__init__configs) + opts="-u -d -v -h --server-db-url --server-db-name --use-default --dont-drop --l1-rpc-url --no-port-reallocation --verbose --chain --ignore-prerequisites --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --server-db-url) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --server-db-name) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --l1-rpc-url) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__chain__init__help) + opts="configs help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__chain__init__help__configs) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__chain__init__help__help) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__chain__initialize__bridges) + opts="-a -v -h --verify --verifier --verifier-url --verifier-api-key --resume --additional-args --verbose --chain --ignore-prerequisites --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --verify) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; + --verifier) + COMPREPLY=($(compgen -W "etherscan sourcify blockscout oklink" -- "${cur}")) + return 0 + ;; + --verifier-url) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --verifier-api-key) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --additional-args) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + -a) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__chain__register__chain) + opts="-a -v -h --verify --verifier --verifier-url --verifier-api-key --resume --additional-args --verbose --chain --ignore-prerequisites --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --verify) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; + --verifier) + COMPREPLY=($(compgen -W "etherscan sourcify blockscout oklink" -- "${cur}")) + return 0 + ;; + --verifier-url) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --verifier-api-key) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --additional-args) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + -a) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__chain__update__token__multiplier__setter) + opts="-a -v -h --verify --verifier --verifier-url --verifier-api-key --resume --additional-args --verbose --chain --ignore-prerequisites --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --verify) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; + --verifier) + COMPREPLY=($(compgen -W "etherscan sourcify blockscout oklink" -- "${cur}")) + return 0 + ;; + --verifier-url) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --verifier-api-key) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --additional-args) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + -a) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__consensus) + opts="-v -h --verbose --chain --ignore-prerequisites --help set-attester-committee get-attester-committee help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__consensus__get__attester__committee) + opts="-v -h --verbose --chain --ignore-prerequisites --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__consensus__help) + opts="set-attester-committee get-attester-committee help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__consensus__help__get__attester__committee) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__consensus__help__help) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__consensus__help__set__attester__committee) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__consensus__set__attester__committee) + opts="-v -h --from-genesis --from-file --verbose --chain --ignore-prerequisites --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --from-file) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__containers) + opts="-o -v -h --observability --verbose --chain --ignore-prerequisites --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --observability) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; + -o) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__contract__verifier) + opts="-v -h --verbose --chain --ignore-prerequisites --help run init help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__contract__verifier__help) + opts="run init help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__contract__verifier__help__help) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__contract__verifier__help__init) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__contract__verifier__help__run) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__contract__verifier__init) + opts="-v -h --zksolc-version --zkvyper-version --solc-version --era-vm-solc-version --vyper-version --only --verbose --chain --ignore-prerequisites --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --zksolc-version) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --zkvyper-version) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --solc-version) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --era-vm-solc-version) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --vyper-version) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__contract__verifier__run) + opts="-v -h --verbose --chain --ignore-prerequisites --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev) + opts="-v -h --verbose --chain --ignore-prerequisites --help database test clean snapshot lint fmt prover contracts config-writer send-transactions status generate-genesis help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__clean) + opts="-v -h --verbose --chain --ignore-prerequisites --help all containers contracts-cache help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__clean__all) + opts="-v -h --verbose --chain --ignore-prerequisites --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__clean__containers) + opts="-v -h --verbose --chain --ignore-prerequisites --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__clean__contracts__cache) + opts="-v -h --verbose --chain --ignore-prerequisites --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__clean__help) + opts="all containers contracts-cache help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__clean__help__all) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__clean__help__containers) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__clean__help__contracts__cache) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__clean__help__help) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__config__writer) + opts="-p -v -h --path --verbose --chain --ignore-prerequisites --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --path) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + -p) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__contracts) + opts="-v -h --l1-contracts --l2-contracts --system-contracts --test-contracts --verbose --chain --ignore-prerequisites --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --l1-contracts) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; + --l2-contracts) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; + --system-contracts) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; + --test-contracts) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__database) + opts="-v -h --verbose --chain --ignore-prerequisites --help check-sqlx-data drop migrate new-migration prepare reset setup help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__database__check__sqlx__data) + opts="-p -c -v -h --prover --prover-url --core --core-url --verbose --chain --ignore-prerequisites --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --prover) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; + -p) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; + --prover-url) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --core) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; + -c) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; + --core-url) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__database__drop) + opts="-p -c -v -h --prover --prover-url --core --core-url --verbose --chain --ignore-prerequisites --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --prover) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; + -p) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; + --prover-url) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --core) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; + -c) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; + --core-url) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__database__help) + opts="check-sqlx-data drop migrate new-migration prepare reset setup help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__database__help__check__sqlx__data) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__database__help__drop) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__database__help__help) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__database__help__migrate) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__database__help__new__migration) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__database__help__prepare) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__database__help__reset) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__database__help__setup) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__database__migrate) + opts="-p -c -v -h --prover --prover-url --core --core-url --verbose --chain --ignore-prerequisites --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --prover) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; + -p) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; + --prover-url) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --core) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; + -c) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; + --core-url) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__database__new__migration) + opts="-v -h --database --name --verbose --chain --ignore-prerequisites --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --database) + COMPREPLY=($(compgen -W "prover core" -- "${cur}")) + return 0 + ;; + --name) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__database__prepare) + opts="-p -c -v -h --prover --prover-url --core --core-url --verbose --chain --ignore-prerequisites --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --prover) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; + -p) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; + --prover-url) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --core) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; + -c) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; + --core-url) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__database__reset) + opts="-p -c -v -h --prover --prover-url --core --core-url --verbose --chain --ignore-prerequisites --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --prover) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; + -p) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; + --prover-url) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --core) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; + -c) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; + --core-url) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__database__setup) + opts="-p -c -v -h --prover --prover-url --core --core-url --verbose --chain --ignore-prerequisites --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --prover) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; + -p) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; + --prover-url) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --core) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; + -c) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; + --core-url) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__fmt) + opts="-c -v -h --check --verbose --chain --ignore-prerequisites --help rustfmt contract prettier help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__fmt__contract) + opts="-v -h --verbose --chain --ignore-prerequisites --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__fmt__help) + opts="rustfmt contract prettier help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__fmt__help__contract) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__fmt__help__help) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__fmt__help__prettier) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__fmt__help__rustfmt) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__fmt__prettier) + opts="-t -v -h --targets --verbose --chain --ignore-prerequisites --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --targets) + COMPREPLY=($(compgen -W "md sol js ts rs contracts autocompletion" -- "${cur}")) + return 0 + ;; + -t) + COMPREPLY=($(compgen -W "md sol js ts rs contracts autocompletion" -- "${cur}")) + return 0 + ;; + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__fmt__rustfmt) + opts="-v -h --verbose --chain --ignore-prerequisites --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__generate__genesis) + opts="-v -h --verbose --chain --ignore-prerequisites --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__help) + opts="database test clean snapshot lint fmt prover contracts config-writer send-transactions status generate-genesis help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__help__clean) + opts="all containers contracts-cache" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__help__clean__all) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__help__clean__containers) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__help__clean__contracts__cache) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__help__config__writer) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__help__contracts) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__help__database) + opts="check-sqlx-data drop migrate new-migration prepare reset setup" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__help__database__check__sqlx__data) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__help__database__drop) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__help__database__migrate) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__help__database__new__migration) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__help__database__prepare) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__help__database__reset) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__help__database__setup) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__help__fmt) + opts="rustfmt contract prettier" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__help__fmt__contract) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__help__fmt__prettier) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__help__fmt__rustfmt) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__help__generate__genesis) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__help__help) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__help__lint) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__help__prover) + opts="info insert-batch insert-version" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__help__prover__info) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__help__prover__insert__batch) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__help__prover__insert__version) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__help__send__transactions) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__help__snapshot) + opts="create" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__help__snapshot__create) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__help__status) + opts="ports" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__help__status__ports) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__help__test) + opts="integration fees revert recovery upgrade build rust l1-contracts prover wallet loadtest" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__help__test__build) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__help__test__fees) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__help__test__integration) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__help__test__l1__contracts) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__help__test__loadtest) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__help__test__prover) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__help__test__recovery) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__help__test__revert) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__help__test__rust) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__help__test__upgrade) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__help__test__wallet) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__lint) + opts="-c -t -v -h --check --targets --verbose --chain --ignore-prerequisites --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --targets) + COMPREPLY=($(compgen -W "md sol js ts rs contracts autocompletion" -- "${cur}")) + return 0 + ;; + -t) + COMPREPLY=($(compgen -W "md sol js ts rs contracts autocompletion" -- "${cur}")) + return 0 + ;; + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__prover) + opts="-v -h --verbose --chain --ignore-prerequisites --help info insert-batch insert-version help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__prover__help) + opts="info insert-batch insert-version help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__prover__help__help) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__prover__help__info) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__prover__help__insert__batch) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__prover__help__insert__version) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__prover__info) + opts="-v -h --verbose --chain --ignore-prerequisites --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__prover__insert__batch) + opts="-v -h --number --default --version --verbose --chain --ignore-prerequisites --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --number) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --version) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__prover__insert__version) + opts="-v -h --default --version --snark-wrapper --verbose --chain --ignore-prerequisites --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --version) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --snark-wrapper) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__send__transactions) + opts="-v -h --file --private-key --l1-rpc-url --confirmations --verbose --chain --ignore-prerequisites --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --file) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --private-key) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --l1-rpc-url) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --confirmations) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__snapshot) + opts="-v -h --verbose --chain --ignore-prerequisites --help create help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__snapshot__create) + opts="-v -h --verbose --chain --ignore-prerequisites --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__snapshot__help) + opts="create help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__snapshot__help__create) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__snapshot__help__help) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__status) + opts="-u -v -h --url --verbose --chain --ignore-prerequisites --help ports help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --url) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + -u) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__status__help) + opts="ports help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__status__help__help) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__status__help__ports) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__status__ports) + opts="-v -h --verbose --chain --ignore-prerequisites --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__test) + opts="-v -h --verbose --chain --ignore-prerequisites --help integration fees revert recovery upgrade build rust l1-contracts prover wallet loadtest help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__test__build) + opts="-v -h --verbose --chain --ignore-prerequisites --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__test__fees) + opts="-n -v -h --no-deps --no-kill --verbose --chain --ignore-prerequisites --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__test__help) + opts="integration fees revert recovery upgrade build rust l1-contracts prover wallet loadtest help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__test__help__build) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__test__help__fees) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__test__help__help) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__test__help__integration) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__test__help__l1__contracts) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__test__help__loadtest) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__test__help__prover) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__test__help__recovery) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__test__help__revert) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__test__help__rust) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__test__help__upgrade) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__test__help__wallet) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__test__integration) + opts="-e -n -t -v -h --external-node --no-deps --test-pattern --verbose --chain --ignore-prerequisites --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --test-pattern) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + -t) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__test__l1__contracts) + opts="-v -h --verbose --chain --ignore-prerequisites --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__test__loadtest) + opts="-v -h --verbose --chain --ignore-prerequisites --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__test__prover) + opts="-v -h --verbose --chain --ignore-prerequisites --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__test__recovery) + opts="-s -n -v -h --snapshot --no-deps --no-kill --verbose --chain --ignore-prerequisites --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__test__revert) + opts="-e -n -v -h --enable-consensus --external-node --no-deps --no-kill --verbose --chain --ignore-prerequisites --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__test__rust) + opts="-v -h --options --verbose --chain --ignore-prerequisites --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --options) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__test__upgrade) + opts="-n -v -h --no-deps --verbose --chain --ignore-prerequisites --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__dev__test__wallet) + opts="-v -h --verbose --chain --ignore-prerequisites --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__ecosystem) + opts="-v -h --verbose --chain --ignore-prerequisites --help create build-transactions init change-default-chain setup-observability help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__ecosystem__build__transactions) + opts="-o -a -v -h --sender --l1-rpc-url --out --verify --verifier --verifier-url --verifier-api-key --resume --additional-args --verbose --chain --ignore-prerequisites --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --sender) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --l1-rpc-url) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --out) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + -o) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --verify) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; + --verifier) + COMPREPLY=($(compgen -W "etherscan sourcify blockscout oklink" -- "${cur}")) + return 0 + ;; + --verifier-url) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --verifier-api-key) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --additional-args) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + -a) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__ecosystem__change__default__chain) + opts="-v -h --verbose --chain --ignore-prerequisites --help [NAME]" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__ecosystem__create) + opts="-v -h --ecosystem-name --l1-network --link-to-code --chain-name --chain-id --prover-mode --wallet-creation --wallet-path --l1-batch-commit-data-generator-mode --base-token-address --base-token-price-nominator --base-token-price-denominator --set-as-default --legacy-bridge --start-containers --verbose --chain --ignore-prerequisites --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --ecosystem-name) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --l1-network) + COMPREPLY=($(compgen -W "localhost sepolia holesky mainnet" -- "${cur}")) + return 0 + ;; + --link-to-code) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi + return 0 + ;; + --chain-name) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --chain-id) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --prover-mode) + COMPREPLY=($(compgen -W "no-proofs gpu" -- "${cur}")) + return 0 + ;; + --wallet-creation) + COMPREPLY=($(compgen -W "localhost random empty in-file" -- "${cur}")) + return 0 + ;; + --wallet-path) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' + COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi + return 0 + ;; + --l1-batch-commit-data-generator-mode) + COMPREPLY=($(compgen -W "rollup validium" -- "${cur}")) + return 0 + ;; + --base-token-address) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --base-token-price-nominator) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --base-token-price-denominator) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --set-as-default) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; + --start-containers) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__ecosystem__help) + opts="create build-transactions init change-default-chain setup-observability help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__ecosystem__help__build__transactions) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__ecosystem__help__change__default__chain) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__ecosystem__help__create) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__ecosystem__help__help) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__ecosystem__help__init) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__ecosystem__help__setup__observability) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__ecosystem__init) + opts="-a -u -d -o -v -h --deploy-erc20 --deploy-ecosystem --ecosystem-contracts-path --l1-rpc-url --verify --verifier --verifier-url --verifier-api-key --resume --additional-args --deploy-paymaster --server-db-url --server-db-name --use-default --dont-drop --ecosystem-only --dev --observability --no-port-reallocation --verbose --chain --ignore-prerequisites --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --deploy-erc20) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; + --deploy-ecosystem) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; + --ecosystem-contracts-path) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --l1-rpc-url) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --verify) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; + --verifier) + COMPREPLY=($(compgen -W "etherscan sourcify blockscout oklink" -- "${cur}")) + return 0 + ;; + --verifier-url) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --verifier-api-key) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --additional-args) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + -a) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --deploy-paymaster) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; + --server-db-url) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --server-db-name) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --observability) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; + -o) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__ecosystem__setup__observability) + opts="-v -h --verbose --chain --ignore-prerequisites --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__explorer) + opts="-v -h --verbose --chain --ignore-prerequisites --help init run-backend run help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__explorer__help) + opts="init run-backend run help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__explorer__help__help) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__explorer__help__init) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__explorer__help__run) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__explorer__help__run__backend) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__explorer__init) + opts="-v -h --verbose --chain --ignore-prerequisites --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__explorer__run) + opts="-v -h --verbose --chain --ignore-prerequisites --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__explorer__run__backend) + opts="-v -h --verbose --chain --ignore-prerequisites --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__external__node) + opts="-v -h --verbose --chain --ignore-prerequisites --help configs init run help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__external__node__configs) + opts="-u -v -h --db-url --db-name --l1-rpc-url --use-default --verbose --chain --ignore-prerequisites --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --db-url) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --db-name) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --l1-rpc-url) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__external__node__help) + opts="configs init run help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__external__node__help__configs) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__external__node__help__help) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__external__node__help__init) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__external__node__help__run) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__external__node__init) + opts="-v -h --verbose --chain --ignore-prerequisites --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__external__node__run) + opts="-a -v -h --reinit --components --enable-consensus --additional-args --verbose --chain --ignore-prerequisites --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --components) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --enable-consensus) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; + --additional-args) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + -a) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help) + opts="autocomplete ecosystem chain dev prover server external-node containers contract-verifier portal explorer consensus update markdown help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__autocomplete) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__chain) + opts="create build-transactions init genesis register-chain deploy-l2-contracts accept-chain-ownership initialize-bridges deploy-consensus-registry deploy-multicall3 deploy-upgrader deploy-paymaster update-token-multiplier-setter" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__chain__accept__chain__ownership) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__chain__build__transactions) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__chain__create) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__chain__deploy__consensus__registry) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__chain__deploy__l2__contracts) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__chain__deploy__multicall3) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__chain__deploy__paymaster) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__chain__deploy__upgrader) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__chain__genesis) + opts="init-database server" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__chain__genesis__init__database) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__chain__genesis__server) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__chain__init) + opts="configs" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__chain__init__configs) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__chain__initialize__bridges) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__chain__register__chain) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__chain__update__token__multiplier__setter) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__consensus) + opts="set-attester-committee get-attester-committee" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__consensus__get__attester__committee) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__consensus__set__attester__committee) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__containers) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__contract__verifier) + opts="run init" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__contract__verifier__init) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__contract__verifier__run) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__dev) + opts="database test clean snapshot lint fmt prover contracts config-writer send-transactions status generate-genesis" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__dev__clean) + opts="all containers contracts-cache" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__dev__clean__all) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__dev__clean__containers) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__dev__clean__contracts__cache) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__dev__config__writer) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__dev__contracts) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__dev__database) + opts="check-sqlx-data drop migrate new-migration prepare reset setup" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__dev__database__check__sqlx__data) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__dev__database__drop) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__dev__database__migrate) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__dev__database__new__migration) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__dev__database__prepare) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__dev__database__reset) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__dev__database__setup) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__dev__fmt) + opts="rustfmt contract prettier" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__dev__fmt__contract) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__dev__fmt__prettier) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__dev__fmt__rustfmt) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__dev__generate__genesis) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__dev__lint) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__dev__prover) + opts="info insert-batch insert-version" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__dev__prover__info) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__dev__prover__insert__batch) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__dev__prover__insert__version) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__dev__send__transactions) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__dev__snapshot) + opts="create" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__dev__snapshot__create) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__dev__status) + opts="ports" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__dev__status__ports) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__dev__test) + opts="integration fees revert recovery upgrade build rust l1-contracts prover wallet loadtest" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__dev__test__build) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__dev__test__fees) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__dev__test__integration) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__dev__test__l1__contracts) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__dev__test__loadtest) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__dev__test__prover) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__dev__test__recovery) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__dev__test__revert) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__dev__test__rust) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__dev__test__upgrade) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__dev__test__wallet) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 5 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__ecosystem) + opts="create build-transactions init change-default-chain setup-observability" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__ecosystem__build__transactions) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__ecosystem__change__default__chain) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__ecosystem__create) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__ecosystem__init) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__ecosystem__setup__observability) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__explorer) + opts="init run-backend run" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__explorer__init) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__explorer__run) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__explorer__run__backend) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__external__node) + opts="configs init run" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__external__node__configs) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__external__node__init) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__external__node__run) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__help) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__markdown) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__portal) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__prover) + opts="init setup-keys run init-bellman-cuda compressor-keys" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__prover__compressor__keys) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__prover__init) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__prover__init__bellman__cuda) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__prover__run) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__prover__setup__keys) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__server) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__update) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__markdown) + opts="-v -h --verbose --chain --ignore-prerequisites --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__portal) + opts="-v -h --verbose --chain --ignore-prerequisites --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__prover) + opts="-v -h --verbose --chain --ignore-prerequisites --help init setup-keys run init-bellman-cuda compressor-keys help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__prover__compressor__keys) + opts="-v -h --path --verbose --chain --ignore-prerequisites --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --path) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__prover__help) + opts="init setup-keys run init-bellman-cuda compressor-keys help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__prover__help__compressor__keys) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__prover__help__help) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__prover__help__init) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__prover__help__init__bellman__cuda) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__prover__help__run) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__prover__help__setup__keys) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__prover__init) + opts="-u -d -v -h --dev --proof-store-dir --bucket-base-url --credentials-file --bucket-name --location --project-id --shall-save-to-public-bucket --public-store-dir --public-bucket-base-url --public-credentials-file --public-bucket-name --public-location --public-project-id --clone --bellman-cuda-dir --bellman-cuda --setup-compressor-key --path --region --mode --setup-keys --setup-database --prover-db-url --prover-db-name --use-default --dont-drop --cloud-type --verbose --chain --ignore-prerequisites --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --proof-store-dir) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --bucket-base-url) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --credentials-file) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --bucket-name) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --location) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --project-id) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --shall-save-to-public-bucket) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; + --public-store-dir) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --public-bucket-base-url) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --public-credentials-file) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --public-bucket-name) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --public-location) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --public-project-id) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --bellman-cuda-dir) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --bellman-cuda) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; + --setup-compressor-key) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; + --path) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --region) + COMPREPLY=($(compgen -W "us europe asia" -- "${cur}")) + return 0 + ;; + --mode) + COMPREPLY=($(compgen -W "download generate" -- "${cur}")) + return 0 + ;; + --setup-keys) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; + --setup-database) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; + --prover-db-url) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --prover-db-name) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --use-default) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; + -u) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; + --dont-drop) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; + -d) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; + --cloud-type) + COMPREPLY=($(compgen -W "gcp local" -- "${cur}")) + return 0 + ;; + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__prover__init__bellman__cuda) + opts="-v -h --clone --bellman-cuda-dir --verbose --chain --ignore-prerequisites --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --bellman-cuda-dir) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__prover__run) + opts="-v -h --component --round --threads --max-allocation --witness-vector-generator-count --max-allocation --docker --tag --verbose --chain --ignore-prerequisites --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --component) + COMPREPLY=($(compgen -W "gateway witness-generator witness-vector-generator prover circuit-prover compressor prover-job-monitor" -- "${cur}")) + return 0 + ;; + --round) + COMPREPLY=($(compgen -W "all-rounds basic-circuits leaf-aggregation node-aggregation recursion-tip scheduler" -- "${cur}")) + return 0 + ;; + --threads) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --max-allocation) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --witness-vector-generator-count) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --max-allocation) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --docker) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; + --tag) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__prover__setup__keys) + opts="-v -h --region --mode --verbose --chain --ignore-prerequisites --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --region) + COMPREPLY=($(compgen -W "us europe asia" -- "${cur}")) + return 0 + ;; + --mode) + COMPREPLY=($(compgen -W "download generate" -- "${cur}")) + return 0 + ;; + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__server) + opts="-a -v -h --components --genesis --additional-args --build --uring --verbose --chain --ignore-prerequisites --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --components) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --additional-args) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + -a) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__update) + opts="-c -v -h --only-config --verbose --chain --ignore-prerequisites --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + esac +} + +if [[ "${BASH_VERSINFO[0]}" -eq 4 && "${BASH_VERSINFO[1]}" -ge 4 || "${BASH_VERSINFO[0]}" -gt 4 ]]; then + complete -F _zkstack -o nosort -o bashdefault -o default zkstack +else + complete -F _zkstack -o bashdefault -o default zkstack +fi diff --git a/zkstack_cli/crates/zkstack/src/commands/args/autocomplete.rs b/zkstack_cli/crates/zkstack/src/commands/args/autocomplete.rs new file mode 100644 index 000000000000..8e44d644f39a --- /dev/null +++ b/zkstack_cli/crates/zkstack/src/commands/args/autocomplete.rs @@ -0,0 +1,13 @@ +use std::path::PathBuf; + +use clap::Parser; + +#[derive(Debug, Parser)] +pub struct AutocompleteArgs { + /// The shell to generate the autocomplete script for + #[arg(long = "generate", value_enum)] + pub generator: clap_complete::Shell, + /// The out directory to write the autocomplete script to + #[arg(short, long, default_value = "./")] + pub out: PathBuf, +} diff --git a/zkstack_cli/crates/zkstack/src/commands/args/mod.rs b/zkstack_cli/crates/zkstack/src/commands/args/mod.rs index d18b05c910e5..5fa83aadf51f 100644 --- a/zkstack_cli/crates/zkstack/src/commands/args/mod.rs +++ b/zkstack_cli/crates/zkstack/src/commands/args/mod.rs @@ -1,7 +1,9 @@ +pub use autocomplete::*; pub use containers::*; pub use run_server::*; pub use update::*; +mod autocomplete; mod containers; mod run_server; mod update; diff --git a/zkstack_cli/crates/zkstack/src/commands/autocomplete.rs b/zkstack_cli/crates/zkstack/src/commands/autocomplete.rs new file mode 100644 index 000000000000..0f2105cd5efa --- /dev/null +++ b/zkstack_cli/crates/zkstack/src/commands/autocomplete.rs @@ -0,0 +1,52 @@ +use std::{ + fs::File, + io::{BufWriter, Write}, +}; + +use anyhow::Context; +use clap::CommandFactory; +use clap_complete::{generate, Generator}; +use common::logger; + +use super::args::AutocompleteArgs; +use crate::{ + messages::{msg_generate_autocomplete_file, MSG_OUTRO_AUTOCOMPLETE_GENERATION}, + ZkStack, +}; + +pub fn run(args: AutocompleteArgs) -> anyhow::Result<()> { + let filename = autocomplete_file_name(&args.generator); + let path = args.out.join(filename); + + logger::info(msg_generate_autocomplete_file( + path.to_str() + .context("the output file path is an invalid UTF8 string")?, + )); + + let file = File::create(path).context("Failed to create file")?; + let mut writer = BufWriter::new(file); + + generate_completions(args.generator, &mut writer)?; + + logger::outro(MSG_OUTRO_AUTOCOMPLETE_GENERATION); + + Ok(()) +} + +pub fn generate_completions(gen: G, buf: &mut dyn Write) -> anyhow::Result<()> { + let mut cmd = ZkStack::command(); + let cmd_name = cmd.get_name().to_string(); + + generate(gen, &mut cmd, cmd_name, buf); + + Ok(()) +} + +pub fn autocomplete_file_name(shell: &clap_complete::Shell) -> &'static str { + match shell { + clap_complete::Shell::Bash => "zkstack.sh", + clap_complete::Shell::Fish => "zkstack.fish", + clap_complete::Shell::Zsh => "_zkstack.zsh", + _ => todo!(), + } +} diff --git a/zkstack_cli/crates/zkstack/src/commands/chain/args/create.rs b/zkstack_cli/crates/zkstack/src/commands/chain/args/create.rs index 5fc46c1b227a..ccf64ad27ac9 100644 --- a/zkstack_cli/crates/zkstack/src/commands/chain/args/create.rs +++ b/zkstack_cli/crates/zkstack/src/commands/chain/args/create.rs @@ -1,7 +1,7 @@ use std::{path::PathBuf, str::FromStr}; use anyhow::{bail, Context}; -use clap::{Parser, ValueEnum}; +use clap::{Parser, ValueEnum, ValueHint}; use common::{Prompt, PromptConfirm, PromptSelect}; use config::forge_interface::deploy_ecosystem::output::Erc20Token; use serde::{Deserialize, Serialize}; @@ -53,7 +53,7 @@ pub struct ChainCreateArgs { prover_mode: Option, #[clap(long, help = MSG_WALLET_CREATION_HELP, value_enum)] wallet_creation: Option, - #[clap(long, help = MSG_WALLET_PATH_HELP)] + #[clap(long, help = MSG_WALLET_PATH_HELP, value_hint = ValueHint::FilePath)] wallet_path: Option, #[clap(long, help = MSG_L1_COMMIT_DATA_GENERATOR_MODE_HELP)] l1_batch_commit_data_generator_mode: Option, diff --git a/zkstack_cli/crates/zkstack/src/commands/chain/args/init/configs.rs b/zkstack_cli/crates/zkstack/src/commands/chain/args/init/configs.rs index c26ad6475247..b34809643cf5 100644 --- a/zkstack_cli/crates/zkstack/src/commands/chain/args/init/configs.rs +++ b/zkstack_cli/crates/zkstack/src/commands/chain/args/init/configs.rs @@ -24,7 +24,7 @@ pub struct InitConfigsArgs { pub genesis_args: GenesisArgs, #[clap(long, help = MSG_L1_RPC_URL_HELP)] pub l1_rpc_url: Option, - #[clap(long, help = MSG_NO_PORT_REALLOCATION_HELP, default_value = "false", default_missing_value = "true", num_args = 0..=1)] + #[clap(long, help = MSG_NO_PORT_REALLOCATION_HELP)] pub no_port_reallocation: bool, } diff --git a/zkstack_cli/crates/zkstack/src/commands/chain/args/init/mod.rs b/zkstack_cli/crates/zkstack/src/commands/chain/args/init/mod.rs index be4d28202b80..d92de9a0641b 100644 --- a/zkstack_cli/crates/zkstack/src/commands/chain/args/init/mod.rs +++ b/zkstack_cli/crates/zkstack/src/commands/chain/args/init/mod.rs @@ -29,7 +29,7 @@ pub struct InitArgs { pub deploy_paymaster: Option, #[clap(long, help = MSG_L1_RPC_URL_HELP)] pub l1_rpc_url: Option, - #[clap(long, help = MSG_NO_PORT_REALLOCATION_HELP, default_value = "false", default_missing_value = "true", num_args = 0..=1)] + #[clap(long, help = MSG_NO_PORT_REALLOCATION_HELP)] pub no_port_reallocation: bool, } diff --git a/zkstack_cli/crates/zkstack/src/commands/dev/commands/lint.rs b/zkstack_cli/crates/zkstack/src/commands/dev/commands/lint.rs index 71f21a02e739..6c3c3fa3d756 100644 --- a/zkstack_cli/crates/zkstack/src/commands/dev/commands/lint.rs +++ b/zkstack_cli/crates/zkstack/src/commands/dev/commands/lint.rs @@ -1,13 +1,23 @@ +use std::{ + fs::File, + io::{Read, Write}, + path::Path, +}; + +use anyhow::{bail, Context}; use clap::Parser; use common::{cmd::Cmd, logger, spinner::Spinner}; use config::EcosystemConfig; use xshell::{cmd, Shell}; -use crate::commands::dev::{ - commands::lint_utils::{get_unignored_files, Target}, - messages::{ - msg_running_linter_for_extension_spinner, msg_running_linters_for_files, - MSG_LINT_CONFIG_PATH_ERR, MSG_RUNNING_CONTRACTS_LINTER_SPINNER, +use crate::commands::{ + autocomplete::{autocomplete_file_name, generate_completions}, + dev::{ + commands::lint_utils::{get_unignored_files, Target}, + messages::{ + msg_running_linter_for_extension_spinner, msg_running_linters_for_files, + MSG_LINT_CONFIG_PATH_ERR, MSG_RUNNING_CONTRACTS_LINTER_SPINNER, + }, }, }; @@ -30,6 +40,7 @@ pub fn run(shell: &Shell, args: LintArgs) -> anyhow::Result<()> { Target::Js, Target::Ts, Target::Contracts, + Target::Autocompletion, ] } else { args.targets.clone() @@ -43,10 +54,13 @@ pub fn run(shell: &Shell, args: LintArgs) -> anyhow::Result<()> { match target { Target::Rs => lint_rs(shell, &ecosystem, args.check)?, Target::Contracts => lint_contracts(shell, &ecosystem, args.check)?, + Target::Autocompletion => lint_autocompletion_files(shell, args.check)?, ext => lint(shell, &ecosystem, &ext, args.check)?, } } + logger::outro("Linting complete."); + Ok(()) } @@ -81,6 +95,7 @@ fn get_linter(target: &Target) -> Vec { Target::Js => vec!["eslint".to_string()], Target::Ts => vec!["eslint".to_string(), "--ext".to_string(), "ts".to_string()], Target::Contracts => vec![], + Target::Autocompletion => vec![], } } @@ -133,3 +148,45 @@ fn lint_contracts(shell: &Shell, ecosystem: &EcosystemConfig, check: bool) -> an Ok(()) } + +fn lint_autocompletion_files(_shell: &Shell, check: bool) -> anyhow::Result<()> { + let completion_folder = Path::new("./zkstack_cli/crates/zkstack/completion/"); + if !completion_folder.exists() { + logger::info("WARNING: Please run this command from the project's root folder"); + return Ok(()); + } + + // Array of supported shells + let shells = [ + clap_complete::Shell::Bash, + clap_complete::Shell::Fish, + clap_complete::Shell::Zsh, + ]; + + for shell in shells { + let mut writer = Vec::new(); + + generate_completions(shell, &mut writer) + .context("Failed to generate autocompletion file")?; + + let new = String::from_utf8(writer)?; + + let path = completion_folder.join(autocomplete_file_name(&shell)); + let mut autocomplete_file = File::open(path.clone()) + .context(format!("failed to open {}", autocomplete_file_name(&shell)))?; + + let mut old = String::new(); + autocomplete_file.read_to_string(&mut old)?; + + if new != old { + if !check { + let mut autocomplete_file = File::create(path).context("Failed to create file")?; + autocomplete_file.write_all(new.as_bytes())?; + } else { + bail!("Autocompletion files need to be regenerated. Run `zkstack dev lint -t autocompletion` to fix this issue.") + } + } + } + + Ok(()) +} diff --git a/zkstack_cli/crates/zkstack/src/commands/dev/commands/lint_utils.rs b/zkstack_cli/crates/zkstack/src/commands/dev/commands/lint_utils.rs index 9095e445384b..11a325047104 100644 --- a/zkstack_cli/crates/zkstack/src/commands/dev/commands/lint_utils.rs +++ b/zkstack_cli/crates/zkstack/src/commands/dev/commands/lint_utils.rs @@ -14,6 +14,7 @@ pub enum Target { Ts, Rs, Contracts, + Autocompletion, } #[derive(Deserialize, Serialize, Debug)] diff --git a/zkstack_cli/crates/zkstack/src/commands/dev/commands/test/args/fees.rs b/zkstack_cli/crates/zkstack/src/commands/dev/commands/test/args/fees.rs index 83d505aa5753..9e76850ff2e2 100644 --- a/zkstack_cli/crates/zkstack/src/commands/dev/commands/test/args/fees.rs +++ b/zkstack_cli/crates/zkstack/src/commands/dev/commands/test/args/fees.rs @@ -7,6 +7,6 @@ use crate::commands::dev::messages::{MSG_NO_DEPS_HELP, MSG_NO_KILL_HELP}; pub struct FeesArgs { #[clap(short, long, help = MSG_NO_DEPS_HELP)] pub no_deps: bool, - #[clap(short, long, help = MSG_NO_KILL_HELP)] + #[clap(long, help = MSG_NO_KILL_HELP)] pub no_kill: bool, } diff --git a/zkstack_cli/crates/zkstack/src/commands/dev/commands/test/args/recovery.rs b/zkstack_cli/crates/zkstack/src/commands/dev/commands/test/args/recovery.rs index cf4734fd82e7..b6ce278a1ca7 100644 --- a/zkstack_cli/crates/zkstack/src/commands/dev/commands/test/args/recovery.rs +++ b/zkstack_cli/crates/zkstack/src/commands/dev/commands/test/args/recovery.rs @@ -11,6 +11,6 @@ pub struct RecoveryArgs { pub snapshot: bool, #[clap(short, long, help = MSG_NO_DEPS_HELP)] pub no_deps: bool, - #[clap(short, long, help = MSG_NO_KILL_HELP)] + #[clap(long, help = MSG_NO_KILL_HELP)] pub no_kill: bool, } diff --git a/zkstack_cli/crates/zkstack/src/commands/dev/commands/test/args/revert.rs b/zkstack_cli/crates/zkstack/src/commands/dev/commands/test/args/revert.rs index e4fb7fba2a97..9f86eec7f3df 100644 --- a/zkstack_cli/crates/zkstack/src/commands/dev/commands/test/args/revert.rs +++ b/zkstack_cli/crates/zkstack/src/commands/dev/commands/test/args/revert.rs @@ -13,6 +13,6 @@ pub struct RevertArgs { pub external_node: bool, #[clap(short, long, help = MSG_NO_DEPS_HELP)] pub no_deps: bool, - #[clap(short, long, help = MSG_NO_KILL_HELP)] + #[clap(long, help = MSG_NO_KILL_HELP)] pub no_kill: bool, } diff --git a/zkstack_cli/crates/zkstack/src/commands/ecosystem/args/create.rs b/zkstack_cli/crates/zkstack/src/commands/ecosystem/args/create.rs index 2e5c50f4538f..14cb5206f6a3 100644 --- a/zkstack_cli/crates/zkstack/src/commands/ecosystem/args/create.rs +++ b/zkstack_cli/crates/zkstack/src/commands/ecosystem/args/create.rs @@ -1,7 +1,7 @@ use std::path::{Path, PathBuf}; use anyhow::bail; -use clap::Parser; +use clap::{Parser, ValueHint}; use common::{cmd::Cmd, logger, Prompt, PromptConfirm, PromptSelect}; use serde::{Deserialize, Serialize}; use slugify_rs::slugify; @@ -26,7 +26,7 @@ pub struct EcosystemCreateArgs { pub ecosystem_name: Option, #[clap(long, help = MSG_L1_NETWORK_HELP, value_enum)] pub l1_network: Option, - #[clap(long, help = MSG_LINK_TO_CODE_HELP)] + #[clap(long, help = MSG_LINK_TO_CODE_HELP, value_hint = ValueHint::DirPath)] pub link_to_code: Option, #[clap(flatten)] #[serde(flatten)] diff --git a/zkstack_cli/crates/zkstack/src/commands/ecosystem/args/init.rs b/zkstack_cli/crates/zkstack/src/commands/ecosystem/args/init.rs index 830b7b25e470..a77a9c28ca93 100644 --- a/zkstack_cli/crates/zkstack/src/commands/ecosystem/args/init.rs +++ b/zkstack_cli/crates/zkstack/src/commands/ecosystem/args/init.rs @@ -96,7 +96,7 @@ pub struct EcosystemInitArgs { pub dev: bool, #[clap(long, short = 'o', help = MSG_OBSERVABILITY_HELP, default_missing_value = "true", num_args = 0..=1)] pub observability: Option, - #[clap(long, help = MSG_NO_PORT_REALLOCATION_HELP, default_value = "false", default_missing_value = "true", num_args = 0..=1)] + #[clap(long, help = MSG_NO_PORT_REALLOCATION_HELP)] pub no_port_reallocation: bool, } diff --git a/zkstack_cli/crates/zkstack/src/commands/mod.rs b/zkstack_cli/crates/zkstack/src/commands/mod.rs index c46400cc8657..b5319cbc6bfa 100644 --- a/zkstack_cli/crates/zkstack/src/commands/mod.rs +++ b/zkstack_cli/crates/zkstack/src/commands/mod.rs @@ -1,4 +1,5 @@ pub mod args; +pub mod autocomplete; pub mod chain; pub mod consensus; pub mod containers; diff --git a/zkstack_cli/crates/zkstack/src/main.rs b/zkstack_cli/crates/zkstack/src/main.rs index 404ac8938101..3ebe26a4fa21 100644 --- a/zkstack_cli/crates/zkstack/src/main.rs +++ b/zkstack_cli/crates/zkstack/src/main.rs @@ -1,6 +1,6 @@ use clap::{command, Parser, Subcommand}; use commands::{ - args::{ContainersArgs, UpdateArgs}, + args::{AutocompleteArgs, ContainersArgs, UpdateArgs}, contract_verifier::ContractVerifierCommands, dev::DevCommands, }; @@ -29,6 +29,7 @@ mod utils; #[derive(Parser, Debug)] #[command( + name = "zkstack", version = version_message(env!("CARGO_PKG_VERSION")), about )] @@ -41,13 +42,15 @@ struct ZkStack { #[derive(Subcommand, Debug)] pub enum ZkStackSubcommands { + /// Create shell autocompletion files + Autocomplete(AutocompleteArgs), /// Ecosystem related commands #[command(subcommand, alias = "e")] Ecosystem(Box), /// Chain related commands #[command(subcommand, alias = "c")] Chain(Box), - /// Chain related commands + /// Supervisor related commands #[command(subcommand)] Dev(DevCommands), /// Prover related commands @@ -55,7 +58,7 @@ pub enum ZkStackSubcommands { Prover(ProverCommands), /// Run server Server(RunServerArgs), - /// External Node related commands + /// External Node related commands #[command(subcommand, alias = "en")] ExternalNode(ExternalNodeCommands), /// Run containers for local development @@ -69,11 +72,13 @@ pub enum ZkStackSubcommands { /// Run block-explorer #[command(subcommand)] Explorer(ExplorerCommands), + /// Consensus utilities #[command(subcommand)] Consensus(consensus::Command), /// Update ZKsync #[command(alias = "u")] Update(UpdateArgs), + /// Print markdown help #[command(hide = true)] Markdown, } @@ -98,8 +103,20 @@ async fn main() -> anyhow::Result<()> { // We must parse arguments before printing the intro, because some autogenerated // Clap commands (like `--version` would look odd otherwise). - let inception_args = ZkStack::parse(); + let zkstack_args = ZkStack::parse(); + + match run_subcommand(zkstack_args).await { + Ok(_) => {} + Err(error) => { + log_error(error); + std::process::exit(1); + } + } + Ok(()) +} + +async fn run_subcommand(zkstack_args: ZkStack) -> anyhow::Result<()> { init_prompt_theme(); logger::new_empty_line(); @@ -107,38 +124,30 @@ async fn main() -> anyhow::Result<()> { let shell = Shell::new().unwrap(); - init_global_config_inner(&shell, &inception_args.global)?; + init_global_config_inner(&shell, &zkstack_args.global)?; if !global_config().ignore_prerequisites { check_general_prerequisites(&shell); } - match run_subcommand(inception_args, &shell).await { - Ok(_) => {} - Err(error) => { - log_error(error); - std::process::exit(1); + match zkstack_args.command { + ZkStackSubcommands::Autocomplete(args) => commands::autocomplete::run(args)?, + ZkStackSubcommands::Ecosystem(args) => commands::ecosystem::run(&shell, *args).await?, + ZkStackSubcommands::Chain(args) => commands::chain::run(&shell, *args).await?, + ZkStackSubcommands::Dev(args) => commands::dev::run(&shell, args).await?, + ZkStackSubcommands::Prover(args) => commands::prover::run(&shell, args).await?, + ZkStackSubcommands::Server(args) => commands::server::run(&shell, args)?, + ZkStackSubcommands::Containers(args) => commands::containers::run(&shell, args)?, + ZkStackSubcommands::ExternalNode(args) => { + commands::external_node::run(&shell, args).await? } - } - Ok(()) -} - -async fn run_subcommand(inception_args: ZkStack, shell: &Shell) -> anyhow::Result<()> { - match inception_args.command { - ZkStackSubcommands::Ecosystem(args) => commands::ecosystem::run(shell, *args).await?, - ZkStackSubcommands::Chain(args) => commands::chain::run(shell, *args).await?, - ZkStackSubcommands::Dev(args) => commands::dev::run(shell, args).await?, - ZkStackSubcommands::Prover(args) => commands::prover::run(shell, args).await?, - ZkStackSubcommands::Server(args) => commands::server::run(shell, args)?, - ZkStackSubcommands::Containers(args) => commands::containers::run(shell, args)?, - ZkStackSubcommands::ExternalNode(args) => commands::external_node::run(shell, args).await?, ZkStackSubcommands::ContractVerifier(args) => { - commands::contract_verifier::run(shell, args).await? + commands::contract_verifier::run(&shell, args).await? } - ZkStackSubcommands::Explorer(args) => commands::explorer::run(shell, args).await?, - ZkStackSubcommands::Consensus(cmd) => cmd.run(shell).await?, - ZkStackSubcommands::Portal => commands::portal::run(shell).await?, - ZkStackSubcommands::Update(args) => commands::update::run(shell, args).await?, + ZkStackSubcommands::Explorer(args) => commands::explorer::run(&shell, args).await?, + ZkStackSubcommands::Consensus(cmd) => cmd.run(&shell).await?, + ZkStackSubcommands::Portal => commands::portal::run(&shell).await?, + ZkStackSubcommands::Update(args) => commands::update::run(&shell, args).await?, ZkStackSubcommands::Markdown => { clap_markdown::print_help_markdown::(); } @@ -146,11 +155,8 @@ async fn run_subcommand(inception_args: ZkStack, shell: &Shell) -> anyhow::Resul Ok(()) } -fn init_global_config_inner( - shell: &Shell, - inception_args: &ZkStackGlobalArgs, -) -> anyhow::Result<()> { - if let Some(name) = &inception_args.chain { +fn init_global_config_inner(shell: &Shell, zkstack_args: &ZkStackGlobalArgs) -> anyhow::Result<()> { + if let Some(name) = &zkstack_args.chain { if let Ok(config) = EcosystemConfig::from_file(shell) { let chains = config.list_of_chains(); if !chains.contains(name) { @@ -163,9 +169,9 @@ fn init_global_config_inner( } } init_global_config(GlobalConfig { - verbose: inception_args.verbose, - chain_name: inception_args.chain.clone(), - ignore_prerequisites: inception_args.ignore_prerequisites, + verbose: zkstack_args.verbose, + chain_name: zkstack_args.chain.clone(), + ignore_prerequisites: zkstack_args.ignore_prerequisites, }); Ok(()) } diff --git a/zkstack_cli/crates/zkstack/src/messages.rs b/zkstack_cli/crates/zkstack/src/messages.rs index 6d6a1ceb566f..e2145c18ffd0 100644 --- a/zkstack_cli/crates/zkstack/src/messages.rs +++ b/zkstack_cli/crates/zkstack/src/messages.rs @@ -16,6 +16,13 @@ pub(super) const MSG_CHAIN_NOT_INITIALIZED: &str = "Chain not initialized. Please create a chain first"; pub(super) const MSG_ARGS_VALIDATOR_ERR: &str = "Invalid arguments"; +/// Autocomplete message +pub(super) fn msg_generate_autocomplete_file(filename: &str) -> String { + format!("Generating completion file: {filename}") +} +pub(super) const MSG_OUTRO_AUTOCOMPLETE_GENERATION: &str = + "Autocompletion file correctly generated"; + /// Ecosystem create related messages pub(super) const MSG_L1_NETWORK_HELP: &str = "L1 Network"; pub(super) const MSG_LINK_TO_CODE_HELP: &str = "Code link"; From caee55fef4eed0ec58cceaeba277bbdedf5c6f51 Mon Sep 17 00:00:00 2001 From: Grzegorz Prusak Date: Wed, 23 Oct 2024 06:22:06 +0200 Subject: [PATCH 08/27] fix(consensus): preventing config update reverts (#3148) Random failures of consensus_global_config RPC may cause config reverts, until the consensus_genesis() RPC is fully deprecated. Although the problems of this sort are transient, this pr adds extra protection from this kind of situations to prevent unnecessary binary restarts. --- core/lib/dal/src/consensus_dal/mod.rs | 64 +++++++++++++++++---------- core/node/consensus/src/en.rs | 7 ++- 2 files changed, 46 insertions(+), 25 deletions(-) diff --git a/core/lib/dal/src/consensus_dal/mod.rs b/core/lib/dal/src/consensus_dal/mod.rs index 9515e93f2b3c..4516434868c4 100644 --- a/core/lib/dal/src/consensus_dal/mod.rs +++ b/core/lib/dal/src/consensus_dal/mod.rs @@ -16,10 +16,48 @@ use crate::{Core, CoreDal}; #[cfg(test)] mod tests; +/// Hash of the batch. pub fn batch_hash(info: &StoredBatchInfo) -> attester::BatchHash { attester::BatchHash(Keccak256::from_bytes(info.hash().0)) } +/// Verifies that the transition from `old` to `new` is admissible. +pub fn verify_config_transition(old: &GlobalConfig, new: &GlobalConfig) -> anyhow::Result<()> { + anyhow::ensure!( + old.genesis.chain_id == new.genesis.chain_id, + "changing chain_id is not allowed: old = {:?}, new = {:?}", + old.genesis.chain_id, + new.genesis.chain_id, + ); + // Note that it may happen that the fork number didn't change, + // in case the binary was updated to support more fields in genesis struct. + // In such a case, the old binary was not able to connect to the consensus network, + // because of the genesis hash mismatch. + // TODO: Perhaps it would be better to deny unknown fields in the genesis instead. + // It would require embedding the genesis either as a json string or protobuf bytes within + // the global config, so that the global config can be parsed with + // `deny_unknown_fields:false` while genesis would be parsed with + // `deny_unknown_fields:true`. + anyhow::ensure!( + old.genesis.fork_number <= new.genesis.fork_number, + "transition to a past fork is not allowed: old = {:?}, new = {:?}", + old.genesis.fork_number, + new.genesis.fork_number, + ); + new.genesis.verify().context("genesis.verify()")?; + // This is a temporary hack until the `consensus_genesis()` RPC is disabled. + if new + == (&GlobalConfig { + genesis: old.genesis.clone(), + registry_address: None, + seed_peers: [].into(), + }) + { + anyhow::bail!("new config is equal to truncated old config, which means that it was sourced from the wrong endpoint"); + } + Ok(()) +} + /// Storage access methods for `zksync_core::consensus` module. #[derive(Debug)] pub struct ConsensusDal<'a, 'c> { @@ -94,6 +132,8 @@ impl ConsensusDal<'_, '_> { if got == want { return Ok(()); } + verify_config_transition(got, want)?; + // If genesis didn't change, just update the config. if got.genesis == want.genesis { let s = zksync_protobuf::serde::Serialize; @@ -112,30 +152,6 @@ impl ConsensusDal<'_, '_> { txn.commit().await?; return Ok(()); } - - // Verify the genesis change. - anyhow::ensure!( - got.genesis.chain_id == want.genesis.chain_id, - "changing chain_id is not allowed: old = {:?}, new = {:?}", - got.genesis.chain_id, - want.genesis.chain_id, - ); - // Note that it may happen that the fork number didn't change, - // in case the binary was updated to support more fields in genesis struct. - // In such a case, the old binary was not able to connect to the consensus network, - // because of the genesis hash mismatch. - // TODO: Perhaps it would be better to deny unknown fields in the genesis instead. - // It would require embedding the genesis either as a json string or protobuf bytes within - // the global config, so that the global config can be parsed with - // `deny_unknown_fields:false` while genesis would be parsed with - // `deny_unknown_fields:true`. - anyhow::ensure!( - got.genesis.fork_number <= want.genesis.fork_number, - "transition to a past fork is not allowed: old = {:?}, new = {:?}", - got.genesis.fork_number, - want.genesis.fork_number, - ); - want.genesis.verify().context("genesis.verify()")?; } // Reset the consensus state. diff --git a/core/node/consensus/src/en.rs b/core/node/consensus/src/en.rs index 518a7ebb29aa..8158cc5aeb26 100644 --- a/core/node/consensus/src/en.rs +++ b/core/node/consensus/src/en.rs @@ -100,7 +100,12 @@ impl EN { let old = old; loop { if let Ok(new) = self.fetch_global_config(ctx).await { - if new != old { + // We verify the transition here to work around the situation + // where `consenus_global_config()` RPC fails randomly and fallback + // to `consensus_genesis()` RPC activates. + if new != old + && consensus_dal::verify_config_transition(&old, &new).is_ok() + { return Err(anyhow::format_err!( "global config changed: old {old:?}, new {new:?}" ) From 5092031050b30c39107df788317a15eaa921b136 Mon Sep 17 00:00:00 2001 From: Daniyar Itegulov Date: Wed, 23 Oct 2024 19:28:32 +1100 Subject: [PATCH 09/27] fix(zkstack_cli): make progress bar optional in non-terminal envs (#3146) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## What ❔ Enables plain logging as a fallback for progress bar. ## Why ❔ Spinner does not print anything when zkstack is redirected to a file, piped or is just ran in an env with no virtual terminal. Most notably this affects our CI where all spinner messages are just swallowed into nowhere. ## Checklist - [x] PR title corresponds to the body of PR (we generate changelog entries from PRs). - [ ] Tests for the changes have been added / updated. - [ ] Documentation comments have been added / updated. - [x] Code has been formatted via `zkstack dev fmt` and `zkstack dev lint`. --- zkstack_cli/crates/common/src/term/spinner.rs | 57 +++++++++++++++---- 1 file changed, 45 insertions(+), 12 deletions(-) diff --git a/zkstack_cli/crates/common/src/term/spinner.rs b/zkstack_cli/crates/common/src/term/spinner.rs index b97ba075ac45..3ec2631804af 100644 --- a/zkstack_cli/crates/common/src/term/spinner.rs +++ b/zkstack_cli/crates/common/src/term/spinner.rs @@ -1,34 +1,40 @@ -use std::time::Instant; +use std::{fmt::Display, io::IsTerminal, time::Instant}; use cliclack::{spinner, ProgressBar}; -use crate::config::global_config; +use crate::{config::global_config, logger}; /// Spinner is a helper struct to show a spinner while some operation is running. pub struct Spinner { msg: String, - pb: ProgressBar, + output: SpinnerOutput, time: Instant, } impl Spinner { /// Create a new spinner with a message. pub fn new(msg: &str) -> Self { - let pb = spinner(); - pb.start(msg); - if global_config().verbose { - pb.stop(msg); - } + let output = if std::io::stdout().is_terminal() { + let pb = spinner(); + pb.start(msg); + if global_config().verbose { + pb.stop(msg); + } + SpinnerOutput::Progress(pb) + } else { + logger::info(msg); + SpinnerOutput::Plain() + }; Spinner { msg: msg.to_owned(), - pb, + output, time: Instant::now(), } } /// Manually finish the spinner. pub fn finish(self) { - self.pb.stop(format!( + self.output.stop(format!( "{} done in {} secs", self.msg, self.time.elapsed().as_secs_f64() @@ -37,7 +43,7 @@ impl Spinner { /// Interrupt the spinner with a failed message. pub fn fail(self) { - self.pb.error(format!( + self.output.error(format!( "{} failed in {} secs", self.msg, self.time.elapsed().as_secs_f64() @@ -46,6 +52,33 @@ impl Spinner { /// Freeze the spinner with current message. pub fn freeze(self) { - self.pb.stop(self.msg); + self.output.stop(self.msg); + } +} + +/// An abstraction that makes interactive progress bar optional in environments where virtual +/// terminal is not available. +/// +/// Uses plain `logger::{info,error}` as the fallback. +/// +/// See https://github.com/console-rs/indicatif/issues/530 for more details. +enum SpinnerOutput { + Progress(ProgressBar), + Plain(), +} + +impl SpinnerOutput { + fn error(&self, msg: impl Display) { + match self { + SpinnerOutput::Progress(pb) => pb.error(msg), + SpinnerOutput::Plain() => logger::error(msg), + } + } + + fn stop(self, msg: impl Display) { + match self { + SpinnerOutput::Progress(pb) => pb.stop(msg), + SpinnerOutput::Plain() => logger::info(msg), + } } } From 11e525e49531e2aa2d556337350b9af9355727fc Mon Sep 17 00:00:00 2001 From: Shahar Kaminsky Date: Wed, 23 Oct 2024 14:05:16 +0300 Subject: [PATCH 10/27] fix(zk chains): Increase Batch Seal Default Deadline (#3154) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## What ❔ This PR increases the L1 Batch seadl default deadline from 1 hour to 8 hours. ## Why ❔ - For lower TPS chains, this configuration matches reality better and is less wasteful in terms of Ethereum interactions. - For higher TPS chains, the batches will be sealed by other seal criteria anyways ## Checklist - [x] PR title corresponds to the body of PR (we generate changelog entries from PRs). - [ ] 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`. --- etc/env/file_based/overrides/mainnet.yaml | 3 ++- etc/env/file_based/overrides/testnet.yaml | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/etc/env/file_based/overrides/mainnet.yaml b/etc/env/file_based/overrides/mainnet.yaml index 0600abf694c2..7565aac869ae 100644 --- a/etc/env/file_based/overrides/mainnet.yaml +++ b/etc/env/file_based/overrides/mainnet.yaml @@ -1,5 +1,6 @@ state_keeper: - block_commit_deadline_ms: 3600000 + # Default batch seal time deadline: 8 hours + block_commit_deadline_ms: 28000000 minimal_l2_gas_price: 45250000 eth: sender: diff --git a/etc/env/file_based/overrides/testnet.yaml b/etc/env/file_based/overrides/testnet.yaml index e4da1ac96e26..d36cf9fc7bc0 100644 --- a/etc/env/file_based/overrides/testnet.yaml +++ b/etc/env/file_based/overrides/testnet.yaml @@ -1,5 +1,6 @@ state_keeper: - block_commit_deadline_ms: 3600000 + # Default batch seal time deadline: 8 hours + block_commit_deadline_ms: 28000000 minimal_l2_gas_price: 25000000 eth: sender: From 35e84cc03a7fdd315932fb3020fe41c95a6e4bca Mon Sep 17 00:00:00 2001 From: Igor Aleksanov Date: Wed, 23 Oct 2024 15:15:47 +0400 Subject: [PATCH 11/27] feat(api): Implement eth_maxPriorityFeePerGas (#3135) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## What ❔ Fixes #13 Implements `eth_maxPriorityFeePerGas` method. ## Why ❔ This method is a de-facto standard now, and SDKs (e.g. viem) can use it assuming that it's supported. Even given that we're not really using EIP1559, we should still support it and return 0. ## Checklist - [ ] PR title corresponds to the body of PR (we generate changelog entries from PRs). - [ ] Tests for the changes have been added / updated. - [ ] Documentation comments have been added / updated. - [ ] Code has been formatted via `zkstack dev fmt` and `zkstack dev lint`. --- core/lib/web3_decl/src/namespaces/eth.rs | 3 +++ .../api_server/src/web3/backend_jsonrpsee/namespaces/eth.rs | 4 ++++ core/node/api_server/src/web3/namespaces/eth.rs | 5 +++++ core/tests/ts-integration/tests/api/web3.test.ts | 6 ++++-- 4 files changed, 16 insertions(+), 2 deletions(-) diff --git a/core/lib/web3_decl/src/namespaces/eth.rs b/core/lib/web3_decl/src/namespaces/eth.rs index 399773b845dc..40cb6300cffa 100644 --- a/core/lib/web3_decl/src/namespaces/eth.rs +++ b/core/lib/web3_decl/src/namespaces/eth.rs @@ -185,6 +185,9 @@ pub trait EthNamespace { newest_block: BlockNumber, reward_percentiles: Vec, ) -> RpcResult; + + #[method(name = "maxPriorityFeePerGas")] + async fn max_priority_fee_per_gas(&self) -> RpcResult; } #[cfg(feature = "server")] diff --git a/core/node/api_server/src/web3/backend_jsonrpsee/namespaces/eth.rs b/core/node/api_server/src/web3/backend_jsonrpsee/namespaces/eth.rs index cc2209a35d39..342756013752 100644 --- a/core/node/api_server/src/web3/backend_jsonrpsee/namespaces/eth.rs +++ b/core/node/api_server/src/web3/backend_jsonrpsee/namespaces/eth.rs @@ -268,4 +268,8 @@ impl EthNamespaceServer for EthNamespace { .await .map_err(|err| self.current_method().map_err(err)) } + + async fn max_priority_fee_per_gas(&self) -> RpcResult { + Ok(self.max_priority_fee_per_gas_impl()) + } } diff --git a/core/node/api_server/src/web3/namespaces/eth.rs b/core/node/api_server/src/web3/namespaces/eth.rs index 5206cd3bc2bb..ee37cb989f1b 100644 --- a/core/node/api_server/src/web3/namespaces/eth.rs +++ b/core/node/api_server/src/web3/namespaces/eth.rs @@ -863,6 +863,11 @@ impl EthNamespace { } }) } + + pub fn max_priority_fee_per_gas_impl(&self) -> U256 { + // ZKsync does not require priority fee. + 0u64.into() + } } // Bogus methods. diff --git a/core/tests/ts-integration/tests/api/web3.test.ts b/core/tests/ts-integration/tests/api/web3.test.ts index 6f1b6c3aa6b8..ceed9654df91 100644 --- a/core/tests/ts-integration/tests/api/web3.test.ts +++ b/core/tests/ts-integration/tests/api/web3.test.ts @@ -189,7 +189,8 @@ describe('web3 API compatibility tests', () => { ['eth_getCompilers', [], []], ['eth_hashrate', [], '0x0'], ['eth_mining', [], false], - ['eth_getUncleCountByBlockNumber', ['0x0'], '0x0'] + ['eth_getUncleCountByBlockNumber', ['0x0'], '0x0'], + ['eth_maxPriorityFeePerGas', [], '0x0'] ])('Should test bogus web3 methods (%s)', async (method: string, input: string[], output: string) => { await expect(alice.provider.send(method, input)).resolves.toEqual(output); }); @@ -271,7 +272,8 @@ describe('web3 API compatibility tests', () => { const eip1559ApiReceipt = await alice.provider.getTransaction(eip1559Tx.hash); expect(eip1559ApiReceipt.maxFeePerGas).toEqual(eip1559Tx.maxFeePerGas!); - expect(eip1559ApiReceipt.maxPriorityFeePerGas).toEqual(eip1559Tx.maxPriorityFeePerGas!); + // `ethers` will use value provided by `eth_maxPriorityFeePerGas`, and we return 0 there. + expect(eip1559ApiReceipt.maxPriorityFeePerGas).toEqual(0n); }); test('Should test getFilterChanges for pending transactions', async () => { From 08a3fe7ffd0410c51334193068649905337d5e84 Mon Sep 17 00:00:00 2001 From: Yury Akudovich Date: Wed, 23 Oct 2024 13:19:42 +0200 Subject: [PATCH 12/27] fix: Fix counter metric type to be Counter. (#3153) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## What ❔ Fix counter metric type to be Counter. ## Why ❔ To have correct calculation of network errors across restarts. ## Checklist - [x] PR title corresponds to the body of PR (we generate changelog entries from PRs). - [ ] Tests for the changes have been added / updated. - [ ] Documentation comments have been added / updated. - [x] Code has been formatted via `zkstack dev fmt` and `zkstack dev lint`. --- core/bin/zksync_tee_prover/src/metrics.rs | 4 ++-- core/bin/zksync_tee_prover/src/tee_prover.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/core/bin/zksync_tee_prover/src/metrics.rs b/core/bin/zksync_tee_prover/src/metrics.rs index 9f535967f79f..769a8bbc7e0f 100644 --- a/core/bin/zksync_tee_prover/src/metrics.rs +++ b/core/bin/zksync_tee_prover/src/metrics.rs @@ -2,7 +2,7 @@ use std::time::Duration; -use vise::{Buckets, Gauge, Histogram, Metrics, Unit}; +use vise::{Buckets, Counter, Gauge, Histogram, Metrics, Unit}; #[derive(Debug, Metrics)] #[metrics(prefix = "tee_prover")] @@ -13,7 +13,7 @@ pub(crate) struct TeeProverMetrics { pub proof_generation_time: Histogram, #[metrics(buckets = Buckets::LATENCIES, unit = Unit::Seconds)] pub proof_submitting_time: Histogram, - pub network_errors_counter: Gauge, + pub network_errors_counter: Counter, pub last_batch_number_processed: Gauge, } diff --git a/core/bin/zksync_tee_prover/src/tee_prover.rs b/core/bin/zksync_tee_prover/src/tee_prover.rs index bb7176644e63..5d22d1e7c630 100644 --- a/core/bin/zksync_tee_prover/src/tee_prover.rs +++ b/core/bin/zksync_tee_prover/src/tee_prover.rs @@ -155,7 +155,7 @@ impl Task for TeeProver { } } Err(err) => { - METRICS.network_errors_counter.inc_by(1); + METRICS.network_errors_counter.inc(); if !err.is_retriable() || retries > config.max_retries { return Err(err.into()); } From 0d78228c8c6a848644ded1e6807ee88f80212c9f Mon Sep 17 00:00:00 2001 From: zksync-era-bot <147085853+zksync-era-bot@users.noreply.github.com> Date: Wed, 23 Oct 2024 16:23:19 +0400 Subject: [PATCH 13/27] chore(main): release core 25.0.0 (#3094) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit :robot: I have created a release *beep* *boop* --- ## [25.0.0](https://github.com/matter-labs/zksync-era/compare/core-v24.29.0...core-v25.0.0) (2024-10-23) ### ⚠ BREAKING CHANGES * **contracts:** integrate protocol defense changes ([#2737](https://github.com/matter-labs/zksync-era/issues/2737)) ### Features * Add CoinMarketCap external API ([#2971](https://github.com/matter-labs/zksync-era/issues/2971)) ([c1cb30e](https://github.com/matter-labs/zksync-era/commit/c1cb30e59ca1d0b5fea5fe0980082aea0eb04aa2)) * **api:** Implement eth_maxPriorityFeePerGas ([#3135](https://github.com/matter-labs/zksync-era/issues/3135)) ([35e84cc](https://github.com/matter-labs/zksync-era/commit/35e84cc03a7fdd315932fb3020fe41c95a6e4bca)) * **api:** Make acceptable values cache lag configurable ([#3028](https://github.com/matter-labs/zksync-era/issues/3028)) ([6747529](https://github.com/matter-labs/zksync-era/commit/67475292ff770d2edd6884be27f976a4144778ae)) * **contracts:** integrate protocol defense changes ([#2737](https://github.com/matter-labs/zksync-era/issues/2737)) ([c60a348](https://github.com/matter-labs/zksync-era/commit/c60a3482ee09b3e371163e62f49e83bc6d6f4548)) * **external-node:** save protocol version before opening a batch ([#3136](https://github.com/matter-labs/zksync-era/issues/3136)) ([d6de4f4](https://github.com/matter-labs/zksync-era/commit/d6de4f40ddce339c760c95e2bf4b8aceb571af7f)) * Prover e2e test ([#2975](https://github.com/matter-labs/zksync-era/issues/2975)) ([0edd796](https://github.com/matter-labs/zksync-era/commit/0edd7962429b3530ae751bd7cc947c97193dd0ca)) * **prover:** Add min_provers and dry_run features. Improve metrics and test. ([#3129](https://github.com/matter-labs/zksync-era/issues/3129)) ([7c28964](https://github.com/matter-labs/zksync-era/commit/7c289649b7b3c418c7193a35b51c264cf4970f3c)) * **tee_verifier:** speedup SQL query for new jobs ([#3133](https://github.com/matter-labs/zksync-era/issues/3133)) ([30ceee8](https://github.com/matter-labs/zksync-era/commit/30ceee8a48046e349ff0234ebb24d468a0e0876c)) * vm2 tracers can access storage ([#3114](https://github.com/matter-labs/zksync-era/issues/3114)) ([e466b52](https://github.com/matter-labs/zksync-era/commit/e466b52948e3c4ed1cb5af4fd999a52028e4d216)) * **vm:** Return compressed bytecodes from `push_transaction()` ([#3126](https://github.com/matter-labs/zksync-era/issues/3126)) ([37f209f](https://github.com/matter-labs/zksync-era/commit/37f209fec8e7cb65c0e60003d46b9ea69c43caf1)) ### Bug Fixes * **call_tracer:** Flat call tracer fixes for blocks ([#3095](https://github.com/matter-labs/zksync-era/issues/3095)) ([30ddb29](https://github.com/matter-labs/zksync-era/commit/30ddb292977340beab37a81f75c35480cbdd59d3)) * **consensus:** preventing config update reverts ([#3148](https://github.com/matter-labs/zksync-era/issues/3148)) ([caee55f](https://github.com/matter-labs/zksync-era/commit/caee55fef4eed0ec58cceaeba277bbdedf5c6f51)) * **en:** Return `SyncState` health check ([#3142](https://github.com/matter-labs/zksync-era/issues/3142)) ([abeee81](https://github.com/matter-labs/zksync-era/commit/abeee8190d3c3a5e577d71024bdfb30ff516ad03)) * **external-node:** delete empty unsealed batch on EN initialization ([#3125](https://github.com/matter-labs/zksync-era/issues/3125)) ([5d5214b](https://github.com/matter-labs/zksync-era/commit/5d5214ba983823b306495d34fdd1d46abacce07a)) * Fix counter metric type to be Counter. ([#3153](https://github.com/matter-labs/zksync-era/issues/3153)) ([08a3fe7](https://github.com/matter-labs/zksync-era/commit/08a3fe7ffd0410c51334193068649905337d5e84)) * **mempool:** minor mempool improvements ([#3113](https://github.com/matter-labs/zksync-era/issues/3113)) ([cd16083](https://github.com/matter-labs/zksync-era/commit/cd160830a0b7ebe5af4ecbd944da1cd51af3528a)) * **prover:** Run for zero queue to allow scaling down to 0 ([#3115](https://github.com/matter-labs/zksync-era/issues/3115)) ([bbe1919](https://github.com/matter-labs/zksync-era/commit/bbe191937fa5c5711a7164fd4f0c2ae65cda0833)) * restore instruction count functionality ([#3081](https://github.com/matter-labs/zksync-era/issues/3081)) ([6159f75](https://github.com/matter-labs/zksync-era/commit/6159f7531a0340a69c4926c4e0325811ed7cabb8)) * **state-keeper:** save call trace for upgrade txs ([#3132](https://github.com/matter-labs/zksync-era/issues/3132)) ([e1c363f](https://github.com/matter-labs/zksync-era/commit/e1c363f8f5e03c8d62bba1523f17b87d6a0e25ad)) * **tee_prover:** add zstd compression ([#3144](https://github.com/matter-labs/zksync-era/issues/3144)) ([7241ae1](https://github.com/matter-labs/zksync-era/commit/7241ae139b2b6bf9a9966eaa2f22203583a3786f)) * **tee_verifier:** correctly initialize storage for re-execution ([#3017](https://github.com/matter-labs/zksync-era/issues/3017)) ([9d88373](https://github.com/matter-labs/zksync-era/commit/9d88373f1b745c489e98e5ef542644a70e815498)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). --------- Co-authored-by: zksync-era-bot --- .github/release-please/manifest.json | 2 +- Cargo.lock | 2 +- core/CHANGELOG.md | 35 ++++++++++++++++++++++++++++ core/bin/external_node/Cargo.toml | 2 +- 4 files changed, 38 insertions(+), 3 deletions(-) diff --git a/.github/release-please/manifest.json b/.github/release-please/manifest.json index a56866a8bd73..a0d1d73bddaf 100644 --- a/.github/release-please/manifest.json +++ b/.github/release-please/manifest.json @@ -1,5 +1,5 @@ { - "core": "24.29.0", + "core": "25.0.0", "prover": "16.5.0", "zkstack_cli": "0.1.2" } diff --git a/Cargo.lock b/Cargo.lock index 05c26a748347..7e4cad34cf8f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10220,7 +10220,7 @@ dependencies = [ [[package]] name = "zksync_external_node" -version = "24.29.0" +version = "25.0.0" dependencies = [ "anyhow", "assert_matches", diff --git a/core/CHANGELOG.md b/core/CHANGELOG.md index 59b49af15540..56239303cd4e 100644 --- a/core/CHANGELOG.md +++ b/core/CHANGELOG.md @@ -1,5 +1,40 @@ # Changelog +## [25.0.0](https://github.com/matter-labs/zksync-era/compare/core-v24.29.0...core-v25.0.0) (2024-10-23) + + +### ⚠ BREAKING CHANGES + +* **contracts:** integrate protocol defense changes ([#2737](https://github.com/matter-labs/zksync-era/issues/2737)) + +### Features + +* Add CoinMarketCap external API ([#2971](https://github.com/matter-labs/zksync-era/issues/2971)) ([c1cb30e](https://github.com/matter-labs/zksync-era/commit/c1cb30e59ca1d0b5fea5fe0980082aea0eb04aa2)) +* **api:** Implement eth_maxPriorityFeePerGas ([#3135](https://github.com/matter-labs/zksync-era/issues/3135)) ([35e84cc](https://github.com/matter-labs/zksync-era/commit/35e84cc03a7fdd315932fb3020fe41c95a6e4bca)) +* **api:** Make acceptable values cache lag configurable ([#3028](https://github.com/matter-labs/zksync-era/issues/3028)) ([6747529](https://github.com/matter-labs/zksync-era/commit/67475292ff770d2edd6884be27f976a4144778ae)) +* **contracts:** integrate protocol defense changes ([#2737](https://github.com/matter-labs/zksync-era/issues/2737)) ([c60a348](https://github.com/matter-labs/zksync-era/commit/c60a3482ee09b3e371163e62f49e83bc6d6f4548)) +* **external-node:** save protocol version before opening a batch ([#3136](https://github.com/matter-labs/zksync-era/issues/3136)) ([d6de4f4](https://github.com/matter-labs/zksync-era/commit/d6de4f40ddce339c760c95e2bf4b8aceb571af7f)) +* Prover e2e test ([#2975](https://github.com/matter-labs/zksync-era/issues/2975)) ([0edd796](https://github.com/matter-labs/zksync-era/commit/0edd7962429b3530ae751bd7cc947c97193dd0ca)) +* **prover:** Add min_provers and dry_run features. Improve metrics and test. ([#3129](https://github.com/matter-labs/zksync-era/issues/3129)) ([7c28964](https://github.com/matter-labs/zksync-era/commit/7c289649b7b3c418c7193a35b51c264cf4970f3c)) +* **tee_verifier:** speedup SQL query for new jobs ([#3133](https://github.com/matter-labs/zksync-era/issues/3133)) ([30ceee8](https://github.com/matter-labs/zksync-era/commit/30ceee8a48046e349ff0234ebb24d468a0e0876c)) +* vm2 tracers can access storage ([#3114](https://github.com/matter-labs/zksync-era/issues/3114)) ([e466b52](https://github.com/matter-labs/zksync-era/commit/e466b52948e3c4ed1cb5af4fd999a52028e4d216)) +* **vm:** Return compressed bytecodes from `push_transaction()` ([#3126](https://github.com/matter-labs/zksync-era/issues/3126)) ([37f209f](https://github.com/matter-labs/zksync-era/commit/37f209fec8e7cb65c0e60003d46b9ea69c43caf1)) + + +### Bug Fixes + +* **call_tracer:** Flat call tracer fixes for blocks ([#3095](https://github.com/matter-labs/zksync-era/issues/3095)) ([30ddb29](https://github.com/matter-labs/zksync-era/commit/30ddb292977340beab37a81f75c35480cbdd59d3)) +* **consensus:** preventing config update reverts ([#3148](https://github.com/matter-labs/zksync-era/issues/3148)) ([caee55f](https://github.com/matter-labs/zksync-era/commit/caee55fef4eed0ec58cceaeba277bbdedf5c6f51)) +* **en:** Return `SyncState` health check ([#3142](https://github.com/matter-labs/zksync-era/issues/3142)) ([abeee81](https://github.com/matter-labs/zksync-era/commit/abeee8190d3c3a5e577d71024bdfb30ff516ad03)) +* **external-node:** delete empty unsealed batch on EN initialization ([#3125](https://github.com/matter-labs/zksync-era/issues/3125)) ([5d5214b](https://github.com/matter-labs/zksync-era/commit/5d5214ba983823b306495d34fdd1d46abacce07a)) +* Fix counter metric type to be Counter. ([#3153](https://github.com/matter-labs/zksync-era/issues/3153)) ([08a3fe7](https://github.com/matter-labs/zksync-era/commit/08a3fe7ffd0410c51334193068649905337d5e84)) +* **mempool:** minor mempool improvements ([#3113](https://github.com/matter-labs/zksync-era/issues/3113)) ([cd16083](https://github.com/matter-labs/zksync-era/commit/cd160830a0b7ebe5af4ecbd944da1cd51af3528a)) +* **prover:** Run for zero queue to allow scaling down to 0 ([#3115](https://github.com/matter-labs/zksync-era/issues/3115)) ([bbe1919](https://github.com/matter-labs/zksync-era/commit/bbe191937fa5c5711a7164fd4f0c2ae65cda0833)) +* restore instruction count functionality ([#3081](https://github.com/matter-labs/zksync-era/issues/3081)) ([6159f75](https://github.com/matter-labs/zksync-era/commit/6159f7531a0340a69c4926c4e0325811ed7cabb8)) +* **state-keeper:** save call trace for upgrade txs ([#3132](https://github.com/matter-labs/zksync-era/issues/3132)) ([e1c363f](https://github.com/matter-labs/zksync-era/commit/e1c363f8f5e03c8d62bba1523f17b87d6a0e25ad)) +* **tee_prover:** add zstd compression ([#3144](https://github.com/matter-labs/zksync-era/issues/3144)) ([7241ae1](https://github.com/matter-labs/zksync-era/commit/7241ae139b2b6bf9a9966eaa2f22203583a3786f)) +* **tee_verifier:** correctly initialize storage for re-execution ([#3017](https://github.com/matter-labs/zksync-era/issues/3017)) ([9d88373](https://github.com/matter-labs/zksync-era/commit/9d88373f1b745c489e98e5ef542644a70e815498)) + ## [24.29.0](https://github.com/matter-labs/zksync-era/compare/core-v24.28.0...core-v24.29.0) (2024-10-14) diff --git a/core/bin/external_node/Cargo.toml b/core/bin/external_node/Cargo.toml index 25f2400c79bb..4e3dc548cf89 100644 --- a/core/bin/external_node/Cargo.toml +++ b/core/bin/external_node/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "zksync_external_node" description = "Non-validator ZKsync node" -version = "24.29.0" # x-release-please-version +version = "25.0.0" # x-release-please-version edition.workspace = true authors.workspace = true homepage.workspace = true From bfedac03b53055c6e2d5fa6bd6bdc78e2cb1724c Mon Sep 17 00:00:00 2001 From: Yury Akudovich Date: Wed, 23 Oct 2024 15:07:41 +0200 Subject: [PATCH 14/27] feat(prover): Autoscaler sends scale request to appropriate agents. (#3150) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## What ❔ Add feature for Autoscaler to send scale request to appropriate agents. ## Why ❔ ## Checklist - [x] PR title corresponds to the body of PR (we generate changelog entries from PRs). - [ ] Tests for the changes have been added / updated. - [ ] Documentation comments have been added / updated. - [x] Code has been formatted via `zkstack dev fmt` and `zkstack dev lint`. ref ZKD-1855 --- .../crates/bin/prover_autoscaler/src/agent.rs | 4 +- .../prover_autoscaler/src/cluster_types.rs | 2 + .../prover_autoscaler/src/global/scaler.rs | 96 +++++++++++++++--- .../prover_autoscaler/src/global/watcher.rs | 97 ++++++++++++++++++- 4 files changed, 177 insertions(+), 22 deletions(-) diff --git a/prover/crates/bin/prover_autoscaler/src/agent.rs b/prover/crates/bin/prover_autoscaler/src/agent.rs index 3269a43815c9..f810bc416721 100644 --- a/prover/crates/bin/prover_autoscaler/src/agent.rs +++ b/prover/crates/bin/prover_autoscaler/src/agent.rs @@ -84,14 +84,14 @@ async fn get_cluster(State(app): State) -> Result, AppError> Ok(Json(cluster)) } -#[derive(Clone, Debug, Serialize, Deserialize)] +#[derive(Clone, Debug, Default, Serialize, Deserialize)] pub struct ScaleDeploymentRequest { pub namespace: String, pub name: String, pub size: i32, } -#[derive(Clone, Debug, Serialize, Deserialize)] +#[derive(Clone, Debug, Default, Serialize, Deserialize)] pub struct ScaleRequest { pub deployments: Vec, } diff --git a/prover/crates/bin/prover_autoscaler/src/cluster_types.rs b/prover/crates/bin/prover_autoscaler/src/cluster_types.rs index c25b624b5d43..b800b86f3c28 100644 --- a/prover/crates/bin/prover_autoscaler/src/cluster_types.rs +++ b/prover/crates/bin/prover_autoscaler/src/cluster_types.rs @@ -45,6 +45,8 @@ pub struct Cluster { #[derive(Debug, Default, Clone, Serialize, Deserialize)] pub struct Clusters { pub clusters: HashMap, + /// Map from cluster to index in agent URLs Vec. + pub agent_ids: HashMap, } #[derive(Default, Debug, EnumString, Display, Hash, PartialEq, Eq, Clone, Copy)] diff --git a/prover/crates/bin/prover_autoscaler/src/global/scaler.rs b/prover/crates/bin/prover_autoscaler/src/global/scaler.rs index f10902f5dd2f..884174562a10 100644 --- a/prover/crates/bin/prover_autoscaler/src/global/scaler.rs +++ b/prover/crates/bin/prover_autoscaler/src/global/scaler.rs @@ -8,6 +8,7 @@ use zksync_config::configs::prover_autoscaler::{Gpu, ProverAutoscalerScalerConfi use super::{queuer, watcher}; use crate::{ + agent::{ScaleDeploymentRequest, ScaleRequest}, cluster_types::{Cluster, Clusters, Pod, PodStatus}, metrics::AUTOSCALER_METRICS, task_wiring::Task, @@ -48,6 +49,16 @@ static PROVER_DEPLOYMENT_RE: Lazy = static PROVER_POD_RE: Lazy = Lazy::new(|| Regex::new(r"^circuit-prover-gpu(-(?[ltvpa]\d+))?").unwrap()); +/// gpu_to_prover converts Gpu type to corresponding deployment name. +fn gpu_to_prover(gpu: Gpu) -> String { + let s = "circuit-prover-gpu"; + match gpu { + Gpu::Unknown => "".into(), + Gpu::L4 => s.into(), + _ => format!("{}-{}", s, gpu.to_string().to_lowercase()), + } +} + pub struct Scaler { /// namespace to Protocol Version configuration. namespaces: HashMap, @@ -299,6 +310,47 @@ impl Scaler { } } +fn diff( + namespace: &str, + provers: HashMap, + clusters: &Clusters, + requests: &mut HashMap, +) { + provers + .into_iter() + .for_each(|(GPUPoolKey { cluster, gpu }, n)| { + let prover = gpu_to_prover(gpu); + clusters + .clusters + .get(&cluster) + .and_then(|c| c.namespaces.get(namespace)) + .and_then(|ns| ns.deployments.get(&prover)) + .map_or_else( + || { + tracing::error!( + "Wasn't able to find deployment {} in cluster {}, namespace {}", + prover, + cluster, + namespace + ) + }, + |d| { + if d.desired != n as i32 { + requests + .entry(cluster.clone()) + .or_default() + .deployments + .push(ScaleDeploymentRequest { + namespace: namespace.into(), + name: prover.clone(), + size: n as i32, + }); + } + }, + ); + }) +} + /// is_namespace_running returns true if there are some pods running in it. fn is_namespace_running(namespace: &str, clusters: &Clusters) -> bool { clusters @@ -309,7 +361,7 @@ fn is_namespace_running(namespace: &str, clusters: &Clusters) -> bool { .flat_map(|v| v.deployments.values()) .map( |d| d.running + d.desired, // If there is something running or expected to run, we - // should consider the namespace. + // should re-evaluate the namespace. ) .sum::() > 0 @@ -320,24 +372,32 @@ impl Task for Scaler { async fn invoke(&self) -> anyhow::Result<()> { let queue = self.queuer.get_queue().await.unwrap(); - let guard = self.watcher.data.lock().await; - if let Err(err) = watcher::check_is_ready(&guard.is_ready) { - AUTOSCALER_METRICS.clusters_not_ready.inc(); - tracing::warn!("Skipping Scaler run: {}", err); - return Ok(()); - } + let mut scale_requests: HashMap = HashMap::new(); + { + let guard = self.watcher.data.lock().await; // Keeping the lock during all calls of run() for + // consitency. + if let Err(err) = watcher::check_is_ready(&guard.is_ready) { + AUTOSCALER_METRICS.clusters_not_ready.inc(); + tracing::warn!("Skipping Scaler run: {}", err); + return Ok(()); + } - for (ns, ppv) in &self.namespaces { - let q = queue.queue.get(ppv).cloned().unwrap_or(0); - tracing::debug!("Running eval for namespace {ns} and PPV {ppv} found queue {q}"); - if q > 0 || is_namespace_running(ns, &guard.clusters) { - let provers = self.run(ns, q, &guard.clusters); - for (k, num) in &provers { - AUTOSCALER_METRICS.provers[&(k.cluster.clone(), ns.clone(), k.gpu)] - .set(*num as u64); + for (ns, ppv) in &self.namespaces { + let q = queue.queue.get(ppv).cloned().unwrap_or(0); + tracing::debug!("Running eval for namespace {ns} and PPV {ppv} found queue {q}"); + if q > 0 || is_namespace_running(ns, &guard.clusters) { + let provers = self.run(ns, q, &guard.clusters); + for (k, num) in &provers { + AUTOSCALER_METRICS.provers[&(k.cluster.clone(), ns.clone(), k.gpu)] + .set(*num as u64); + } + diff(ns, provers, &guard.clusters, &mut scale_requests); } - // TODO: compare before and desired, send commands [cluster,namespace,deployment] -> provers } + } // Unlock self.watcher.data. + + if let Err(err) = self.watcher.send_scale(scale_requests).await { + tracing::error!("Failed scale request: {}", err); } Ok(()) @@ -401,6 +461,7 @@ mod tests { }, )] .into(), + ..Default::default() }, ), [( @@ -467,6 +528,7 @@ mod tests { ) ] .into(), + ..Default::default() }, ), [ @@ -552,6 +614,7 @@ mod tests { ) ] .into(), + ..Default::default() }, ), [ @@ -662,6 +725,7 @@ mod tests { ) ] .into(), + ..Default::default() }, ), [ diff --git a/prover/crates/bin/prover_autoscaler/src/global/watcher.rs b/prover/crates/bin/prover_autoscaler/src/global/watcher.rs index 646b320e12df..1b54d332ebb1 100644 --- a/prover/crates/bin/prover_autoscaler/src/global/watcher.rs +++ b/prover/crates/bin/prover_autoscaler/src/global/watcher.rs @@ -2,12 +2,17 @@ use std::{collections::HashMap, sync::Arc}; use anyhow::{anyhow, Context, Ok, Result}; use futures::future; -use reqwest::Method; +use reqwest::{ + header::{HeaderMap, HeaderValue, CONTENT_TYPE}, + Method, +}; + use tokio::sync::Mutex; use url::Url; use zksync_utils::http_with_retries::send_request_with_retries; use crate::{ + agent::{ScaleRequest, ScaleResponse}, cluster_types::{Cluster, Clusters}, metrics::{AUTOSCALER_METRICS, DEFAULT_ERROR_CODE}, task_wiring::Task, @@ -51,13 +56,96 @@ impl Watcher { }) .collect(), data: Arc::new(Mutex::new(WatchedData { - clusters: Clusters { - clusters: HashMap::new(), - }, + clusters: Clusters::default(), is_ready: vec![false; size], })), } } + + pub async fn send_scale(&self, requests: HashMap) -> anyhow::Result<()> { + let id_requests: HashMap; + { + // Convert cluster names into ids. Holding the data lock. + let guard = self.data.lock().await; + id_requests = requests + .into_iter() + .filter_map(|(cluster, scale_request)| { + guard.clusters.agent_ids.get(&cluster).map_or_else( + || { + tracing::error!("Failed to find id for cluster {}", cluster); + None + }, + |id| Some((*id, scale_request)), + ) + }) + .collect(); + } + + let handles: Vec<_> = id_requests + .into_iter() + .map(|(id, sr)| { + let url: String = self.cluster_agents[id] + .clone() + .join("/scale") + .unwrap() + .to_string(); + tracing::debug!("Sending scale request to {}, data: {:?}.", url, sr); + tokio::spawn(async move { + let mut headers = HeaderMap::new(); + headers.insert(CONTENT_TYPE, HeaderValue::from_static("application/json")); + let response = send_request_with_retries( + &url, + MAX_RETRIES, + Method::POST, + Some(headers), + Some(serde_json::to_vec(&sr)?), + ) + .await; + let response = response.map_err(|err| { + AUTOSCALER_METRICS.calls[&(url.clone(), DEFAULT_ERROR_CODE)].inc(); + anyhow::anyhow!("Failed fetching cluster from url: {url}: {err:?}") + })?; + AUTOSCALER_METRICS.calls[&(url, response.status().as_u16())].inc(); + let response = response + .json::() + .await + .context("Failed to read response as json"); + Ok((id, response)) + }) + }) + .collect(); + + future::try_join_all( + future::join_all(handles) + .await + .into_iter() + .map(|h| async move { + let (id, res) = h??; + + let errors: Vec<_> = res + .expect("failed to do request to Agent") + .scale_result + .iter() + .filter_map(|e| { + if !e.is_empty() { + Some(format!("Agent {} failed to scale: {}", id, e)) + } else { + None + } + }) + .collect(); + + if !errors.is_empty() { + return Err(anyhow!(errors.join(";"))); + } + Ok(()) + }) + .collect::>(), + ) + .await?; + + Ok(()) + } } #[async_trait::async_trait] @@ -102,6 +190,7 @@ impl Task for Watcher { let (i, res) = h??; let c = res?; let mut guard = self.data.lock().await; + guard.clusters.agent_ids.insert(c.name.clone(), i); guard.clusters.clusters.insert(c.name.clone(), c); guard.is_ready[i] = true; Ok(()) From c79949b8ffde9867b961192afa6c815b44865ae4 Mon Sep 17 00:00:00 2001 From: Yury Akudovich Date: Wed, 23 Oct 2024 16:10:41 +0200 Subject: [PATCH 15/27] fix: Fix Doc lint. (#3158) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## What ❔ Fix error found by Doc lint. ## Why ❔ ## Checklist - [x] PR title corresponds to the body of PR (we generate changelog entries from PRs). - [ ] Tests for the changes have been added / updated. - [ ] Documentation comments have been added / updated. - [x] Code has been formatted via `zkstack dev fmt` and `zkstack dev lint`. ref ZKD-1855 --- prover/crates/bin/prover_autoscaler/src/global/watcher.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/prover/crates/bin/prover_autoscaler/src/global/watcher.rs b/prover/crates/bin/prover_autoscaler/src/global/watcher.rs index 1b54d332ebb1..6e02c0fe2fdc 100644 --- a/prover/crates/bin/prover_autoscaler/src/global/watcher.rs +++ b/prover/crates/bin/prover_autoscaler/src/global/watcher.rs @@ -6,7 +6,6 @@ use reqwest::{ header::{HeaderMap, HeaderValue, CONTENT_TYPE}, Method, }; - use tokio::sync::Mutex; use url::Url; use zksync_utils::http_with_retries::send_request_with_retries; From 84986f44b32d0a7fa68c3f60b1ec266ce663e778 Mon Sep 17 00:00:00 2001 From: Alex Ostrovski Date: Wed, 23 Oct 2024 17:20:20 +0300 Subject: [PATCH 16/27] test(vm): Run `multivm` tests with shadowing (#3137) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## What ❔ Runs shared unit tests in the `multivm` crate for the shadowed VM. ## Why ❔ Allows to cheaply check VM divergences. ## Checklist - [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`. --- core/lib/multivm/README.md | 2 + core/lib/multivm/src/versions/mod.rs | 2 + .../{testonly/shadow.rs => shadow/mod.rs} | 2 + core/lib/multivm/src/versions/shadow/tests.rs | 415 ++++++++++++++++++ .../versions/testonly/get_used_contracts.rs | 25 +- core/lib/multivm/src/versions/testonly/mod.rs | 12 +- .../src/versions/testonly/tester/mod.rs | 2 +- .../src/versions/vm_latest/tests/mod.rs | 9 +- core/lib/vm_interface/src/utils/dump.rs | 12 + core/lib/vm_interface/src/utils/mod.rs | 4 +- core/lib/vm_interface/src/utils/shadow.rs | 340 ++++++++------ 11 files changed, 674 insertions(+), 151 deletions(-) rename core/lib/multivm/src/versions/{testonly/shadow.rs => shadow/mod.rs} (99%) create mode 100644 core/lib/multivm/src/versions/shadow/tests.rs diff --git a/core/lib/multivm/README.md b/core/lib/multivm/README.md index f5e8a552242a..34883db5990a 100644 --- a/core/lib/multivm/README.md +++ b/core/lib/multivm/README.md @@ -14,5 +14,7 @@ If you want to add unit tests for the VM wrapper, consider the following: - Whenever possible, make tests reusable; declare test logic in the [`testonly`](src/versions/testonly/mod.rs) module, and then instantiate tests using this logic for the supported VM versions. If necessary, extend the tested VM trait so that test logic can be defined in a generic way. See the `testonly` module docs for more detailed guidelines. +- If you define a generic test, don't forget to add its instantiations for all supported VMs (`vm_latest`, `vm_fast` and + `shadow`). `shadow` tests allow checking VM divergences for free! - Do not use an RNG where it can be avoided (e.g., for test contract addresses). - Avoid using zero / default values in cases they can be treated specially by the tested code. diff --git a/core/lib/multivm/src/versions/mod.rs b/core/lib/multivm/src/versions/mod.rs index 1df706a6cce5..b6523b3d474a 100644 --- a/core/lib/multivm/src/versions/mod.rs +++ b/core/lib/multivm/src/versions/mod.rs @@ -1,3 +1,5 @@ +#[cfg(test)] +mod shadow; mod shared; #[cfg(test)] mod testonly; diff --git a/core/lib/multivm/src/versions/testonly/shadow.rs b/core/lib/multivm/src/versions/shadow/mod.rs similarity index 99% rename from core/lib/multivm/src/versions/testonly/shadow.rs rename to core/lib/multivm/src/versions/shadow/mod.rs index 6a7d42b06fca..fe9ce8eefcb9 100644 --- a/core/lib/multivm/src/versions/testonly/shadow.rs +++ b/core/lib/multivm/src/versions/shadow/mod.rs @@ -28,6 +28,8 @@ use crate::{ vm_latest::HistoryEnabled, }; +mod tests; + type ReferenceVm = vm_latest::Vm, HistoryEnabled>; type ShadowedFastVm = crate::vm_instance::ShadowedFastVm; diff --git a/core/lib/multivm/src/versions/shadow/tests.rs b/core/lib/multivm/src/versions/shadow/tests.rs new file mode 100644 index 000000000000..64179f59be16 --- /dev/null +++ b/core/lib/multivm/src/versions/shadow/tests.rs @@ -0,0 +1,415 @@ +//! Unit tests from the `testonly` test suite. + +use std::collections::HashSet; + +use zksync_types::{writes::StateDiffRecord, StorageKey, Transaction, H256, U256}; + +use super::ShadowedFastVm; +use crate::{ + interface::{ + utils::{ShadowMut, ShadowRef}, + CurrentExecutionState, L2BlockEnv, VmExecutionMode, VmExecutionResultAndLogs, + }, + versions::testonly::TestedVm, +}; + +impl TestedVm for ShadowedFastVm { + type StateDump = (); + + fn dump_state(&self) -> Self::StateDump { + // Do nothing + } + + fn gas_remaining(&mut self) -> u32 { + self.get_mut("gas_remaining", |r| match r { + ShadowMut::Main(vm) => vm.gas_remaining(), + ShadowMut::Shadow(vm) => vm.gas_remaining(), + }) + } + + fn get_current_execution_state(&self) -> CurrentExecutionState { + self.get_custom("current_execution_state", |r| match r { + ShadowRef::Main(vm) => vm.get_current_execution_state(), + ShadowRef::Shadow(vm) => vm.get_current_execution_state(), + }) + } + + fn decommitted_hashes(&self) -> HashSet { + self.get("decommitted_hashes", |r| match r { + ShadowRef::Main(vm) => vm.decommitted_hashes(), + ShadowRef::Shadow(vm) => TestedVm::decommitted_hashes(vm), + }) + } + + fn execute_with_state_diffs( + &mut self, + diffs: Vec, + mode: VmExecutionMode, + ) -> VmExecutionResultAndLogs { + self.get_custom_mut("execute_with_state_diffs", |r| match r { + ShadowMut::Main(vm) => vm.execute_with_state_diffs(diffs.clone(), mode), + ShadowMut::Shadow(vm) => vm.execute_with_state_diffs(diffs.clone(), mode), + }) + } + + fn insert_bytecodes(&mut self, bytecodes: &[&[u8]]) { + self.get_mut("insert_bytecodes", |r| match r { + ShadowMut::Main(vm) => vm.insert_bytecodes(bytecodes), + ShadowMut::Shadow(vm) => TestedVm::insert_bytecodes(vm, bytecodes), + }); + } + + fn known_bytecode_hashes(&self) -> HashSet { + self.get("known_bytecode_hashes", |r| match r { + ShadowRef::Main(vm) => vm.known_bytecode_hashes(), + ShadowRef::Shadow(vm) => vm.known_bytecode_hashes(), + }) + } + + fn manually_decommit(&mut self, code_hash: H256) -> bool { + self.get_mut("manually_decommit", |r| match r { + ShadowMut::Main(vm) => vm.manually_decommit(code_hash), + ShadowMut::Shadow(vm) => vm.manually_decommit(code_hash), + }) + } + + fn verify_required_bootloader_heap(&self, cells: &[(u32, U256)]) { + self.get("verify_required_bootloader_heap", |r| match r { + ShadowRef::Main(vm) => vm.verify_required_bootloader_heap(cells), + ShadowRef::Shadow(vm) => vm.verify_required_bootloader_heap(cells), + }); + } + + fn write_to_bootloader_heap(&mut self, cells: &[(usize, U256)]) { + self.get_mut("manually_decommit", |r| match r { + ShadowMut::Main(vm) => vm.write_to_bootloader_heap(cells), + ShadowMut::Shadow(vm) => TestedVm::write_to_bootloader_heap(vm, cells), + }); + } + + fn read_storage(&mut self, key: StorageKey) -> U256 { + self.get_mut("read_storage", |r| match r { + ShadowMut::Main(vm) => vm.read_storage(key), + ShadowMut::Shadow(vm) => vm.read_storage(key), + }) + } + + fn last_l2_block_hash(&self) -> H256 { + self.get("last_l2_block_hash", |r| match r { + ShadowRef::Main(vm) => vm.last_l2_block_hash(), + ShadowRef::Shadow(vm) => vm.last_l2_block_hash(), + }) + } + + fn push_l2_block_unchecked(&mut self, block: L2BlockEnv) { + self.get_mut("push_l2_block_unchecked", |r| match r { + ShadowMut::Main(vm) => vm.push_l2_block_unchecked(block), + ShadowMut::Shadow(vm) => vm.push_l2_block_unchecked(block), + }); + } + + fn push_transaction_with_refund(&mut self, tx: Transaction, refund: u64) { + self.get_mut("push_transaction_with_refund", |r| match r { + ShadowMut::Main(vm) => vm.push_transaction_with_refund(tx.clone(), refund), + ShadowMut::Shadow(vm) => vm.push_transaction_with_refund(tx.clone(), refund), + }); + } +} + +mod block_tip { + use crate::versions::testonly::block_tip::*; + + #[test] + fn dry_run_upper_bound() { + test_dry_run_upper_bound::(); + } +} + +mod bootloader { + use crate::versions::testonly::bootloader::*; + + #[test] + fn dummy_bootloader() { + test_dummy_bootloader::(); + } + + #[test] + fn bootloader_out_of_gas() { + test_bootloader_out_of_gas::(); + } +} + +mod bytecode_publishing { + use crate::versions::testonly::bytecode_publishing::*; + + #[test] + fn bytecode_publishing() { + test_bytecode_publishing::(); + } +} + +mod circuits { + use crate::versions::testonly::circuits::*; + + #[test] + fn circuits() { + test_circuits::(); + } +} + +mod code_oracle { + use crate::versions::testonly::code_oracle::*; + + #[test] + fn code_oracle() { + test_code_oracle::(); + } + + #[test] + fn code_oracle_big_bytecode() { + test_code_oracle_big_bytecode::(); + } + + #[test] + fn refunds_in_code_oracle() { + test_refunds_in_code_oracle::(); + } +} + +mod default_aa { + use crate::versions::testonly::default_aa::*; + + #[test] + fn default_aa_interaction() { + test_default_aa_interaction::(); + } +} + +mod gas_limit { + use crate::versions::testonly::gas_limit::*; + + #[test] + fn tx_gas_limit_offset() { + test_tx_gas_limit_offset::(); + } +} + +mod get_used_contracts { + use crate::versions::testonly::get_used_contracts::*; + + #[test] + fn get_used_contracts() { + test_get_used_contracts::(); + } + + #[test] + fn get_used_contracts_with_far_call() { + test_get_used_contracts_with_far_call::(); + } + + #[test] + fn get_used_contracts_with_out_of_gas_far_call() { + test_get_used_contracts_with_out_of_gas_far_call::(); + } +} + +mod is_write_initial { + use crate::versions::testonly::is_write_initial::*; + + #[test] + fn is_write_initial_behaviour() { + test_is_write_initial_behaviour::(); + } +} + +mod l1_tx_execution { + use crate::versions::testonly::l1_tx_execution::*; + + #[test] + fn l1_tx_execution() { + test_l1_tx_execution::(); + } + + #[test] + fn l1_tx_execution_high_gas_limit() { + test_l1_tx_execution_high_gas_limit::(); + } +} + +mod l2_blocks { + use crate::versions::testonly::l2_blocks::*; + + #[test] + fn l2_block_initialization_timestamp() { + test_l2_block_initialization_timestamp::(); + } + + #[test] + fn l2_block_initialization_number_non_zero() { + test_l2_block_initialization_number_non_zero::(); + } + + #[test] + fn l2_block_same_l2_block() { + test_l2_block_same_l2_block::(); + } + + #[test] + fn l2_block_new_l2_block() { + test_l2_block_new_l2_block::(); + } + + #[test] + fn l2_block_first_in_batch() { + test_l2_block_first_in_batch::(); + } +} + +mod nonce_holder { + use crate::versions::testonly::nonce_holder::*; + + #[test] + fn nonce_holder() { + test_nonce_holder::(); + } +} + +mod precompiles { + use crate::versions::testonly::precompiles::*; + + #[test] + fn keccak() { + test_keccak::(); + } + + #[test] + fn sha256() { + test_sha256::(); + } + + #[test] + fn ecrecover() { + test_ecrecover::(); + } +} + +mod refunds { + use crate::versions::testonly::refunds::*; + + #[test] + fn predetermined_refunded_gas() { + test_predetermined_refunded_gas::(); + } + + #[test] + fn negative_pubdata_for_transaction() { + test_negative_pubdata_for_transaction::(); + } +} + +mod require_eip712 { + use crate::versions::testonly::require_eip712::*; + + #[test] + fn require_eip712() { + test_require_eip712::(); + } +} + +mod rollbacks { + use crate::versions::testonly::rollbacks::*; + + #[test] + fn vm_rollbacks() { + test_vm_rollbacks::(); + } + + #[test] + fn vm_loadnext_rollbacks() { + test_vm_loadnext_rollbacks::(); + } + + #[test] + fn rollback_in_call_mode() { + test_rollback_in_call_mode::(); + } +} + +mod secp256r1 { + use crate::versions::testonly::secp256r1::*; + + #[test] + fn secp256r1() { + test_secp256r1::(); + } +} + +mod simple_execution { + use crate::versions::testonly::simple_execution::*; + + #[test] + fn estimate_fee() { + test_estimate_fee::(); + } + + #[test] + fn simple_execute() { + test_simple_execute::(); + } +} + +mod storage { + use crate::versions::testonly::storage::*; + + #[test] + fn storage_behavior() { + test_storage_behavior::(); + } + + #[test] + fn transient_storage_behavior() { + test_transient_storage_behavior::(); + } +} + +mod tracing_execution_error { + use crate::versions::testonly::tracing_execution_error::*; + + #[test] + fn tracing_of_execution_errors() { + test_tracing_of_execution_errors::(); + } +} + +mod transfer { + use crate::versions::testonly::transfer::*; + + #[test] + fn send_and_transfer() { + test_send_and_transfer::(); + } + + #[test] + fn reentrancy_protection_send_and_transfer() { + test_reentrancy_protection_send_and_transfer::(); + } +} + +mod upgrade { + use crate::versions::testonly::upgrade::*; + + #[test] + fn protocol_upgrade_is_first() { + test_protocol_upgrade_is_first::(); + } + + #[test] + fn force_deploy_upgrade() { + test_force_deploy_upgrade::(); + } + + #[test] + fn complex_upgrader() { + test_complex_upgrader::(); + } +} diff --git a/core/lib/multivm/src/versions/testonly/get_used_contracts.rs b/core/lib/multivm/src/versions/testonly/get_used_contracts.rs index fbad94a0eee3..d3ffee20c344 100644 --- a/core/lib/multivm/src/versions/testonly/get_used_contracts.rs +++ b/core/lib/multivm/src/versions/testonly/get_used_contracts.rs @@ -1,4 +1,4 @@ -use std::{collections::HashSet, iter}; +use std::iter; use assert_matches::assert_matches; use ethabi::Token; @@ -11,7 +11,7 @@ use zksync_utils::{bytecode::hash_bytecode, h256_to_u256}; use super::{ read_proxy_counter_contract, read_test_contract, tester::{VmTester, VmTesterBuilder}, - TestedVm, BASE_SYSTEM_CONTRACTS, + TestedVm, }; use crate::{ interface::{ @@ -27,7 +27,7 @@ pub(crate) fn test_get_used_contracts() { .with_rich_accounts(1) .build::(); - assert!(known_bytecodes_without_base_system_contracts(&vm.vm).is_empty()); + assert!(vm.vm.known_bytecode_hashes().is_empty()); // create and push and execute some not-empty factory deps transaction with success status // to check that `get_decommitted_hashes()` updates @@ -44,10 +44,7 @@ pub(crate) fn test_get_used_contracts() { .contains(&h256_to_u256(tx.bytecode_hash))); // Note: `Default_AA` will be in the list of used contracts if L2 tx is used - assert_eq!( - vm.vm.decommitted_hashes(), - known_bytecodes_without_base_system_contracts(&vm.vm) - ); + assert_eq!(vm.vm.decommitted_hashes(), vm.vm.known_bytecode_hashes()); // create push and execute some non-empty factory deps transaction that fails // (`known_bytecodes` will be updated but we expect `get_decommitted_hashes()` to not be updated) @@ -80,23 +77,11 @@ pub(crate) fn test_get_used_contracts() { for factory_dep in tx2.execute.factory_deps { let hash = hash_bytecode(&factory_dep); let hash_to_u256 = h256_to_u256(hash); - assert!(known_bytecodes_without_base_system_contracts(&vm.vm).contains(&hash_to_u256)); + assert!(vm.vm.known_bytecode_hashes().contains(&hash_to_u256)); assert!(!vm.vm.decommitted_hashes().contains(&hash_to_u256)); } } -fn known_bytecodes_without_base_system_contracts(vm: &impl TestedVm) -> HashSet { - let mut known_bytecodes_without_base_system_contracts = vm.known_bytecode_hashes(); - known_bytecodes_without_base_system_contracts - .remove(&h256_to_u256(BASE_SYSTEM_CONTRACTS.default_aa.hash)); - if let Some(evm_emulator) = &BASE_SYSTEM_CONTRACTS.evm_emulator { - let was_removed = - known_bytecodes_without_base_system_contracts.remove(&h256_to_u256(evm_emulator.hash)); - assert!(was_removed); - } - known_bytecodes_without_base_system_contracts -} - /// Counter test contract bytecode inflated by appending lots of `NOP` opcodes at the end. This leads to non-trivial /// decommitment cost (>10,000 gas). fn inflated_counter_bytecode() -> Vec { diff --git a/core/lib/multivm/src/versions/testonly/mod.rs b/core/lib/multivm/src/versions/testonly/mod.rs index 838ba98a9aab..74cda6a95229 100644 --- a/core/lib/multivm/src/versions/testonly/mod.rs +++ b/core/lib/multivm/src/versions/testonly/mod.rs @@ -9,6 +9,8 @@ //! - Tests use [`VmTester`] built using [`VmTesterBuilder`] to create a VM instance. This allows to set up storage for the VM, //! custom [`SystemEnv`] / [`L1BatchEnv`], deployed contracts, pre-funded accounts etc. +use std::collections::HashSet; + use ethabi::Contract; use once_cell::sync::Lazy; use zksync_contracts::{ @@ -20,7 +22,7 @@ use zksync_types::{ utils::storage_key_for_eth_balance, Address, L1BatchNumber, L2BlockNumber, L2ChainId, ProtocolVersionId, U256, }; -use zksync_utils::{bytecode::hash_bytecode, bytes_to_be_words, u256_to_h256}; +use zksync_utils::{bytecode::hash_bytecode, bytes_to_be_words, h256_to_u256, u256_to_h256}; use zksync_vm_interface::{L1BatchEnv, L2BlockEnv, SystemEnv, TxExecutionMode}; pub(super) use self::tester::{TestedVm, VmTester, VmTesterBuilder}; @@ -45,7 +47,6 @@ pub(super) mod refunds; pub(super) mod require_eip712; pub(super) mod rollbacks; pub(super) mod secp256r1; -mod shadow; pub(super) mod simple_execution; pub(super) mod storage; mod tester; @@ -133,6 +134,13 @@ pub(crate) fn get_bootloader(test: &str) -> SystemContractCode { } } +pub(crate) fn filter_out_base_system_contracts(all_bytecode_hashes: &mut HashSet) { + all_bytecode_hashes.remove(&h256_to_u256(BASE_SYSTEM_CONTRACTS.default_aa.hash)); + if let Some(evm_emulator) = &BASE_SYSTEM_CONTRACTS.evm_emulator { + all_bytecode_hashes.remove(&h256_to_u256(evm_emulator.hash)); + } +} + pub(super) fn default_system_env() -> SystemEnv { SystemEnv { zk_porter_available: false, diff --git a/core/lib/multivm/src/versions/testonly/tester/mod.rs b/core/lib/multivm/src/versions/testonly/tester/mod.rs index 4bab9bca610e..7432322e0c8d 100644 --- a/core/lib/multivm/src/versions/testonly/tester/mod.rs +++ b/core/lib/multivm/src/versions/testonly/tester/mod.rs @@ -195,7 +195,7 @@ pub(crate) trait TestedVm: fn insert_bytecodes(&mut self, bytecodes: &[&[u8]]); - /// Includes bytecodes that have failed to decommit. + /// Includes bytecodes that have failed to decommit. Should exclude base system contract bytecodes (default AA / EVM emulator). fn known_bytecode_hashes(&self) -> HashSet; /// Returns `true` iff the decommit is fresh. diff --git a/core/lib/multivm/src/versions/vm_latest/tests/mod.rs b/core/lib/multivm/src/versions/vm_latest/tests/mod.rs index 2835f5b6faa0..6f748d543d35 100644 --- a/core/lib/multivm/src/versions/vm_latest/tests/mod.rs +++ b/core/lib/multivm/src/versions/vm_latest/tests/mod.rs @@ -14,7 +14,7 @@ use crate::{ storage::{InMemoryStorage, ReadStorage, StorageView, WriteStorage}, CurrentExecutionState, L2BlockEnv, VmExecutionMode, VmExecutionResultAndLogs, }, - versions::testonly::TestedVm, + versions::testonly::{filter_out_base_system_contracts, TestedVm}, vm_latest::{ constants::BOOTLOADER_HEAP_PAGE, old_vm::{event_sink::InMemoryEventSink, history_recorder::HistoryRecorder}, @@ -104,13 +104,16 @@ impl TestedVm for TestedLatestVm { } fn known_bytecode_hashes(&self) -> HashSet { - self.state + let mut bytecode_hashes: HashSet<_> = self + .state .decommittment_processor .known_bytecodes .inner() .keys() .copied() - .collect() + .collect(); + filter_out_base_system_contracts(&mut bytecode_hashes); + bytecode_hashes } fn manually_decommit(&mut self, code_hash: H256) -> bool { diff --git a/core/lib/vm_interface/src/utils/dump.rs b/core/lib/vm_interface/src/utils/dump.rs index 522a455a11ba..4076aa72270b 100644 --- a/core/lib/vm_interface/src/utils/dump.rs +++ b/core/lib/vm_interface/src/utils/dump.rs @@ -139,6 +139,18 @@ impl DumpingVm { } } +impl AsRef for DumpingVm { + fn as_ref(&self) -> &Vm { + &self.inner + } +} + +impl AsMut for DumpingVm { + fn as_mut(&mut self) -> &mut Vm { + &mut self.inner + } +} + impl VmInterface for DumpingVm { type TracerDispatcher = Vm::TracerDispatcher; diff --git a/core/lib/vm_interface/src/utils/mod.rs b/core/lib/vm_interface/src/utils/mod.rs index 80a51c7b144f..394df7fc9a1d 100644 --- a/core/lib/vm_interface/src/utils/mod.rs +++ b/core/lib/vm_interface/src/utils/mod.rs @@ -2,7 +2,9 @@ pub use self::{ dump::VmDump, - shadow::{DivergenceErrors, DivergenceHandler, ShadowVm}, + shadow::{ + CheckDivergence, DivergenceErrors, DivergenceHandler, ShadowMut, ShadowRef, ShadowVm, + }, }; mod dump; diff --git a/core/lib/vm_interface/src/utils/shadow.rs b/core/lib/vm_interface/src/utils/shadow.rs index 8cdc899238e4..e8ef87c3c7f8 100644 --- a/core/lib/vm_interface/src/utils/shadow.rs +++ b/core/lib/vm_interface/src/utils/shadow.rs @@ -1,4 +1,5 @@ use std::{ + any, cell::RefCell, collections::{BTreeMap, BTreeSet}, fmt, @@ -65,6 +66,154 @@ impl VmWithReporting { } } +/// Reference to either the main or shadow VM. +#[derive(Debug)] +pub enum ShadowRef<'a, Main, Shadow> { + /// Reference to the main VM. + Main(&'a Main), + /// Reference to the shadow VM. + Shadow(&'a Shadow), +} + +/// Mutable reference to either the main or shadow VM. +#[derive(Debug)] +pub enum ShadowMut<'a, Main, Shadow> { + /// Reference to the main VM. + Main(&'a mut Main), + /// Reference to the shadow VM. + Shadow(&'a mut Shadow), +} + +/// Type that can check divergence between its instances. +pub trait CheckDivergence { + /// Checks divergences and returns a list of divergence errors, if any. + fn check_divergence(&self, other: &Self) -> DivergenceErrors; +} + +#[derive(Debug)] +struct DivergingEq(T); + +impl CheckDivergence for DivergingEq { + fn check_divergence(&self, other: &Self) -> DivergenceErrors { + let mut errors = DivergenceErrors::new(); + errors.check_match(any::type_name::(), &self.0, &other.0); + errors + } +} + +impl CheckDivergence for CurrentExecutionState { + fn check_divergence(&self, other: &Self) -> DivergenceErrors { + let mut errors = DivergenceErrors::new(); + errors.check_match("final_state.events", &self.events, &other.events); + errors.check_match( + "final_state.user_l2_to_l1_logs", + &self.user_l2_to_l1_logs, + &other.user_l2_to_l1_logs, + ); + errors.check_match( + "final_state.system_logs", + &self.system_logs, + &other.system_logs, + ); + errors.check_match( + "final_state.storage_refunds", + &self.storage_refunds, + &other.storage_refunds, + ); + errors.check_match( + "final_state.pubdata_costs", + &self.pubdata_costs, + &other.pubdata_costs, + ); + errors.check_match( + "final_state.used_contract_hashes", + &self.used_contract_hashes.iter().collect::>(), + &other.used_contract_hashes.iter().collect::>(), + ); + + let main_deduplicated_logs = DivergenceErrors::gather_logs(&self.deduplicated_storage_logs); + let shadow_deduplicated_logs = + DivergenceErrors::gather_logs(&other.deduplicated_storage_logs); + errors.check_match( + "deduplicated_storage_logs", + &main_deduplicated_logs, + &shadow_deduplicated_logs, + ); + errors + } +} + +impl CheckDivergence for VmExecutionResultAndLogs { + fn check_divergence(&self, other: &Self) -> DivergenceErrors { + let mut errors = DivergenceErrors::new(); + errors.check_match("result", &self.result, &other.result); + errors.check_match("logs.events", &self.logs.events, &other.logs.events); + errors.check_match( + "logs.system_l2_to_l1_logs", + &self.logs.system_l2_to_l1_logs, + &other.logs.system_l2_to_l1_logs, + ); + errors.check_match( + "logs.user_l2_to_l1_logs", + &self.logs.user_l2_to_l1_logs, + &other.logs.user_l2_to_l1_logs, + ); + let main_logs = UniqueStorageLogs::new(&self.logs.storage_logs); + let shadow_logs = UniqueStorageLogs::new(&other.logs.storage_logs); + errors.check_match("logs.storage_logs", &main_logs, &shadow_logs); + errors.check_match("refunds", &self.refunds, &other.refunds); + errors.check_match( + "statistics.circuit_statistic", + &self.statistics.circuit_statistic, + &other.statistics.circuit_statistic, + ); + errors.check_match( + "statistics.pubdata_published", + &self.statistics.pubdata_published, + &other.statistics.pubdata_published, + ); + errors.check_match( + "statistics.gas_remaining", + &self.statistics.gas_remaining, + &other.statistics.gas_remaining, + ); + errors.check_match( + "statistics.gas_used", + &self.statistics.gas_used, + &other.statistics.gas_used, + ); + errors.check_match( + "statistics.computational_gas_used", + &self.statistics.computational_gas_used, + &other.statistics.computational_gas_used, + ); + errors + } +} + +impl CheckDivergence for FinishedL1Batch { + fn check_divergence(&self, other: &Self) -> DivergenceErrors { + let mut errors = DivergenceErrors::new(); + errors.extend( + self.block_tip_execution_result + .check_divergence(&other.block_tip_execution_result), + ); + errors.extend( + self.final_execution_state + .check_divergence(&other.final_execution_state), + ); + + errors.check_match( + "final_bootloader_memory", + &self.final_bootloader_memory, + &other.final_bootloader_memory, + ); + errors.check_match("pubdata_input", &self.pubdata_input, &other.pubdata_input); + errors.check_match("state_diffs", &self.state_diffs, &other.state_diffs); + errors + } +} + /// Shadowed VM that executes 2 VMs for each operation and compares their outputs. /// /// If a divergence is detected, the VM state is dumped using [a pluggable handler](Self::set_dump_handler()), @@ -105,6 +254,66 @@ where pub fn dump_state(&self) -> VmDump { self.main.dump_state() } + + /// Gets the specified value from both the main and shadow VM, checking whether it matches on both. + pub fn get(&self, name: &str, mut action: impl FnMut(ShadowRef<'_, Main, Shadow>) -> R) -> R + where + R: PartialEq + fmt::Debug + 'static, + { + self.get_custom(name, |r| DivergingEq(action(r))).0 + } + + /// Same as [`Self::get()`], but uses custom divergence checks for the type encapsulated in the [`CheckDivergence`] trait. + pub fn get_custom( + &self, + name: &str, + mut action: impl FnMut(ShadowRef<'_, Main, Shadow>) -> R, + ) -> R { + let main_output = action(ShadowRef::Main(self.main.as_ref())); + let borrow = self.shadow.borrow(); + if let Some(shadow) = &*borrow { + let shadow_output = action(ShadowRef::Shadow(&shadow.vm)); + let errors = main_output.check_divergence(&shadow_output); + if let Err(err) = errors.into_result() { + drop(borrow); + self.report_shared(err.context(format!("get({name})"))); + } + } + main_output + } + + /// Gets the specified value from both the main and shadow VM, potentially changing their state + /// and checking whether the returned value matches. + pub fn get_mut( + &mut self, + name: &str, + mut action: impl FnMut(ShadowMut<'_, Main, Shadow>) -> R, + ) -> R + where + R: PartialEq + fmt::Debug + 'static, + { + self.get_custom_mut(name, |r| DivergingEq(action(r))).0 + } + + /// Same as [`Self::get_mut()`], but uses custom divergence checks for the type encapsulated in the [`CheckDivergence`] trait. + pub fn get_custom_mut( + &mut self, + name: &str, + mut action: impl FnMut(ShadowMut<'_, Main, Shadow>) -> R, + ) -> R + where + R: CheckDivergence, + { + let main_output = action(ShadowMut::Main(self.main.as_mut())); + if let Some(shadow) = self.shadow.get_mut() { + let shadow_output = action(ShadowMut::Shadow(&mut shadow.vm)); + let errors = main_output.check_divergence(&shadow_output); + if let Err(err) = errors.into_result() { + self.report_shared(err.context(format!("get_mut({name})"))); + } + } + main_output + } } impl ShadowVm @@ -151,7 +360,6 @@ where } } -/// **Important.** This doesn't properly handle tracers; they are not passed to the shadow VM! impl VmInterface for ShadowVm where S: ReadStorage, @@ -197,9 +405,7 @@ where let main_result = self.main.inspect(main_tracer, execution_mode); if let Some(shadow) = self.shadow.get_mut() { let shadow_result = shadow.vm.inspect(shadow_tracer, execution_mode); - let mut errors = DivergenceErrors::new(); - errors.check_results_match(&main_result, &shadow_result); - + let errors = main_result.check_divergence(&shadow_result); if let Err(err) = errors.into_result() { let ctx = format!("executing VM with mode {execution_mode:?}"); self.report(err.context(ctx)); @@ -240,8 +446,7 @@ where tx, with_compression, ); - let mut errors = DivergenceErrors::new(); - errors.check_results_match(&main_tx_result, &shadow_result.1); + let errors = main_tx_result.check_divergence(&shadow_result.1); if let Err(err) = errors.into_result() { let ctx = format!( "inspecting transaction {tx_repr}, with_compression={with_compression:?}" @@ -256,31 +461,7 @@ where let main_batch = self.main.finish_batch(); if let Some(shadow) = self.shadow.get_mut() { let shadow_batch = shadow.vm.finish_batch(); - let mut errors = DivergenceErrors::new(); - errors.check_results_match( - &main_batch.block_tip_execution_result, - &shadow_batch.block_tip_execution_result, - ); - errors.check_final_states_match( - &main_batch.final_execution_state, - &shadow_batch.final_execution_state, - ); - errors.check_match( - "final_bootloader_memory", - &main_batch.final_bootloader_memory, - &shadow_batch.final_bootloader_memory, - ); - errors.check_match( - "pubdata_input", - &main_batch.pubdata_input, - &shadow_batch.pubdata_input, - ); - errors.check_match( - "state_diffs", - &main_batch.state_diffs, - &shadow_batch.state_diffs, - ); - + let errors = main_batch.check_divergence(&shadow_batch); if let Err(err) = errors.into_result() { self.report(err); } @@ -321,63 +502,15 @@ impl DivergenceErrors { } } + fn extend(&mut self, from: Self) { + self.divergences.extend(from.divergences); + } + fn context(mut self, context: String) -> Self { self.context = Some(context); self } - fn check_results_match( - &mut self, - main_result: &VmExecutionResultAndLogs, - shadow_result: &VmExecutionResultAndLogs, - ) { - self.check_match("result", &main_result.result, &shadow_result.result); - self.check_match( - "logs.events", - &main_result.logs.events, - &shadow_result.logs.events, - ); - self.check_match( - "logs.system_l2_to_l1_logs", - &main_result.logs.system_l2_to_l1_logs, - &shadow_result.logs.system_l2_to_l1_logs, - ); - self.check_match( - "logs.user_l2_to_l1_logs", - &main_result.logs.user_l2_to_l1_logs, - &shadow_result.logs.user_l2_to_l1_logs, - ); - let main_logs = UniqueStorageLogs::new(&main_result.logs.storage_logs); - let shadow_logs = UniqueStorageLogs::new(&shadow_result.logs.storage_logs); - self.check_match("logs.storage_logs", &main_logs, &shadow_logs); - self.check_match("refunds", &main_result.refunds, &shadow_result.refunds); - self.check_match( - "statistics.circuit_statistic", - &main_result.statistics.circuit_statistic, - &shadow_result.statistics.circuit_statistic, - ); - self.check_match( - "statistics.pubdata_published", - &main_result.statistics.pubdata_published, - &shadow_result.statistics.pubdata_published, - ); - self.check_match( - "statistics.gas_remaining", - &main_result.statistics.gas_remaining, - &shadow_result.statistics.gas_remaining, - ); - self.check_match( - "statistics.gas_used", - &main_result.statistics.gas_used, - &shadow_result.statistics.gas_used, - ); - self.check_match( - "statistics.computational_gas_used", - &main_result.statistics.computational_gas_used, - &shadow_result.statistics.computational_gas_used, - ); - } - fn check_match(&mut self, context: &str, main: &T, shadow: &T) { if main != shadow { let comparison = pretty_assertions::Comparison::new(main, shadow); @@ -386,47 +519,6 @@ impl DivergenceErrors { } } - fn check_final_states_match( - &mut self, - main: &CurrentExecutionState, - shadow: &CurrentExecutionState, - ) { - self.check_match("final_state.events", &main.events, &shadow.events); - self.check_match( - "final_state.user_l2_to_l1_logs", - &main.user_l2_to_l1_logs, - &shadow.user_l2_to_l1_logs, - ); - self.check_match( - "final_state.system_logs", - &main.system_logs, - &shadow.system_logs, - ); - self.check_match( - "final_state.storage_refunds", - &main.storage_refunds, - &shadow.storage_refunds, - ); - self.check_match( - "final_state.pubdata_costs", - &main.pubdata_costs, - &shadow.pubdata_costs, - ); - self.check_match( - "final_state.used_contract_hashes", - &main.used_contract_hashes.iter().collect::>(), - &shadow.used_contract_hashes.iter().collect::>(), - ); - - let main_deduplicated_logs = Self::gather_logs(&main.deduplicated_storage_logs); - let shadow_deduplicated_logs = Self::gather_logs(&shadow.deduplicated_storage_logs); - self.check_match( - "deduplicated_storage_logs", - &main_deduplicated_logs, - &shadow_deduplicated_logs, - ); - } - fn gather_logs(logs: &[StorageLog]) -> BTreeMap { logs.iter() .filter(|log| log.is_write()) From 0aecae1e02d31d34d1ccc0ddf54617174d134e55 Mon Sep 17 00:00:00 2001 From: Manuel Mauro Date: Wed, 23 Oct 2024 18:00:00 +0200 Subject: [PATCH 17/27] feat(zkstack_cli): Add --dev flag to chain init and genesis (#3152) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## What ❔ Add `--dev` flag to chain init and genesis. ## Why ❔ ## Checklist - [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`. --- .../crates/zkstack/completion/_zkstack.zsh | 19 ++--- .../crates/zkstack/completion/zkstack.fish | 7 +- .../crates/zkstack/completion/zkstack.sh | 10 +-- .../src/commands/chain/args/genesis.rs | 4 +- .../src/commands/chain/args/init/mod.rs | 73 +++++++++++++------ .../src/commands/ecosystem/args/init.rs | 24 ++++-- .../zkstack/src/commands/ecosystem/init.rs | 9 ++- zkstack_cli/crates/zkstack/src/messages.rs | 4 +- 8 files changed, 94 insertions(+), 56 deletions(-) diff --git a/zkstack_cli/crates/zkstack/completion/_zkstack.zsh b/zkstack_cli/crates/zkstack/completion/_zkstack.zsh index a8a60a6130a6..b985f5b93346 100644 --- a/zkstack_cli/crates/zkstack/completion/_zkstack.zsh +++ b/zkstack_cli/crates/zkstack/completion/_zkstack.zsh @@ -131,12 +131,10 @@ _arguments "${_arguments_options[@]}" : \ '--observability=[Enable Grafana]' \ '--chain=[Chain to use]:CHAIN: ' \ '--resume[]' \ -'-u[Use default database urls and names]' \ -'--use-default[Use default database urls and names]' \ '-d[]' \ '--dont-drop[]' \ '--ecosystem-only[Initialize ecosystem only and skip chain initialization (chain can be initialized later with \`chain init\` subcommand)]' \ -'--dev[Deploy ecosystem using all defaults. Suitable for local development]' \ +'--dev[Use defaults for all options and flags. Suitable for local development]' \ '--no-port-reallocation[Do not reallocate ports]' \ '-v[Verbose mode]' \ '--verbose[Verbose mode]' \ @@ -286,11 +284,10 @@ _arguments "${_arguments_options[@]}" : \ '--l1-rpc-url=[L1 RPC URL]:L1_RPC_URL: ' \ '--chain=[Chain to use]:CHAIN: ' \ '--resume[]' \ -'-u[Use default database urls and names]' \ -'--use-default[Use default database urls and names]' \ '-d[]' \ '--dont-drop[]' \ '--no-port-reallocation[Do not reallocate ports]' \ +'--dev[Use defaults for all options and flags. Suitable for local development]' \ '-v[Verbose mode]' \ '--verbose[Verbose mode]' \ '--ignore-prerequisites[Ignores prerequisites checks]' \ @@ -312,8 +309,8 @@ _arguments "${_arguments_options[@]}" : \ '--server-db-name=[Server database name]:SERVER_DB_NAME: ' \ '--l1-rpc-url=[L1 RPC URL]:L1_RPC_URL: ' \ '--chain=[Chain to use]:CHAIN: ' \ -'-u[Use default database urls and names]' \ -'--use-default[Use default database urls and names]' \ +'-d[Use default database urls and names]' \ +'--dev[Use default database urls and names]' \ '-d[]' \ '--dont-drop[]' \ '--no-port-reallocation[Do not reallocate ports]' \ @@ -357,8 +354,8 @@ _arguments "${_arguments_options[@]}" : \ '--server-db-url=[Server database url without database name]:SERVER_DB_URL: ' \ '--server-db-name=[Server database name]:SERVER_DB_NAME: ' \ '--chain=[Chain to use]:CHAIN: ' \ -'-u[Use default database urls and names]' \ -'--use-default[Use default database urls and names]' \ +'-d[Use default database urls and names]' \ +'--dev[Use default database urls and names]' \ '-d[]' \ '--dont-drop[]' \ '-v[Verbose mode]' \ @@ -381,8 +378,8 @@ _arguments "${_arguments_options[@]}" : \ '--server-db-url=[Server database url without database name]:SERVER_DB_URL: ' \ '--server-db-name=[Server database name]:SERVER_DB_NAME: ' \ '--chain=[Chain to use]:CHAIN: ' \ -'-u[Use default database urls and names]' \ -'--use-default[Use default database urls and names]' \ +'-d[Use default database urls and names]' \ +'--dev[Use default database urls and names]' \ '-d[]' \ '--dont-drop[]' \ '-v[Verbose mode]' \ diff --git a/zkstack_cli/crates/zkstack/completion/zkstack.fish b/zkstack_cli/crates/zkstack/completion/zkstack.fish index d490085e6154..f90bcf2c4ac3 100644 --- a/zkstack_cli/crates/zkstack/completion/zkstack.fish +++ b/zkstack_cli/crates/zkstack/completion/zkstack.fish @@ -107,10 +107,9 @@ complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and __fish_se complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and __fish_seen_subcommand_from init" -s o -l observability -d 'Enable Grafana' -r -f -a "{true\t'',false\t''}" complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and __fish_seen_subcommand_from init" -l chain -d 'Chain to use' -r complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and __fish_seen_subcommand_from init" -l resume -complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and __fish_seen_subcommand_from init" -s u -l use-default -d 'Use default database urls and names' complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and __fish_seen_subcommand_from init" -s d -l dont-drop complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and __fish_seen_subcommand_from init" -l ecosystem-only -d 'Initialize ecosystem only and skip chain initialization (chain can be initialized later with `chain init` subcommand)' -complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and __fish_seen_subcommand_from init" -l dev -d 'Deploy ecosystem using all defaults. Suitable for local development' +complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and __fish_seen_subcommand_from init" -l dev -d 'Use defaults for all options and flags. Suitable for local development' complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and __fish_seen_subcommand_from init" -l no-port-reallocation -d 'Do not reallocate ports' complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and __fish_seen_subcommand_from init" -s v -l verbose -d 'Verbose mode' complete -c zkstack -n "__fish_zkstack_using_subcommand ecosystem; and __fish_seen_subcommand_from init" -l ignore-prerequisites -d 'Ignores prerequisites checks' @@ -185,9 +184,9 @@ complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_s complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from init" -l l1-rpc-url -d 'L1 RPC URL' -r complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from init" -l chain -d 'Chain to use' -r complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from init" -l resume -complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from init" -s u -l use-default -d 'Use default database urls and names' complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from init" -s d -l dont-drop complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from init" -l no-port-reallocation -d 'Do not reallocate ports' +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from init" -l dev -d 'Use defaults for all options and flags. Suitable for local development' complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from init" -s v -l verbose -d 'Verbose mode' complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from init" -l ignore-prerequisites -d 'Ignores prerequisites checks' complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from init" -s h -l help -d 'Print help (see more with \'--help\')' @@ -196,7 +195,7 @@ complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_s complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from genesis" -l server-db-url -d 'Server database url without database name' -r complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from genesis" -l server-db-name -d 'Server database name' -r complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from genesis" -l chain -d 'Chain to use' -r -complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from genesis" -s u -l use-default -d 'Use default database urls and names' +complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from genesis" -s d -l dev -d 'Use default database urls and names' complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from genesis" -s d -l dont-drop complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from genesis" -s v -l verbose -d 'Verbose mode' complete -c zkstack -n "__fish_zkstack_using_subcommand chain; and __fish_seen_subcommand_from genesis" -l ignore-prerequisites -d 'Ignores prerequisites checks' diff --git a/zkstack_cli/crates/zkstack/completion/zkstack.sh b/zkstack_cli/crates/zkstack/completion/zkstack.sh index 27639acd50be..d21480bba2ca 100644 --- a/zkstack_cli/crates/zkstack/completion/zkstack.sh +++ b/zkstack_cli/crates/zkstack/completion/zkstack.sh @@ -1441,7 +1441,7 @@ _zkstack() { return 0 ;; zkstack__chain__genesis) - opts="-u -d -v -h --server-db-url --server-db-name --use-default --dont-drop --verbose --chain --ignore-prerequisites --help init-database server help" + opts="-d -d -v -h --server-db-url --server-db-name --dev --dont-drop --verbose --chain --ignore-prerequisites --help init-database server help" if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -1523,7 +1523,7 @@ _zkstack() { return 0 ;; zkstack__chain__genesis__init__database) - opts="-u -d -v -h --server-db-url --server-db-name --use-default --dont-drop --verbose --chain --ignore-prerequisites --help" + opts="-d -d -v -h --server-db-url --server-db-name --dev --dont-drop --verbose --chain --ignore-prerequisites --help" if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -1819,7 +1819,7 @@ _zkstack() { return 0 ;; zkstack__chain__init) - opts="-a -u -d -v -h --verify --verifier --verifier-url --verifier-api-key --resume --additional-args --server-db-url --server-db-name --use-default --dont-drop --deploy-paymaster --l1-rpc-url --no-port-reallocation --verbose --chain --ignore-prerequisites --help configs help" + opts="-a -d -v -h --verify --verifier --verifier-url --verifier-api-key --resume --additional-args --server-db-url --server-db-name --dont-drop --deploy-paymaster --l1-rpc-url --no-port-reallocation --dev --verbose --chain --ignore-prerequisites --help configs help" if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -1877,7 +1877,7 @@ _zkstack() { return 0 ;; zkstack__chain__init__configs) - opts="-u -d -v -h --server-db-url --server-db-name --use-default --dont-drop --l1-rpc-url --no-port-reallocation --verbose --chain --ignore-prerequisites --help" + opts="-d -d -v -h --server-db-url --server-db-name --dev --dont-drop --l1-rpc-url --no-port-reallocation --verbose --chain --ignore-prerequisites --help" if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -4829,7 +4829,7 @@ _zkstack() { return 0 ;; zkstack__ecosystem__init) - opts="-a -u -d -o -v -h --deploy-erc20 --deploy-ecosystem --ecosystem-contracts-path --l1-rpc-url --verify --verifier --verifier-url --verifier-api-key --resume --additional-args --deploy-paymaster --server-db-url --server-db-name --use-default --dont-drop --ecosystem-only --dev --observability --no-port-reallocation --verbose --chain --ignore-prerequisites --help" + opts="-a -d -o -v -h --deploy-erc20 --deploy-ecosystem --ecosystem-contracts-path --l1-rpc-url --verify --verifier --verifier-url --verifier-api-key --resume --additional-args --deploy-paymaster --server-db-url --server-db-name --dont-drop --ecosystem-only --dev --observability --no-port-reallocation --verbose --chain --ignore-prerequisites --help" if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 diff --git a/zkstack_cli/crates/zkstack/src/commands/chain/args/genesis.rs b/zkstack_cli/crates/zkstack/src/commands/chain/args/genesis.rs index aaf995985a36..f990cbfd77da 100644 --- a/zkstack_cli/crates/zkstack/src/commands/chain/args/genesis.rs +++ b/zkstack_cli/crates/zkstack/src/commands/chain/args/genesis.rs @@ -21,7 +21,7 @@ pub struct GenesisArgs { #[clap(long, help = MSG_SERVER_DB_NAME_HELP)] pub server_db_name: Option, #[clap(long, short, help = MSG_USE_DEFAULT_DATABASES_HELP)] - pub use_default: bool, + pub dev: bool, #[clap(long, short, action)] pub dont_drop: bool, } @@ -30,7 +30,7 @@ impl GenesisArgs { pub fn fill_values_with_prompt(self, config: &ChainConfig) -> GenesisArgsFinal { let DBNames { server_name, .. } = generate_db_names(config); let chain_name = config.name.clone(); - if self.use_default { + if self.dev { GenesisArgsFinal { server_db: DatabaseConfig::new(DATABASE_SERVER_URL.clone(), server_name), dont_drop: self.dont_drop, diff --git a/zkstack_cli/crates/zkstack/src/commands/chain/args/init/mod.rs b/zkstack_cli/crates/zkstack/src/commands/chain/args/init/mod.rs index d92de9a0641b..a5c7a6890ca1 100644 --- a/zkstack_cli/crates/zkstack/src/commands/chain/args/init/mod.rs +++ b/zkstack_cli/crates/zkstack/src/commands/chain/args/init/mod.rs @@ -9,8 +9,9 @@ use crate::{ commands::chain::args::genesis::{GenesisArgs, GenesisArgsFinal}, defaults::LOCAL_RPC_URL, messages::{ - MSG_DEPLOY_PAYMASTER_PROMPT, MSG_GENESIS_ARGS_HELP, MSG_L1_RPC_URL_HELP, + MSG_DEPLOY_PAYMASTER_PROMPT, MSG_DEV_ARG_HELP, MSG_L1_RPC_URL_HELP, MSG_L1_RPC_URL_INVALID_ERR, MSG_L1_RPC_URL_PROMPT, MSG_NO_PORT_REALLOCATION_HELP, + MSG_SERVER_DB_NAME_HELP, MSG_SERVER_DB_URL_HELP, }, }; @@ -22,45 +23,70 @@ pub struct InitArgs { #[clap(flatten)] #[serde(flatten)] pub forge_args: ForgeScriptArgs, - #[clap(flatten, next_help_heading = MSG_GENESIS_ARGS_HELP)] - #[serde(flatten)] - pub genesis_args: GenesisArgs, + #[clap(long, help = MSG_SERVER_DB_URL_HELP)] + pub server_db_url: Option, + #[clap(long, help = MSG_SERVER_DB_NAME_HELP)] + pub server_db_name: Option, + #[clap(long, short, action)] + pub dont_drop: bool, #[clap(long, default_missing_value = "true", num_args = 0..=1)] pub deploy_paymaster: Option, #[clap(long, help = MSG_L1_RPC_URL_HELP)] pub l1_rpc_url: Option, #[clap(long, help = MSG_NO_PORT_REALLOCATION_HELP)] pub no_port_reallocation: bool, + #[clap(long, help = MSG_DEV_ARG_HELP)] + pub dev: bool, } impl InitArgs { + pub fn get_genesis_args(&self) -> GenesisArgs { + GenesisArgs { + server_db_url: self.server_db_url.clone(), + server_db_name: self.server_db_name.clone(), + dev: self.dev, + dont_drop: self.dont_drop, + } + } + pub fn fill_values_with_prompt(self, config: &ChainConfig) -> InitArgsFinal { - let deploy_paymaster = self.deploy_paymaster.unwrap_or_else(|| { - common::PromptConfirm::new(MSG_DEPLOY_PAYMASTER_PROMPT) - .default(true) - .ask() - }); + let genesis = self.get_genesis_args(); + + let deploy_paymaster = if self.dev { + true + } else { + self.deploy_paymaster.unwrap_or_else(|| { + common::PromptConfirm::new(MSG_DEPLOY_PAYMASTER_PROMPT) + .default(true) + .ask() + }) + }; - let l1_rpc_url = self.l1_rpc_url.unwrap_or_else(|| { - let mut prompt = Prompt::new(MSG_L1_RPC_URL_PROMPT); - if config.l1_network == L1Network::Localhost { - prompt = prompt.default(LOCAL_RPC_URL); - } - prompt - .validate_with(|val: &String| -> Result<(), String> { - Url::parse(val) - .map(|_| ()) - .map_err(|_| MSG_L1_RPC_URL_INVALID_ERR.to_string()) - }) - .ask() - }); + let l1_rpc_url = if self.dev { + LOCAL_RPC_URL.to_string() + } else { + self.l1_rpc_url.unwrap_or_else(|| { + let mut prompt = Prompt::new(MSG_L1_RPC_URL_PROMPT); + if config.l1_network == L1Network::Localhost { + prompt = prompt.default(LOCAL_RPC_URL); + } + prompt + .validate_with(|val: &String| -> Result<(), String> { + Url::parse(val) + .map(|_| ()) + .map_err(|_| MSG_L1_RPC_URL_INVALID_ERR.to_string()) + }) + .ask() + }) + }; InitArgsFinal { forge_args: self.forge_args, - genesis_args: self.genesis_args.fill_values_with_prompt(config), + genesis_args: genesis.fill_values_with_prompt(config), deploy_paymaster, l1_rpc_url, no_port_reallocation: self.no_port_reallocation, + dev: self.dev, } } } @@ -72,4 +98,5 @@ pub struct InitArgsFinal { pub deploy_paymaster: bool, pub l1_rpc_url: String, pub no_port_reallocation: bool, + pub dev: bool, } diff --git a/zkstack_cli/crates/zkstack/src/commands/ecosystem/args/init.rs b/zkstack_cli/crates/zkstack/src/commands/ecosystem/args/init.rs index a77a9c28ca93..09115fd49ba7 100644 --- a/zkstack_cli/crates/zkstack/src/commands/ecosystem/args/init.rs +++ b/zkstack_cli/crates/zkstack/src/commands/ecosystem/args/init.rs @@ -11,9 +11,9 @@ use crate::{ defaults::LOCAL_RPC_URL, messages::{ MSG_DEPLOY_ECOSYSTEM_PROMPT, MSG_DEPLOY_ERC20_PROMPT, MSG_DEV_ARG_HELP, - MSG_GENESIS_ARGS_HELP, MSG_L1_RPC_URL_HELP, MSG_L1_RPC_URL_INVALID_ERR, - MSG_L1_RPC_URL_PROMPT, MSG_NO_PORT_REALLOCATION_HELP, MSG_OBSERVABILITY_HELP, - MSG_OBSERVABILITY_PROMPT, + MSG_L1_RPC_URL_HELP, MSG_L1_RPC_URL_INVALID_ERR, MSG_L1_RPC_URL_PROMPT, + MSG_NO_PORT_REALLOCATION_HELP, MSG_OBSERVABILITY_HELP, MSG_OBSERVABILITY_PROMPT, + MSG_SERVER_DB_NAME_HELP, MSG_SERVER_DB_URL_HELP, }, }; @@ -86,9 +86,12 @@ pub struct EcosystemInitArgs { /// Deploy Paymaster contract #[clap(long, default_missing_value = "true", num_args = 0..=1)] pub deploy_paymaster: Option, - #[clap(flatten, next_help_heading = MSG_GENESIS_ARGS_HELP)] - #[serde(flatten)] - pub genesis_args: GenesisArgs, + #[clap(long, help = MSG_SERVER_DB_URL_HELP)] + pub server_db_url: Option, + #[clap(long, help = MSG_SERVER_DB_NAME_HELP)] + pub server_db_name: Option, + #[clap(long, short, action)] + pub dont_drop: bool, /// Initialize ecosystem only and skip chain initialization (chain can be initialized later with `chain init` subcommand) #[clap(long, default_value_t = false)] pub ecosystem_only: bool, @@ -101,6 +104,15 @@ pub struct EcosystemInitArgs { } impl EcosystemInitArgs { + pub fn get_genesis_args(&self) -> GenesisArgs { + GenesisArgs { + server_db_url: self.server_db_url.clone(), + server_db_name: self.server_db_name.clone(), + dev: self.dev, + dont_drop: self.dont_drop, + } + } + pub fn fill_values_with_prompt(self, l1_network: L1Network) -> EcosystemInitArgsFinal { let deploy_erc20 = if self.dev { true diff --git a/zkstack_cli/crates/zkstack/src/commands/ecosystem/init.rs b/zkstack_cli/crates/zkstack/src/commands/ecosystem/init.rs index 6e006f8d65df..06b9b9161112 100644 --- a/zkstack_cli/crates/zkstack/src/commands/ecosystem/init.rs +++ b/zkstack_cli/crates/zkstack/src/commands/ecosystem/init.rs @@ -341,10 +341,10 @@ async fn init_chains( }; // Set default values for dev mode let mut deploy_paymaster = init_args.deploy_paymaster; - let mut genesis_args = init_args.genesis_args.clone(); + let mut genesis_args = init_args.get_genesis_args().clone(); if final_init_args.dev { deploy_paymaster = Some(true); - genesis_args.use_default = true; + genesis_args.dev = true; } // Can't initialize multiple chains with the same DB if list_of_chains.len() > 1 { @@ -359,10 +359,13 @@ async fn init_chains( let chain_init_args = chain::args::init::InitArgs { forge_args: final_init_args.forge_args.clone(), - genesis_args: genesis_args.clone(), + server_db_url: genesis_args.server_db_url.clone(), + server_db_name: genesis_args.server_db_name.clone(), + dont_drop: genesis_args.dont_drop, deploy_paymaster, l1_rpc_url: Some(final_init_args.ecosystem.l1_rpc_url.clone()), no_port_reallocation: final_init_args.no_port_reallocation, + dev: final_init_args.dev, }; let final_chain_init_args = chain_init_args.fill_values_with_prompt(&chain_config); diff --git a/zkstack_cli/crates/zkstack/src/messages.rs b/zkstack_cli/crates/zkstack/src/messages.rs index e2145c18ffd0..b9786dc4d8d1 100644 --- a/zkstack_cli/crates/zkstack/src/messages.rs +++ b/zkstack_cli/crates/zkstack/src/messages.rs @@ -15,6 +15,8 @@ pub(super) const MSG_SELECTED_CONFIG: &str = "Selected config"; pub(super) const MSG_CHAIN_NOT_INITIALIZED: &str = "Chain not initialized. Please create a chain first"; pub(super) const MSG_ARGS_VALIDATOR_ERR: &str = "Invalid arguments"; +pub(super) const MSG_DEV_ARG_HELP: &str = + "Use defaults for all options and flags. Suitable for local development"; /// Autocomplete message pub(super) fn msg_generate_autocomplete_file(filename: &str) -> String { @@ -61,8 +63,6 @@ pub(super) fn msg_path_to_zksync_does_not_exist_err(path: &str) -> String { pub(super) const MSG_L1_RPC_URL_HELP: &str = "L1 RPC URL"; pub(super) const MSG_NO_PORT_REALLOCATION_HELP: &str = "Do not reallocate ports"; pub(super) const MSG_GENESIS_ARGS_HELP: &str = "Genesis options"; -pub(super) const MSG_DEV_ARG_HELP: &str = - "Deploy ecosystem using all defaults. Suitable for local development"; pub(super) const MSG_OBSERVABILITY_HELP: &str = "Enable Grafana"; pub(super) const MSG_OBSERVABILITY_PROMPT: &str = "Do you want to setup observability? (Grafana)"; pub(super) const MSG_DEPLOY_ECOSYSTEM_PROMPT: &str = From 724d9a9c7f2127263845b640c843e751fd3c21ae Mon Sep 17 00:00:00 2001 From: Manuel Mauro Date: Wed, 23 Oct 2024 18:01:00 +0200 Subject: [PATCH 18/27] feat(zkstack_cli): Build dependencies at zkstack build time (#3157) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## What ❔ Build dependencies (e.g., `yarn install`) at `zkstack` build time. ## Why ❔ ## Checklist - [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`. --- zkstack_cli/crates/zkstack/Cargo.toml | 1 + zkstack_cli/crates/zkstack/build.rs | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/zkstack_cli/crates/zkstack/Cargo.toml b/zkstack_cli/crates/zkstack/Cargo.toml index 93a78c751b14..85ab8081eaa4 100644 --- a/zkstack_cli/crates/zkstack/Cargo.toml +++ b/zkstack_cli/crates/zkstack/Cargo.toml @@ -55,4 +55,5 @@ anyhow.workspace = true clap_complete.workspace = true dirs.workspace = true ethers.workspace = true +xshell.workspace = true zksync_protobuf_build.workspace = true diff --git a/zkstack_cli/crates/zkstack/build.rs b/zkstack_cli/crates/zkstack/build.rs index bccf5bae89f9..e52e952bf730 100644 --- a/zkstack_cli/crates/zkstack/build.rs +++ b/zkstack_cli/crates/zkstack/build.rs @@ -2,6 +2,7 @@ use std::path::{Path, PathBuf}; use anyhow::{anyhow, Context}; use ethers::contract::Abigen; +use xshell::{cmd, Shell}; const COMPLETION_DIR: &str = "completion"; @@ -14,6 +15,11 @@ fn main() -> anyhow::Result<()> { .write_to_file(outdir.join("consensus_registry_abi.rs")) .context("Failed to write ABI to file")?; + if let Err(e) = build_dependencies() { + println!("cargo:error=It was not possible to install projects dependencies"); + println!("cargo:error={}", e); + } + if let Err(e) = configure_shell_autocompletion() { println!("cargo:warning=It was not possible to install autocomplete scripts. Please generate them manually with `zkstack autocomplete`"); println!("cargo:error={}", e); @@ -130,3 +136,14 @@ impl ShellAutocomplete for clap_complete::Shell { Ok(()) } } + +fn build_dependencies() -> anyhow::Result<()> { + let shell = Shell::new()?; + let code_dir = Path::new("../"); + + let _dir_guard = shell.push_dir(code_dir); + + cmd!(shell, "yarn install") + .run() + .context("Failed to install dependencies") +} From 340a1786e32c8a4130ae4dafa26b8a545d0b3648 Mon Sep 17 00:00:00 2001 From: Yury Akudovich Date: Wed, 23 Oct 2024 18:07:33 +0200 Subject: [PATCH 19/27] docs: Add manual installation instruction for zkstack_cli (#3160) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## What ❔ Add manual installation instruction for zkstack_cli. ## Why ❔ Using `curl | bash` could be problematic, we should provide better way. ## Checklist - [x] PR title corresponds to the body of PR (we generate changelog entries from PRs). - [ ] Tests for the changes have been added / updated. - [ ] Documentation comments have been added / updated. - [x] Code has been formatted via `zkstack dev fmt` and `zkstack dev lint`. --- zkstack_cli/README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/zkstack_cli/README.md b/zkstack_cli/README.md index f1c92cc3d2e3..e81165088218 100644 --- a/zkstack_cli/README.md +++ b/zkstack_cli/README.md @@ -30,6 +30,16 @@ zkstackup --local This command installs `zkstack` from the current repository. +#### Manual installation + +Run from the repository root: + +```bash +cargo install --path zkstack_cli/crates/zkstack --force --locked +``` + +And make sure that `.cargo/bin` is included into `PATH`. + ### Foundry Integration Foundry is used for deploying smart contracts. Pass flags for Foundry integration with the `-a` option, e.g., From e7b587ac8afee4d27fb9dd9ab0f5c02beafbc42c Mon Sep 17 00:00:00 2001 From: Yury Akudovich Date: Wed, 23 Oct 2024 18:16:03 +0200 Subject: [PATCH 20/27] ci: Reduce GAR builder disk usage by moving keys around. (#3161) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## What ❔ Move keys from prover to circuit-prover as the build sequentially. Remove prover-gar image after it being uploaded. ## Why ❔ To allow running this on a machine with 100G disk. ## Checklist - [x] PR title corresponds to the body of PR (we generate changelog entries from PRs). - [ ] Tests for the changes have been added / updated. - [ ] Documentation comments have been added / updated. - [ ] Code has been formatted via `zkstack dev fmt` and `zkstack dev lint`. --- ...ild-prover-fri-gpu-gar-and-circuit-prover-gpu-gar.yml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build-prover-fri-gpu-gar-and-circuit-prover-gpu-gar.yml b/.github/workflows/build-prover-fri-gpu-gar-and-circuit-prover-gpu-gar.yml index b92fb8e81110..4639f8c77c41 100644 --- a/.github/workflows/build-prover-fri-gpu-gar-and-circuit-prover-gpu-gar.yml +++ b/.github/workflows/build-prover-fri-gpu-gar-and-circuit-prover-gpu-gar.yml @@ -28,7 +28,6 @@ jobs: - name: Download Setup data run: | gsutil -m rsync -r gs://matterlabs-setup-data-us/${{ inputs.setup_keys_id }} docker/prover-gpu-fri-gar - cp -v docker/prover-gpu-fri-gar/*.bin docker/circuit-prover-gpu-gar/ - name: Login to us-central1 GAR run: | @@ -70,6 +69,14 @@ jobs: --tag europe-docker.pkg.dev/matterlabs-infra/matterlabs-docker/prover-fri-gpu-gar:2.0-${{ inputs.protocol_version }}-${{ inputs.image_tag_suffix }} \ us-docker.pkg.dev/matterlabs-infra/matterlabs-docker/prover-fri-gpu-gar:2.0-${{ inputs.protocol_version }}-${{ inputs.image_tag_suffix }} + - name: Remove prover-gpu-fri-gar image to free space + run: | + docker image rm us-docker.pkg.dev/matterlabs-infra/matterlabs-docker/prover-fri-gpu-gar:2.0-${{ inputs.protocol_version }}-${{ inputs.image_tag_suffix }} + + - name: Move Setup data from prover-gpu-fri-gar to circuit-prover-gpu-gar + run: | + mv -v docker/prover-gpu-fri-gar/*.bin docker/circuit-prover-gpu-gar/ + - name: Build and push circuit-prover-gpu-gar uses: docker/build-push-action@5cd11c3a4ced054e52742c5fd54dca954e0edd85 # v6.7.0 with: From d0f61b0552dcacc2e8e33fdbcae6f1e5fbb43820 Mon Sep 17 00:00:00 2001 From: Ivan Schasny <31857042+ischasny@users.noreply.github.com> Date: Wed, 23 Oct 2024 18:43:34 +0100 Subject: [PATCH 21/27] fix: update logging in cbt l1 behaviour (#3149) Stop converting `BigDecimal` to `BigInt` when logging to avoid loosing precision. --- .../base_token_adjuster/src/base_token_l1_behaviour.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/core/node/base_token_adjuster/src/base_token_l1_behaviour.rs b/core/node/base_token_adjuster/src/base_token_l1_behaviour.rs index 0199b06ebd69..0922101e59de 100644 --- a/core/node/base_token_adjuster/src/base_token_l1_behaviour.rs +++ b/core/node/base_token_adjuster/src/base_token_l1_behaviour.rs @@ -6,7 +6,7 @@ use std::{ }; use anyhow::Context; -use bigdecimal::{num_bigint::ToBigInt, BigDecimal, Zero}; +use bigdecimal::{BigDecimal, Zero}; use zksync_config::BaseTokenAdjusterConfig; use zksync_eth_client::{BoundEthInterface, CallFunctionArgs, Options}; use zksync_node_fee_model::l1_gas_price::TxParamsProvider; @@ -57,7 +57,7 @@ impl BaseTokenL1Behaviour { self.update_last_persisted_l1_ratio(prev_ratio.clone()); tracing::info!( "Fetched current base token ratio from the L1: {}", - prev_ratio.to_bigint().unwrap() + prev_ratio ); prev_ratio }; @@ -71,7 +71,7 @@ impl BaseTokenL1Behaviour { "Skipping L1 update. current_ratio {}, previous_ratio {}, deviation {}", current_ratio, prev_ratio, - deviation.to_bigint().unwrap() + deviation ); return Ok(()); } @@ -98,7 +98,7 @@ impl BaseTokenL1Behaviour { new_ratio.denominator.get(), base_fee_per_gas, priority_fee_per_gas, - deviation.to_bigint().unwrap() + deviation ); METRICS .l1_gas_used From 4629450d2d40c2c4c28255e51d5bb67d588ba837 Mon Sep 17 00:00:00 2001 From: perekopskiy <53865202+perekopskiy@users.noreply.github.com> Date: Wed, 23 Oct 2024 21:33:32 +0300 Subject: [PATCH 22/27] ci: unify fmt check (#3159) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## What ❔ prover ci should check formatting with zkstack_cli ## Why ❔ ## Checklist - [ ] PR title corresponds to the body of PR (we generate changelog entries from PRs). - [ ] Tests for the changes have been added / updated. - [ ] Documentation comments have been added / updated. - [ ] Code has been formatted via `zkstack dev fmt` and `zkstack dev lint`. --- .github/workflows/ci-prover-reusable.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci-prover-reusable.yml b/.github/workflows/ci-prover-reusable.yml index 6cb9c26d21e7..4154885549b8 100644 --- a/.github/workflows/ci-prover-reusable.yml +++ b/.github/workflows/ci-prover-reusable.yml @@ -40,7 +40,9 @@ jobs: ci_run zkstack dev db setup --prover-url=${{ env.prover_url }} --core-url=${{ env.core_url }} - name: Formatting - run: ci_run bash -c "cd prover && cargo fmt --check" + run: | + ci_run git config --global --add safe.directory /usr/src/zksync + ci_run zkstack dev fmt --check rustfmt unit-tests: runs-on: [ matterlabs-ci-runner-highmem-long ] From 561fc1bddfc79061dab9d8d150baa06acfa90692 Mon Sep 17 00:00:00 2001 From: QEDK <1994constant@gmail.com> Date: Thu, 24 Oct 2024 06:04:10 +0530 Subject: [PATCH 23/27] feat: Implement gas relay mode and inclusion data for data attestation (#3070) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## What ❔ This PR adds gas relay API support for gasless submission to the Avail network, it also provides the attestation implementation necessary for data attestation. ## Why ❔ Gas relay API support is required for Avail partners that choose to pay in a different token. Data attestation ensures that arbitrary tx data cannot be used for rollup finality and that no data withholding attack can occur. ## Checklist - [X] PR title corresponds to the body of PR (we generate changelog entries from PRs). - [ ] Tests for the changes have been added / updated. - [X] Documentation comments have been added / updated. - [X] Code has been formatted via `zk fmt` and `zk lint`. Supersedes #2987 --------- Co-authored-by: vibhurajeev Co-authored-by: dimazhornyk Co-authored-by: Dima Zhornyk <55756184+dimazhornyk@users.noreply.github.com> --- .gitignore | 1 + Cargo.lock | 3 + Cargo.toml | 3 +- core/lib/basic_types/src/api_key.rs | 20 ++ core/lib/basic_types/src/lib.rs | 1 + .../lib/config/src/configs/da_client/avail.rs | 28 ++- core/lib/config/src/testonly.rs | 16 +- core/lib/env_config/src/da_client.rs | 80 +++++-- core/lib/protobuf_config/src/da_client.rs | 53 +++- .../src/proto/config/da_client.proto | 20 +- .../src/proto/config/secrets.proto | 1 + core/lib/protobuf_config/src/secrets.rs | 54 ++++- core/node/da_clients/Cargo.toml | 3 + core/node/da_clients/src/avail/client.rs | 226 +++++++++++++++--- core/node/da_clients/src/avail/sdk.rs | 100 +++++++- 15 files changed, 512 insertions(+), 97 deletions(-) create mode 100644 core/lib/basic_types/src/api_key.rs diff --git a/.gitignore b/.gitignore index 86ed40c70417..adf3b7799618 100644 --- a/.gitignore +++ b/.gitignore @@ -115,6 +115,7 @@ prover/data/keys/setup_* # ZK Stack CLI chains/era/configs/* chains/gateway/* +chains/avail/* configs/* era-observability/ core/tests/ts-integration/deployments-zk diff --git a/Cargo.lock b/Cargo.lock index 7e4cad34cf8f..a42ef8e3fdcc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10028,14 +10028,17 @@ version = "0.1.0" dependencies = [ "anyhow", "async-trait", + "backon", "base58", "blake2 0.10.6", "blake2b_simd", + "bytes", "flate2", "futures 0.3.30", "hex", "jsonrpsee 0.23.2", "parity-scale-codec", + "reqwest 0.12.7", "scale-encode", "serde", "serde_json", diff --git a/Cargo.toml b/Cargo.toml index f1e70e7f3028..0f8e6ba77ae6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -110,6 +110,7 @@ backon = "0.4.4" bigdecimal = "0.4.5" bincode = "1" blake2 = "0.10" +bytes = "1" chrono = "0.4" clap = "4.2.2" codegen = "0.2.0" @@ -155,7 +156,7 @@ rayon = "1.3.1" regex = "1" reqwest = "0.12" rlp = "0.5" -rocksdb = "0.21.0" +rocksdb = "0.21" rustc_version = "0.4.0" rustls = "0.23" secp256k1 = { version = "0.27.0", features = ["recovery", "global-context"] } diff --git a/core/lib/basic_types/src/api_key.rs b/core/lib/basic_types/src/api_key.rs new file mode 100644 index 000000000000..eadf4e9051b5 --- /dev/null +++ b/core/lib/basic_types/src/api_key.rs @@ -0,0 +1,20 @@ +use std::str::FromStr; + +use secrecy::{ExposeSecret, Secret}; + +#[derive(Debug, Clone)] +pub struct APIKey(pub Secret); + +impl PartialEq for APIKey { + fn eq(&self, other: &Self) -> bool { + self.0.expose_secret().eq(other.0.expose_secret()) + } +} + +impl FromStr for APIKey { + type Err = anyhow::Error; + + fn from_str(s: &str) -> Result { + Ok(APIKey(s.parse()?)) + } +} diff --git a/core/lib/basic_types/src/lib.rs b/core/lib/basic_types/src/lib.rs index 79c7b3924e34..7953f362fd42 100644 --- a/core/lib/basic_types/src/lib.rs +++ b/core/lib/basic_types/src/lib.rs @@ -24,6 +24,7 @@ use serde::{de, Deserialize, Deserializer, Serialize}; #[macro_use] mod macros; +pub mod api_key; pub mod basic_fri_types; pub mod commitment; pub mod network; diff --git a/core/lib/config/src/configs/da_client/avail.rs b/core/lib/config/src/configs/da_client/avail.rs index 590dc5fef18a..b8e9db0f3937 100644 --- a/core/lib/config/src/configs/da_client/avail.rs +++ b/core/lib/config/src/configs/da_client/avail.rs @@ -1,16 +1,38 @@ use serde::Deserialize; -use zksync_basic_types::seed_phrase::SeedPhrase; +use zksync_basic_types::{api_key::APIKey, seed_phrase::SeedPhrase}; + +pub const AVAIL_GAS_RELAY_CLIENT_NAME: &str = "GasRelay"; +pub const AVAIL_FULL_CLIENT_NAME: &str = "FullClient"; + +#[derive(Clone, Debug, PartialEq, Deserialize)] +#[serde(tag = "avail_client")] +pub enum AvailClientConfig { + FullClient(AvailDefaultConfig), + GasRelay(AvailGasRelayConfig), +} #[derive(Clone, Debug, PartialEq, Deserialize)] pub struct AvailConfig { - pub api_node_url: String, pub bridge_api_url: String, - pub app_id: u32, pub timeout: usize, + #[serde(flatten)] + pub config: AvailClientConfig, +} + +#[derive(Clone, Debug, PartialEq, Deserialize)] +pub struct AvailDefaultConfig { + pub api_node_url: String, + pub app_id: u32, +} + +#[derive(Clone, Debug, PartialEq, Deserialize)] +pub struct AvailGasRelayConfig { + pub gas_relay_api_url: String, pub max_retries: usize, } #[derive(Clone, Debug, PartialEq)] pub struct AvailSecrets { pub seed_phrase: Option, + pub gas_relay_api_key: Option, } diff --git a/core/lib/config/src/testonly.rs b/core/lib/config/src/testonly.rs index 9b1ec13e2d2e..880bc5aa98d2 100644 --- a/core/lib/config/src/testonly.rs +++ b/core/lib/config/src/testonly.rs @@ -3,6 +3,7 @@ use std::num::NonZeroUsize; use rand::{distributions::Distribution, Rng}; use secrecy::Secret; use zksync_basic_types::{ + api_key::APIKey, basic_fri_types::CircuitIdRoundTuple, commitment::L1BatchCommitmentMode, network::Network, @@ -17,7 +18,12 @@ use zksync_crypto_primitives::K256PrivateKey; use crate::{ configs::{ - self, da_client::DAClientConfig::Avail, external_price_api_client::ForcedPriceClientConfig, + self, + da_client::{ + avail::{AvailClientConfig, AvailDefaultConfig}, + DAClientConfig::Avail, + }, + external_price_api_client::ForcedPriceClientConfig, }, AvailConfig, }; @@ -935,11 +941,12 @@ impl Distribution for EncodeDist { impl Distribution for EncodeDist { fn sample(&self, rng: &mut R) -> configs::da_client::DAClientConfig { Avail(AvailConfig { - api_node_url: self.sample(rng), bridge_api_url: self.sample(rng), - app_id: self.sample(rng), timeout: self.sample(rng), - max_retries: self.sample(rng), + config: AvailClientConfig::FullClient(AvailDefaultConfig { + api_node_url: self.sample(rng), + app_id: self.sample(rng), + }), }) } } @@ -948,6 +955,7 @@ impl Distribution for EncodeDist { fn sample(&self, rng: &mut R) -> configs::secrets::DataAvailabilitySecrets { configs::secrets::DataAvailabilitySecrets::Avail(configs::da_client::avail::AvailSecrets { seed_phrase: Some(SeedPhrase(Secret::new(self.sample(rng)))), + gas_relay_api_key: Some(APIKey(Secret::new(self.sample(rng)))), }) } } diff --git a/core/lib/env_config/src/da_client.rs b/core/lib/env_config/src/da_client.rs index 0fc3ad216f87..1043786fc1eb 100644 --- a/core/lib/env_config/src/da_client.rs +++ b/core/lib/env_config/src/da_client.rs @@ -2,19 +2,34 @@ use std::env; use zksync_config::configs::{ da_client::{ - avail::AvailSecrets, DAClientConfig, AVAIL_CLIENT_CONFIG_NAME, - OBJECT_STORE_CLIENT_CONFIG_NAME, + avail::{ + AvailClientConfig, AvailSecrets, AVAIL_FULL_CLIENT_NAME, AVAIL_GAS_RELAY_CLIENT_NAME, + }, + DAClientConfig, AVAIL_CLIENT_CONFIG_NAME, OBJECT_STORE_CLIENT_CONFIG_NAME, }, secrets::DataAvailabilitySecrets, + AvailConfig, }; use crate::{envy_load, FromEnv}; impl FromEnv for DAClientConfig { fn from_env() -> anyhow::Result { - let client_tag = std::env::var("DA_CLIENT")?; + let client_tag = env::var("DA_CLIENT")?; let config = match client_tag.as_str() { - AVAIL_CLIENT_CONFIG_NAME => Self::Avail(envy_load("da_avail_config", "DA_")?), + AVAIL_CLIENT_CONFIG_NAME => Self::Avail(AvailConfig { + bridge_api_url: env::var("DA_BRIDGE_API_URL").ok().unwrap(), + timeout: env::var("DA_TIMEOUT")?.parse()?, + config: match env::var("DA_AVAIL_CLIENT_TYPE")?.as_str() { + AVAIL_FULL_CLIENT_NAME => { + AvailClientConfig::FullClient(envy_load("da_avail_full_client", "DA_")?) + } + AVAIL_GAS_RELAY_CLIENT_NAME => { + AvailClientConfig::GasRelay(envy_load("da_avail_gas_relay", "DA_")?) + } + _ => anyhow::bail!("Unknown Avail DA client type"), + }, + }), OBJECT_STORE_CLIENT_CONFIG_NAME => { Self::ObjectStore(envy_load("da_object_store", "DA_")?) } @@ -30,11 +45,21 @@ impl FromEnv for DataAvailabilitySecrets { let client_tag = std::env::var("DA_CLIENT")?; let secrets = match client_tag.as_str() { AVAIL_CLIENT_CONFIG_NAME => { - let seed_phrase = env::var("DA_SECRETS_SEED_PHRASE") - .ok() - .map(|s| s.parse()) - .transpose()?; - Self::Avail(AvailSecrets { seed_phrase }) + let seed_phrase: Option = + env::var("DA_SECRETS_SEED_PHRASE") + .ok() + .map(|s| s.parse().unwrap()); + let gas_relay_api_key: Option = + env::var("DA_SECRETS_GAS_RELAY_API_KEY") + .ok() + .map(|s| s.parse().unwrap()); + if seed_phrase.is_none() && gas_relay_api_key.is_none() { + anyhow::bail!("No secrets provided for Avail DA client"); + } + Self::Avail(AvailSecrets { + seed_phrase, + gas_relay_api_key, + }) } _ => anyhow::bail!("Unknown DA client name: {}", client_tag), }; @@ -47,7 +72,10 @@ impl FromEnv for DataAvailabilitySecrets { mod tests { use zksync_config::{ configs::{ - da_client::{DAClientConfig, DAClientConfig::ObjectStore}, + da_client::{ + avail::{AvailClientConfig, AvailDefaultConfig}, + DAClientConfig::{self, ObjectStore}, + }, object_store::ObjectStoreMode::GCS, }, AvailConfig, ObjectStoreConfig, @@ -91,14 +119,14 @@ mod tests { bridge_api_url: &str, app_id: u32, timeout: usize, - max_retries: usize, ) -> DAClientConfig { DAClientConfig::Avail(AvailConfig { - api_node_url: api_node_url.to_string(), bridge_api_url: bridge_api_url.to_string(), - app_id, timeout, - max_retries, + config: AvailClientConfig::FullClient(AvailDefaultConfig { + api_node_url: api_node_url.to_string(), + app_id, + }), }) } @@ -107,11 +135,13 @@ mod tests { let mut lock = MUTEX.lock(); let config = r#" DA_CLIENT="Avail" - DA_API_NODE_URL="localhost:12345" + DA_AVAIL_CLIENT_TYPE="FullClient" + DA_BRIDGE_API_URL="localhost:54321" - DA_APP_ID="1" DA_TIMEOUT="2" - DA_MAX_RETRIES="3" + + DA_API_NODE_URL="localhost:12345" + DA_APP_ID="1" "#; lock.set_env(config); @@ -124,7 +154,6 @@ mod tests { "localhost:54321", "1".parse::().unwrap(), "2".parse::().unwrap(), - "3".parse::().unwrap(), ) ); } @@ -139,15 +168,18 @@ mod tests { lock.set_env(config); - let actual = match DataAvailabilitySecrets::from_env().unwrap() { - DataAvailabilitySecrets::Avail(avail) => avail.seed_phrase, + let (actual_seed, actual_key) = match DataAvailabilitySecrets::from_env().unwrap() { + DataAvailabilitySecrets::Avail(avail) => (avail.seed_phrase, avail.gas_relay_api_key), }; assert_eq!( - actual.unwrap(), - "bottom drive obey lake curtain smoke basket hold race lonely fit walk" - .parse() - .unwrap() + (actual_seed.unwrap(), actual_key), + ( + "bottom drive obey lake curtain smoke basket hold race lonely fit walk" + .parse() + .unwrap(), + None + ) ); } } diff --git a/core/lib/protobuf_config/src/da_client.rs b/core/lib/protobuf_config/src/da_client.rs index 1499e88efb4c..a17a8711a27b 100644 --- a/core/lib/protobuf_config/src/da_client.rs +++ b/core/lib/protobuf_config/src/da_client.rs @@ -1,10 +1,10 @@ use anyhow::Context; -use zksync_config::{ - configs::{ - da_client::DAClientConfig::{Avail, ObjectStore}, - {self}, +use zksync_config::configs::{ + self, + da_client::{ + avail::{AvailClientConfig, AvailConfig, AvailDefaultConfig, AvailGasRelayConfig}, + DAClientConfig::{Avail, ObjectStore}, }, - AvailConfig, }; use zksync_protobuf::{required, ProtoRepr}; @@ -18,15 +18,31 @@ impl ProtoRepr for proto::DataAvailabilityClient { let client = match config { proto::data_availability_client::Config::Avail(conf) => Avail(AvailConfig { - api_node_url: required(&conf.api_node_url) - .context("api_node_url")? - .clone(), bridge_api_url: required(&conf.bridge_api_url) .context("bridge_api_url")? .clone(), - app_id: *required(&conf.app_id).context("app_id")?, timeout: *required(&conf.timeout).context("timeout")? as usize, - max_retries: *required(&conf.max_retries).context("max_retries")? as usize, + config: match conf.config.as_ref() { + Some(proto::avail_config::Config::FullClient(full_client_conf)) => { + AvailClientConfig::FullClient(AvailDefaultConfig { + api_node_url: required(&full_client_conf.api_node_url) + .context("api_node_url")? + .clone(), + app_id: *required(&full_client_conf.app_id).context("app_id")?, + }) + } + Some(proto::avail_config::Config::GasRelay(gas_relay_conf)) => { + AvailClientConfig::GasRelay(AvailGasRelayConfig { + gas_relay_api_url: required(&gas_relay_conf.gas_relay_api_url) + .context("gas_relay_api_url")? + .clone(), + max_retries: *required(&gas_relay_conf.max_retries) + .context("max_retries")? + as usize, + }) + } + None => return Err(anyhow::anyhow!("Invalid Avail DA configuration")), + }, }), proto::data_availability_client::Config::ObjectStore(conf) => { ObjectStore(object_store_proto::ObjectStore::read(conf)?) @@ -41,11 +57,22 @@ impl ProtoRepr for proto::DataAvailabilityClient { Avail(config) => Self { config: Some(proto::data_availability_client::Config::Avail( proto::AvailConfig { - api_node_url: Some(config.api_node_url.clone()), bridge_api_url: Some(config.bridge_api_url.clone()), - app_id: Some(config.app_id), timeout: Some(config.timeout as u64), - max_retries: Some(config.max_retries as u64), + config: match &config.config { + AvailClientConfig::FullClient(conf) => Some( + proto::avail_config::Config::FullClient(proto::AvailClientConfig { + api_node_url: Some(conf.api_node_url.clone()), + app_id: Some(conf.app_id), + }), + ), + AvailClientConfig::GasRelay(conf) => Some( + proto::avail_config::Config::GasRelay(proto::AvailGasRelayConfig { + gas_relay_api_url: Some(conf.gas_relay_api_url.clone()), + max_retries: Some(conf.max_retries as u64), + }), + ), + }, }, )), }, diff --git a/core/lib/protobuf_config/src/proto/config/da_client.proto b/core/lib/protobuf_config/src/proto/config/da_client.proto index d01bda2c8470..73fa2435996f 100644 --- a/core/lib/protobuf_config/src/proto/config/da_client.proto +++ b/core/lib/protobuf_config/src/proto/config/da_client.proto @@ -5,12 +5,26 @@ package zksync.config.da_client; import "zksync/config/object_store.proto"; message AvailConfig { - optional string api_node_url = 1; optional string bridge_api_url = 2; - optional uint32 app_id = 4; optional uint64 timeout = 5; - optional uint64 max_retries = 6; + oneof config { + AvailClientConfig full_client = 7; + AvailGasRelayConfig gas_relay = 8; + } + reserved 1; reserved "api_node_url"; reserved 3; reserved "seed"; + reserved 4; reserved "app_id"; + reserved 6; reserved "max_retries"; +} + +message AvailClientConfig { + optional string api_node_url = 1; + optional uint32 app_id = 2; +} + +message AvailGasRelayConfig { + optional string gas_relay_api_url = 1; + optional uint64 max_retries = 2; } message DataAvailabilityClient { diff --git a/core/lib/protobuf_config/src/proto/config/secrets.proto b/core/lib/protobuf_config/src/proto/config/secrets.proto index 17b915b3f087..43c4542783c7 100644 --- a/core/lib/protobuf_config/src/proto/config/secrets.proto +++ b/core/lib/protobuf_config/src/proto/config/secrets.proto @@ -21,6 +21,7 @@ message ConsensusSecrets { message AvailSecret { optional string seed_phrase = 1; + optional string gas_relay_api_key = 2; } message DataAvailabilitySecrets { diff --git a/core/lib/protobuf_config/src/secrets.rs b/core/lib/protobuf_config/src/secrets.rs index 587351480078..07ab340c2313 100644 --- a/core/lib/protobuf_config/src/secrets.rs +++ b/core/lib/protobuf_config/src/secrets.rs @@ -2,7 +2,7 @@ use std::str::FromStr; use anyhow::Context; use secrecy::ExposeSecret; -use zksync_basic_types::{seed_phrase::SeedPhrase, url::SensitiveUrl}; +use zksync_basic_types::{api_key::APIKey, seed_phrase::SeedPhrase, url::SensitiveUrl}; use zksync_config::configs::{ consensus::{AttesterSecretKey, ConsensusSecrets, NodeSecretKey, ValidatorSecretKey}, da_client::avail::AvailSecrets, @@ -103,14 +103,31 @@ impl ProtoRepr for proto::DataAvailabilitySecrets { let secrets = required(&self.da_secrets).context("config")?; let client = match secrets { - DaSecrets::Avail(avail_secret) => DataAvailabilitySecrets::Avail(AvailSecrets { - seed_phrase: Some( - SeedPhrase::from_str( - required(&avail_secret.seed_phrase).context("seed_phrase")?, - ) - .unwrap(), - ), - }), + DaSecrets::Avail(avail_secret) => { + let seed_phrase = match avail_secret.seed_phrase.as_ref() { + Some(seed) => match SeedPhrase::from_str(seed) { + Ok(seed) => Some(seed), + Err(_) => None, + }, + None => None, + }; + let gas_relay_api_key = match avail_secret.gas_relay_api_key.as_ref() { + Some(api_key) => match APIKey::from_str(api_key) { + Ok(api_key) => Some(api_key), + Err(_) => None, + }, + None => None, + }; + if seed_phrase.is_none() && gas_relay_api_key.is_none() { + return Err(anyhow::anyhow!( + "At least one of seed_phrase or gas_relay_api_key must be provided" + )); + } + DataAvailabilitySecrets::Avail(AvailSecrets { + seed_phrase, + gas_relay_api_key, + }) + } }; Ok(client) @@ -133,7 +150,24 @@ impl ProtoRepr for proto::DataAvailabilitySecrets { None }; - Some(DaSecrets::Avail(AvailSecret { seed_phrase })) + let gas_relay_api_key = if config.gas_relay_api_key.is_some() { + Some( + config + .clone() + .gas_relay_api_key + .unwrap() + .0 + .expose_secret() + .to_string(), + ) + } else { + None + }; + + Some(DaSecrets::Avail(AvailSecret { + seed_phrase, + gas_relay_api_key, + })) } }; diff --git a/core/node/da_clients/Cargo.toml b/core/node/da_clients/Cargo.toml index 60b65067f48d..fa2f15920bd0 100644 --- a/core/node/da_clients/Cargo.toml +++ b/core/node/da_clients/Cargo.toml @@ -37,3 +37,6 @@ blake2b_simd.workspace = true jsonrpsee = { workspace = true, features = ["ws-client"] } parity-scale-codec = { workspace = true, features = ["derive"] } subxt-signer = { workspace = true, features = ["sr25519", "native"] } +reqwest = { workspace = true } +bytes = { workspace = true } +backon.workspace = true diff --git a/core/node/da_clients/src/avail/client.rs b/core/node/da_clients/src/avail/client.rs index 7718691bf185..46d652d57137 100644 --- a/core/node/da_clients/src/avail/client.rs +++ b/core/node/da_clients/src/avail/client.rs @@ -1,34 +1,133 @@ -use std::{fmt::Debug, sync::Arc}; +use std::{fmt::Debug, sync::Arc, time::Duration}; +use anyhow::anyhow; use async_trait::async_trait; use jsonrpsee::ws_client::WsClientBuilder; +use serde::{Deserialize, Serialize}; use subxt_signer::ExposeSecret; -use zksync_config::configs::da_client::avail::{AvailConfig, AvailSecrets}; +use zksync_config::configs::da_client::avail::{AvailClientConfig, AvailConfig, AvailSecrets}; use zksync_da_client::{ types::{DAError, DispatchResponse, InclusionData}, DataAvailabilityClient, }; +use zksync_types::{ + ethabi::{self, Token}, + web3::contract::Tokenize, + H256, U256, +}; + +use crate::avail::sdk::{GasRelayClient, RawAvailClient}; -use crate::avail::sdk::RawAvailClient; +#[derive(Debug, Clone)] +enum AvailClientMode { + Default(Box), + GasRelay(GasRelayClient), +} /// An implementation of the `DataAvailabilityClient` trait that interacts with the Avail network. #[derive(Debug, Clone)] pub struct AvailClient { config: AvailConfig, - sdk_client: Arc, + sdk_client: Arc, + api_client: Arc, // bridge API reqwest client +} + +#[derive(Deserialize, Serialize, Debug, Clone)] +#[serde(rename_all = "camelCase")] +pub struct BridgeAPIResponse { + blob_root: Option, + bridge_root: Option, + data_root_index: Option, + data_root_proof: Option>, + leaf: Option, + leaf_index: Option, + leaf_proof: Option>, + range_hash: Option, + error: Option, +} + +#[derive(Deserialize, Serialize, Debug)] +#[serde(rename_all = "camelCase")] +struct MerkleProofInput { + // proof of inclusion for the data root + data_root_proof: Vec, + // proof of inclusion of leaf within blob/bridge root + leaf_proof: Vec, + // abi.encodePacked(startBlock, endBlock) of header range commitment on vectorx + range_hash: H256, + // index of the data root in the commitment tree + data_root_index: U256, + // blob root to check proof against, or reconstruct the data root + blob_root: H256, + // bridge root to check proof against, or reconstruct the data root + bridge_root: H256, + // leaf being proven + leaf: H256, + // index of the leaf in the blob/bridge root tree + leaf_index: U256, +} + +impl Tokenize for MerkleProofInput { + fn into_tokens(self) -> Vec { + vec![Token::Tuple(vec![ + Token::Array( + self.data_root_proof + .iter() + .map(|x| Token::FixedBytes(x.as_bytes().to_vec())) + .collect(), + ), + Token::Array( + self.leaf_proof + .iter() + .map(|x| Token::FixedBytes(x.as_bytes().to_vec())) + .collect(), + ), + Token::FixedBytes(self.range_hash.as_bytes().to_vec()), + Token::Uint(self.data_root_index), + Token::FixedBytes(self.blob_root.as_bytes().to_vec()), + Token::FixedBytes(self.bridge_root.as_bytes().to_vec()), + Token::FixedBytes(self.leaf.as_bytes().to_vec()), + Token::Uint(self.leaf_index), + ])] + } } impl AvailClient { pub async fn new(config: AvailConfig, secrets: AvailSecrets) -> anyhow::Result { - let seed_phrase = secrets - .seed_phrase - .ok_or_else(|| anyhow::anyhow!("seed phrase"))?; - let sdk_client = RawAvailClient::new(config.app_id, seed_phrase.0.expose_secret()).await?; - - Ok(Self { - config, - sdk_client: Arc::new(sdk_client), - }) + let api_client = Arc::new(reqwest::Client::new()); + match config.config.clone() { + AvailClientConfig::GasRelay(conf) => { + let gas_relay_api_key = secrets + .gas_relay_api_key + .ok_or_else(|| anyhow::anyhow!("Gas relay API key is missing"))?; + let gas_relay_client = GasRelayClient::new( + &conf.gas_relay_api_url, + gas_relay_api_key.0.expose_secret(), + conf.max_retries, + Arc::clone(&api_client), + ) + .await?; + Ok(Self { + config, + sdk_client: Arc::new(AvailClientMode::GasRelay(gas_relay_client)), + api_client, + }) + } + AvailClientConfig::FullClient(conf) => { + let seed_phrase = secrets + .seed_phrase + .ok_or_else(|| anyhow::anyhow!("Seed phrase is missing"))?; + // these unwraps are safe because we validate in protobuf config + let sdk_client = + RawAvailClient::new(conf.app_id, seed_phrase.0.expose_secret()).await?; + + Ok(Self { + config, + sdk_client: Arc::new(AvailClientMode::Default(Box::new(sdk_client))), + api_client, + }) + } + } } } @@ -39,37 +138,83 @@ impl DataAvailabilityClient for AvailClient { _: u32, // batch_number data: Vec, ) -> anyhow::Result { - let client = WsClientBuilder::default() - .build(self.config.api_node_url.as_str()) - .await - .map_err(to_non_retriable_da_error)?; + match self.sdk_client.as_ref() { + AvailClientMode::Default(client) => { + let default_config = match &self.config.config { + AvailClientConfig::FullClient(conf) => conf, + _ => unreachable!(), // validated in protobuf config + }; + let ws_client = WsClientBuilder::default() + .build(default_config.api_node_url.clone().as_str()) + .await + .map_err(to_non_retriable_da_error)?; - let extrinsic = self - .sdk_client - .build_extrinsic(&client, data) - .await - .map_err(to_non_retriable_da_error)?; + let extrinsic = client + .build_extrinsic(&ws_client, data) + .await + .map_err(to_non_retriable_da_error)?; - let block_hash = self - .sdk_client - .submit_extrinsic(&client, extrinsic.as_str()) - .await - .map_err(to_non_retriable_da_error)?; - let tx_id = self - .sdk_client - .get_tx_id(&client, block_hash.as_str(), extrinsic.as_str()) - .await - .map_err(to_non_retriable_da_error)?; - - Ok(DispatchResponse::from(format!("{}:{}", block_hash, tx_id))) + let block_hash = client + .submit_extrinsic(&ws_client, extrinsic.as_str()) + .await + .map_err(to_non_retriable_da_error)?; + let tx_id = client + .get_tx_id(&ws_client, block_hash.as_str(), extrinsic.as_str()) + .await + .map_err(to_non_retriable_da_error)?; + Ok(DispatchResponse::from(format!("{}:{}", block_hash, tx_id))) + } + AvailClientMode::GasRelay(client) => { + let (block_hash, extrinsic_index) = client + .post_data(data) + .await + .map_err(to_retriable_da_error)?; + Ok(DispatchResponse { + blob_id: format!("{:x}:{}", block_hash, extrinsic_index), + }) + } + } } async fn get_inclusion_data( &self, - _blob_id: &str, + blob_id: &str, ) -> anyhow::Result, DAError> { - // TODO: implement inclusion data retrieval - Ok(Some(InclusionData { data: vec![] })) + let (block_hash, tx_idx) = blob_id.split_once(':').ok_or_else(|| DAError { + error: anyhow!("Invalid blob ID format"), + is_retriable: false, + })?; + let url = format!( + "{}/eth/proof/{}?index={}", + self.config.bridge_api_url, block_hash, tx_idx + ); + + let response = self + .api_client + .get(&url) + .timeout(Duration::from_secs(self.config.timeout as u64)) + .send() + .await + .map_err(to_retriable_da_error)?; + + let bridge_api_data = response + .json::() + .await + .map_err(to_retriable_da_error)?; + + let attestation_data: MerkleProofInput = MerkleProofInput { + data_root_proof: bridge_api_data.data_root_proof.unwrap(), + leaf_proof: bridge_api_data.leaf_proof.unwrap(), + range_hash: bridge_api_data.range_hash.unwrap(), + data_root_index: bridge_api_data.data_root_index.unwrap(), + blob_root: bridge_api_data.blob_root.unwrap(), + bridge_root: bridge_api_data.bridge_root.unwrap(), + leaf: bridge_api_data.leaf.unwrap(), + leaf_index: bridge_api_data.leaf_index.unwrap(), + }; + Ok(Some(InclusionData { + data: ethabi::encode(&attestation_data.into_tokens()), + })) } fn clone_boxed(&self) -> Box { @@ -87,3 +232,10 @@ pub fn to_non_retriable_da_error(error: impl Into) -> DAError { is_retriable: false, } } + +pub fn to_retriable_da_error(error: impl Into) -> DAError { + DAError { + error: error.into(), + is_retriable: true, + } +} diff --git a/core/node/da_clients/src/avail/sdk.rs b/core/node/da_clients/src/avail/sdk.rs index 002422109d05..f693280ba4a9 100644 --- a/core/node/da_clients/src/avail/sdk.rs +++ b/core/node/da_clients/src/avail/sdk.rs @@ -1,18 +1,22 @@ //! Minimal reimplementation of the Avail SDK client required for the DA client implementation. //! This is considered to be a temporary solution until a mature SDK is available on crates.io -use std::fmt::Debug; +use std::{fmt::Debug, sync::Arc, time}; +use backon::{ConstantBuilder, Retryable}; +use bytes::Bytes; use jsonrpsee::{ core::client::{Client, ClientT, Subscription, SubscriptionClientT}, rpc_params, }; use parity_scale_codec::{Compact, Decode, Encode}; use scale_encode::EncodeAsFields; +use serde::{Deserialize, Serialize}; use subxt_signer::{ bip39::Mnemonic, sr25519::{Keypair, Signature}, }; +use zksync_types::H256; use crate::avail::client::to_non_retriable_da_error; @@ -287,7 +291,7 @@ impl RawAvailClient { let status = sub.next().await.transpose()?; if status.is_some() && status.as_ref().unwrap().is_object() { - if let Some(block_hash) = status.unwrap().get("inBlock") { + if let Some(block_hash) = status.unwrap().get("finalized") { break block_hash .as_str() .ok_or_else(|| anyhow::anyhow!("Invalid block hash"))? @@ -369,3 +373,95 @@ fn ss58hash(data: &[u8]) -> Vec { ctx.update(data); ctx.finalize().to_vec() } + +/// An implementation of the `DataAvailabilityClient` trait that interacts with the Avail network. +#[derive(Debug, Clone)] +pub(crate) struct GasRelayClient { + api_url: String, + api_key: String, + max_retries: usize, + api_client: Arc, +} + +#[derive(Deserialize, Serialize, Debug, Clone)] +pub struct GasRelayAPISubmissionResponse { + submission_id: String, +} + +#[derive(Deserialize, Serialize, Debug, Clone)] +pub struct GasRelayAPIStatusResponse { + submission: GasRelayAPISubmission, +} + +#[derive(Deserialize, Serialize, Debug, Clone)] +pub struct GasRelayAPISubmission { + block_hash: Option, + extrinsic_index: Option, +} + +impl GasRelayClient { + const DEFAULT_INCLUSION_DELAY: time::Duration = time::Duration::from_secs(60); + const RETRY_DELAY: time::Duration = time::Duration::from_secs(5); + pub(crate) async fn new( + api_url: &str, + api_key: &str, + max_retries: usize, + api_client: Arc, + ) -> anyhow::Result { + Ok(Self { + api_url: api_url.to_owned(), + api_key: api_key.to_owned(), + max_retries, + api_client, + }) + } + + pub(crate) async fn post_data(&self, data: Vec) -> anyhow::Result<(H256, u64)> { + let submit_url = format!("{}/user/submit_raw_data?token=ethereum", &self.api_url); + // send the data to the gas relay + let submit_response = self + .api_client + .post(&submit_url) + .body(Bytes::from(data)) + .header("Content-Type", "text/plain") + .header("Authorization", &self.api_key) + .send() + .await?; + + let submit_response = submit_response + .json::() + .await?; + + let status_url = format!( + "{}/user/get_submission_info?submission_id={}", + self.api_url, submit_response.submission_id + ); + + tokio::time::sleep(Self::DEFAULT_INCLUSION_DELAY).await; + let status_response = (|| async { + self.api_client + .get(&status_url) + .header("Authorization", &self.api_key) + .send() + .await + }) + .retry( + &ConstantBuilder::default() + .with_delay(Self::RETRY_DELAY) + .with_max_times(self.max_retries), + ) + .await?; + + let status_response = status_response.json::().await?; + let (block_hash, extrinsic_index) = ( + status_response.submission.block_hash.ok_or_else(|| { + anyhow::anyhow!("Block hash not found in the response from the gas relay") + })?, + status_response.submission.extrinsic_index.ok_or_else(|| { + anyhow::anyhow!("Extrinsic index not found in the response from the gas relay") + })?, + ); + + Ok((block_hash, extrinsic_index)) + } +} From 04f4daef85b618b76dda618906b9d8b09cddfe58 Mon Sep 17 00:00:00 2001 From: Daniyar Itegulov Date: Thu, 24 Oct 2024 15:04:47 +1100 Subject: [PATCH 24/27] chore: lower no base token ratio log level (#3141) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## What ❔ Lowers no base token ratio log level to `WARN` instead of `ERROR` ## Why ❔ It gets printed >500 times during integration tests making it hard to find the actual errors. ## Checklist - [ ] PR title corresponds to the body of PR (we generate changelog entries from PRs). - [ ] Tests for the changes have been added / updated. - [ ] Documentation comments have been added / updated. - [ ] Code has been formatted via `zkstack dev fmt` and `zkstack dev lint`. --- core/node/base_token_adjuster/src/base_token_ratio_provider.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/node/base_token_adjuster/src/base_token_ratio_provider.rs b/core/node/base_token_adjuster/src/base_token_ratio_provider.rs index e16ea16ff0f5..b613e5219dd2 100644 --- a/core/node/base_token_adjuster/src/base_token_ratio_provider.rs +++ b/core/node/base_token_adjuster/src/base_token_ratio_provider.rs @@ -81,7 +81,7 @@ impl DBBaseTokenRatioProvider { // Though the DB should be populated very soon after the server starts, it is possible // to have no ratios in the DB right after genesis. Having initial ratios in the DB // from the genesis stage will eliminate this possibility. - tracing::error!("No latest price found in the database. Using default ratio."); + tracing::warn!("No latest price found in the database. Using default ratio."); BaseTokenConversionRatio::default() } Err(err) => anyhow::bail!("Failed to get latest base token ratio: {:?}", err), From 6719429312fdf5137459711aa54da16e550c4919 Mon Sep 17 00:00:00 2001 From: Yury Akudovich Date: Thu, 24 Oct 2024 09:58:16 +0200 Subject: [PATCH 25/27] ci: Remove invalid step from GAR build workflow (#3164) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## What ❔ ## Why ❔ There is no need to remove local docker image. ## Checklist - [x] PR title corresponds to the body of PR (we generate changelog entries from PRs). - [ ] Tests for the changes have been added / updated. - [ ] Documentation comments have been added / updated. - [ ] Code has been formatted via `zkstack dev fmt` and `zkstack dev lint`. --- .../build-prover-fri-gpu-gar-and-circuit-prover-gpu-gar.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.github/workflows/build-prover-fri-gpu-gar-and-circuit-prover-gpu-gar.yml b/.github/workflows/build-prover-fri-gpu-gar-and-circuit-prover-gpu-gar.yml index 4639f8c77c41..30990889caf6 100644 --- a/.github/workflows/build-prover-fri-gpu-gar-and-circuit-prover-gpu-gar.yml +++ b/.github/workflows/build-prover-fri-gpu-gar-and-circuit-prover-gpu-gar.yml @@ -69,10 +69,6 @@ jobs: --tag europe-docker.pkg.dev/matterlabs-infra/matterlabs-docker/prover-fri-gpu-gar:2.0-${{ inputs.protocol_version }}-${{ inputs.image_tag_suffix }} \ us-docker.pkg.dev/matterlabs-infra/matterlabs-docker/prover-fri-gpu-gar:2.0-${{ inputs.protocol_version }}-${{ inputs.image_tag_suffix }} - - name: Remove prover-gpu-fri-gar image to free space - run: | - docker image rm us-docker.pkg.dev/matterlabs-infra/matterlabs-docker/prover-fri-gpu-gar:2.0-${{ inputs.protocol_version }}-${{ inputs.image_tag_suffix }} - - name: Move Setup data from prover-gpu-fri-gar to circuit-prover-gpu-gar run: | mv -v docker/prover-gpu-fri-gar/*.bin docker/circuit-prover-gpu-gar/ From 16f275756cd28024a6b11ac1ac327eb5b8b446e1 Mon Sep 17 00:00:00 2001 From: perekopskiy <53865202+perekopskiy@users.noreply.github.com> Date: Thu, 24 Oct 2024 12:07:20 +0300 Subject: [PATCH 26/27] feat: gateway preparation (#3006) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## What ❔ - adds new fields to DB tables and rust structs - adds new config variables - update commitment generator to work with post-gateway - adds new vm subversion (vm fast is not changed yet) ## Why ❔ prepare for gateway, reduce sync-layer-stable diff ## Checklist - [ ] PR title corresponds to the body of PR (we generate changelog entries from PRs). - [ ] Tests for the changes have been added / updated. - [ ] Documentation comments have been added / updated. - [ ] Code has been formatted via `zk_supervisor fmt` and `zk_supervisor lint`. --- Cargo.lock | 2 + core/bin/external_node/src/config/mod.rs | 8 + core/bin/external_node/src/node_builder.rs | 20 +- core/bin/snapshots_creator/src/tests.rs | 1 + .../system-constants-generator/src/utils.rs | 9 +- core/bin/zksync_server/src/node_builder.rs | 6 +- core/lib/basic_types/src/commitment.rs | 24 +- core/lib/basic_types/src/protocol_version.rs | 7 + core/lib/basic_types/src/vm.rs | 1 + core/lib/config/src/configs/contracts.rs | 9 + core/lib/config/src/testonly.rs | 2 + core/lib/constants/src/contracts.rs | 26 +- core/lib/constants/src/lib.rs | 1 + core/lib/constants/src/message_root.rs | 5 + core/lib/constants/src/system_logs.rs | 11 +- core/lib/contracts/src/lib.rs | 14 + ...01396dacefc0cea8cbcf5807185eb00fc0f7.json} | 30 +- ...0cc9e176729744c779fee97ca9392ae8a8c8.json} | 18 +- ...11345ef888824e0ca3c5f39befbbc5bd0388.json} | 7 +- ...892118f5732374e62f35e27800422afb5746.json} | 30 +- ...2f38816f163a3e3fba4fdbb81076b969e970.json} | 30 +- ...911add046315e5f8877bc57a34e3dadf9e37.json} | 30 +- ...7bd02627ebaf2df7c5ad517cb60a243182d2.json} | 16 +- ...3369701d7cd5f75ca031bf77ca27d0437cb9.json} | 30 +- ...33f6503bc79cc9f809d35c558e275ba117ba.json} | 8 +- ...806fcc54d73216a7dc54be6ba210ef02d789.json} | 30 +- ...0e9c138d0a6d35e9ce7fc396c5e76fbc25dd.json} | 30 +- ...673e4b5bba059ebe07bbbb64578881db030b.json} | 30 +- ...7999eabb611338925abe9dc9e64c837183d9.json} | 18 +- .../20240925103531_gateway_upgrade.down.sql | 8 + .../20240925103531_gateway_upgrade.up.sql | 11 + core/lib/dal/src/blocks_dal.rs | 92 +- core/lib/dal/src/consensus/conv.rs | 45 +- core/lib/dal/src/consensus/mod.rs | 5 +- core/lib/dal/src/consensus/proto/mod.proto | 11 + core/lib/dal/src/consensus/tests.rs | 11 +- core/lib/dal/src/consensus_dal/tests.rs | 3 + core/lib/dal/src/eth_watcher_dal.rs | 2 +- core/lib/dal/src/lib.rs | 4 +- core/lib/dal/src/models/storage_block.rs | 16 +- core/lib/dal/src/models/storage_sync.rs | 17 +- core/lib/dal/src/sync_dal.rs | 4 +- core/lib/dal/src/tests/mod.rs | 2 + core/lib/env_config/src/contracts.rs | 4 + core/lib/eth_client/src/clients/http/query.rs | 85 +- core/lib/eth_client/src/clients/mock.rs | 34 +- core/lib/multivm/Cargo.toml | 1 + core/lib/multivm/src/lib.rs | 1 + core/lib/multivm/src/pubdata_builders/mod.rs | 24 + .../multivm/src/pubdata_builders/rollup.rs | 128 ++ .../lib/multivm/src/pubdata_builders/tests.rs | 123 + .../lib/multivm/src/pubdata_builders/utils.rs | 70 + .../multivm/src/pubdata_builders/validium.rs | 93 + core/lib/multivm/src/utils/events.rs | 56 +- core/lib/multivm/src/utils/mod.rs | 69 +- core/lib/multivm/src/versions/shadow/mod.rs | 1 - core/lib/multivm/src/versions/shadow/tests.rs | 26 +- .../src/versions/testonly/block_tip.rs | 8 +- .../src/versions/testonly/bootloader.rs | 6 +- .../versions/testonly/bytecode_publishing.rs | 8 +- .../multivm/src/versions/testonly/circuits.rs | 4 +- .../src/versions/testonly/code_oracle.rs | 10 +- .../src/versions/testonly/default_aa.rs | 8 +- .../versions/testonly/get_used_contracts.rs | 7 +- .../src/versions/testonly/is_write_initial.rs | 6 +- .../src/versions/testonly/l1_tx_execution.rs | 14 +- .../src/versions/testonly/l2_blocks.rs | 18 +- core/lib/multivm/src/versions/testonly/mod.rs | 13 +- .../src/versions/testonly/nonce_holder.rs | 4 +- .../src/versions/testonly/precompiles.rs | 8 +- .../multivm/src/versions/testonly/refunds.rs | 27 +- .../src/versions/testonly/require_eip712.rs | 8 +- .../src/versions/testonly/secp256r1.rs | 4 +- .../src/versions/testonly/simple_execution.rs | 16 +- .../multivm/src/versions/testonly/storage.rs | 8 +- .../src/versions/testonly/tester/mod.rs | 16 +- .../testonly/tester/transaction_test_info.rs | 13 +- .../multivm/src/versions/testonly/transfer.rs | 22 +- .../multivm/src/versions/testonly/upgrade.rs | 22 +- core/lib/multivm/src/versions/vm_1_3_2/vm.rs | 17 +- .../vm_1_4_1/tracers/pubdata_tracer.rs | 3 +- .../vm_1_4_1/types/internals/pubdata.rs | 2 +- core/lib/multivm/src/versions/vm_1_4_1/vm.rs | 15 +- .../vm_1_4_2/tracers/pubdata_tracer.rs | 3 +- .../vm_1_4_2/types/internals/pubdata.rs | 2 +- core/lib/multivm/src/versions/vm_1_4_2/vm.rs | 11 +- .../tracers/pubdata_tracer.rs | 3 +- .../types/internals/pubdata.rs | 2 +- .../src/versions/vm_boojum_integration/vm.rs | 11 +- .../multivm/src/versions/vm_fast/pubdata.rs | 2 +- .../multivm/src/versions/vm_fast/tests/mod.rs | 17 +- core/lib/multivm/src/versions/vm_fast/vm.rs | 81 +- .../vm_latest/bootloader_state/state.rs | 43 +- .../vm_latest/bootloader_state/utils.rs | 77 +- .../src/versions/vm_latest/constants.rs | 3 +- .../vm_latest/implementation/execution.rs | 1 + .../versions/vm_latest/tests/call_tracer.rs | 6 +- .../src/versions/vm_latest/tests/mod.rs | 25 +- .../vm_latest/tests/prestate_tracer.rs | 10 +- .../src/versions/vm_latest/tests/rollbacks.rs | 10 +- .../vm_latest/tracers/pubdata_tracer.rs | 30 +- .../versions/vm_latest/types/internals/mod.rs | 2 - .../vm_latest/types/internals/pubdata.rs | 123 - .../vm_latest/types/internals/vm_state.rs | 1 + core/lib/multivm/src/versions/vm_latest/vm.rs | 35 +- core/lib/multivm/src/versions/vm_m5/vm.rs | 19 +- core/lib/multivm/src/versions/vm_m6/vm.rs | 14 +- .../src/versions/vm_refunds_enhancement/vm.rs | 13 +- .../src/versions/vm_virtual_blocks/vm.rs | 11 +- core/lib/multivm/src/vm_instance.rs | 28 +- core/lib/protobuf_config/src/contracts.rs | 16 + .../src/proto/config/contracts.proto | 2 + core/lib/prover_interface/src/inputs.rs | 5 +- core/lib/snapshots_applier/src/tests/utils.rs | 1 + core/lib/state/src/test_utils.rs | 1 + core/lib/tee_verifier/src/lib.rs | 10 +- core/lib/types/src/api/en.rs | 4 +- core/lib/types/src/api/mod.rs | 1 + core/lib/types/src/block.rs | 3 +- core/lib/types/src/commitment/mod.rs | 140 +- core/lib/types/src/commitment/tests/mod.rs | 5 + .../tests/post_boojum_1_4_1_test.json | 33 +- .../tests/post_boojum_1_4_2_test.json | 33 +- .../tests/post_boojum_1_5_0_test.json | 187 +- .../post_boojum_1_5_0_test_with_evm.json | 187 +- .../commitment/tests/post_gateway_test.json | 1977 +++++++++++++++++ core/lib/types/src/l2_to_l1_log.rs | 15 +- core/lib/vm_executor/src/batch/factory.rs | 30 +- core/lib/vm_executor/src/oneshot/block.rs | 1 + core/lib/vm_executor/src/oneshot/contracts.rs | 5 + core/lib/vm_executor/src/oneshot/mod.rs | 7 +- core/lib/vm_executor/src/storage.rs | 17 +- core/lib/vm_interface/src/executor.rs | 3 +- core/lib/vm_interface/src/lib.rs | 5 +- core/lib/vm_interface/src/pubdata/mod.rs | 90 + .../src/types/inputs/execution_mode.rs | 19 + core/lib/vm_interface/src/types/inputs/mod.rs | 2 +- core/lib/vm_interface/src/utils/dump.rs | 17 +- core/lib/vm_interface/src/utils/shadow.rs | 16 +- core/lib/vm_interface/src/vm.rs | 13 +- core/node/api_server/src/web3/state.rs | 1 + core/node/block_reverter/src/tests.rs | 1 + core/node/commitment_generator/Cargo.toml | 1 + core/node/commitment_generator/src/lib.rs | 63 +- core/node/commitment_generator/src/utils.rs | 88 +- core/node/consensus/src/storage/store.rs | 8 + core/node/consensus/src/testonly.rs | 13 +- core/node/db_pruner/src/tests.rs | 1 + core/node/eth_sender/src/tests.rs | 4 + core/node/eth_watch/src/lib.rs | 4 +- .../src/l1_gas_price/gas_adjuster/mod.rs | 4 +- core/node/genesis/src/lib.rs | 1 + core/node/logs_bloom_backfill/src/lib.rs | 1 + .../layers/state_keeper/mempool_io.rs | 10 +- .../layers/state_keeper/output_handler.rs | 15 +- core/node/node_sync/src/external_io.rs | 5 +- core/node/node_sync/src/fetcher.rs | 16 +- core/node/node_sync/src/sync_action.rs | 1 + core/node/node_sync/src/tests.rs | 6 +- .../src/request_processor.rs | 91 +- .../src/tee_request_processor.rs | 3 +- .../state_keeper/src/executor/tests/tester.rs | 30 +- core/node/state_keeper/src/io/common/mod.rs | 4 +- core/node/state_keeper/src/io/common/tests.rs | 8 +- core/node/state_keeper/src/io/mempool.rs | 83 +- core/node/state_keeper/src/io/mod.rs | 16 +- core/node/state_keeper/src/io/persistence.rs | 85 +- .../io/seal_logic/l2_block_seal_subtasks.rs | 17 +- .../state_keeper/src/io/seal_logic/mod.rs | 7 +- core/node/state_keeper/src/io/tests/mod.rs | 14 +- core/node/state_keeper/src/io/tests/tester.rs | 2 + core/node/state_keeper/src/keeper.rs | 25 +- core/node/state_keeper/src/testonly/mod.rs | 7 +- .../src/testonly/test_batch_executor.rs | 7 +- core/node/state_keeper/src/tests/mod.rs | 3 +- core/node/state_keeper/src/updates/mod.rs | 20 +- core/node/test_utils/src/lib.rs | 9 + core/node/vm_runner/src/process.rs | 1 + core/node/vm_runner/src/storage.rs | 9 +- core/tests/vm-benchmark/src/vm.rs | 8 +- etc/multivm_bootloaders/vm_gateway/commit | 1 + .../fee_estimate.yul/fee_estimate.yul.zbin | Bin 0 -> 75296 bytes .../vm_gateway/gas_test.yul/gas_test.yul.zbin | Bin 0 -> 71392 bytes .../playground_batch.yul.zbin | Bin 0 -> 75424 bytes .../proved_batch.yul/proved_batch.yul.zbin | Bin 0 -> 71904 bytes prover/Cargo.lock | 1 + yarn.lock | 235 +- zkstack_cli/crates/config/src/contracts.rs | 2 + 188 files changed, 4838 insertions(+), 1207 deletions(-) create mode 100644 core/lib/constants/src/message_root.rs rename core/lib/dal/.sqlx/{query-7aebc0d8eb43bd835c4f175edc4c0371bdc118b25d64fcf526bd6575e4d675c8.json => query-1cb61327bed4d65a3fc81aa2229e01396dacefc0cea8cbcf5807185eb00fc0f7.json} (78%) rename core/lib/dal/.sqlx/{query-a62f400a5b0b66300f5febf762c7e0c8a39a49d1cea78ef771d4c64fbbc16756.json => query-250cc655f48144137906a72490680cc9e176729744c779fee97ca9392ae8a8c8.json} (83%) rename core/lib/dal/.sqlx/{query-55f4585be3d0f1a147cb10f6e59325fad494a512ba92df95439d2d7fe0f3a285.json => query-398598e20f1892b47bf749b220f611345ef888824e0ca3c5f39befbbc5bd0388.json} (65%) rename core/lib/dal/.sqlx/{query-942d6d948770c374ba4d3566c50e56e43137ac0cf45312d70dec0c407cadc1bf.json => query-45154c2efc8d07c4f83ae3e229f9892118f5732374e62f35e27800422afb5746.json} (70%) rename core/lib/dal/.sqlx/{query-e2d0bd978f76e0ce09b36b0e4b0a2baec4b2531ecaa8da234863e2eb810761c7.json => query-4bd1a4e612d10f2ca26068c140442f38816f163a3e3fba4fdbb81076b969e970.json} (79%) rename core/lib/dal/.sqlx/{query-0784f2cc13f85763cc7da29902850fa76a03907957b7a0d87ea55a7873f3312e.json => query-62e8330881b73917394384adbf73911add046315e5f8877bc57a34e3dadf9e37.json} (79%) rename core/lib/dal/.sqlx/{query-2049362aad5e32981e48e5c5ef7a00a91254ec6c8a68a359d22b02df5a40911f.json => query-7553d8013d101af0451830d26b7d7bd02627ebaf2df7c5ad517cb60a243182d2.json} (83%) rename core/lib/dal/.sqlx/{query-b456147560b107640abdc10f7ac76b563ff2f0f3a818e8c8a02c2ef632d0b960.json => query-77864e5eb5eada8edf8f4457aa153369701d7cd5f75ca031bf77ca27d0437cb9.json} (80%) rename core/lib/dal/.sqlx/{query-34910600545933d85931d41bfe2dfcb3522a0772ac3d2476652df4216d823e04.json => query-7d8c19c3568c03ec3e4a788b22c233f6503bc79cc9f809d35c558e275ba117ba.json} (55%) rename core/lib/dal/.sqlx/{query-f30748bef5f8d08b60739cdfd9508c8132d0958e4e25f4954e93d2095b4f11e8.json => query-a42121cd85daeb95ee268ba5cff1806fcc54d73216a7dc54be6ba210ef02d789.json} (73%) rename core/lib/dal/.sqlx/{query-2def67eb8372245ed59e76e07d615598f5d22a3aebd893afddded0e3c6b94a3b.json => query-b7d448837439a3e3dfe73070d3c20e9c138d0a6d35e9ce7fc396c5e76fbc25dd.json} (73%) rename core/lib/dal/.sqlx/{query-5aa487a98dff53a5d32a5916a26cbf3ffb03b3791c0e9a9f39fb85cfffc65db2.json => query-c5aedd2b1871d8f6276a31482caa673e4b5bba059ebe07bbbb64578881db030b.json} (77%) rename core/lib/dal/.sqlx/{query-f208ac4d454220cdd5cf8fa1405b21ca4cc94c38a7d18023ef1e89de484e60d8.json => query-d4cdd4eed07dfdad2757c480903f7999eabb611338925abe9dc9e64c837183d9.json} (84%) create mode 100644 core/lib/dal/migrations/20240925103531_gateway_upgrade.down.sql create mode 100644 core/lib/dal/migrations/20240925103531_gateway_upgrade.up.sql create mode 100644 core/lib/multivm/src/pubdata_builders/mod.rs create mode 100644 core/lib/multivm/src/pubdata_builders/rollup.rs create mode 100644 core/lib/multivm/src/pubdata_builders/tests.rs create mode 100644 core/lib/multivm/src/pubdata_builders/utils.rs create mode 100644 core/lib/multivm/src/pubdata_builders/validium.rs delete mode 100644 core/lib/multivm/src/versions/vm_latest/types/internals/pubdata.rs create mode 100644 core/lib/types/src/commitment/tests/post_gateway_test.json create mode 100644 core/lib/vm_interface/src/pubdata/mod.rs create mode 100644 etc/multivm_bootloaders/vm_gateway/commit create mode 100644 etc/multivm_bootloaders/vm_gateway/fee_estimate.yul/fee_estimate.yul.zbin create mode 100644 etc/multivm_bootloaders/vm_gateway/gas_test.yul/gas_test.yul.zbin create mode 100644 etc/multivm_bootloaders/vm_gateway/playground_batch.yul/playground_batch.yul.zbin create mode 100644 etc/multivm_bootloaders/vm_gateway/proved_batch.yul/proved_batch.yul.zbin diff --git a/Cargo.lock b/Cargo.lock index a42ef8e3fdcc..64ae0a9a12f4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9667,6 +9667,7 @@ dependencies = [ "zksync_multivm", "zksync_node_genesis", "zksync_node_test_utils", + "zksync_system_constants", "zksync_types", "zksync_utils", "zksync_web3_decl", @@ -10532,6 +10533,7 @@ dependencies = [ "zk_evm 0.150.6", "zksync_contracts", "zksync_eth_signer", + "zksync_mini_merkle_tree", "zksync_system_constants", "zksync_test_account", "zksync_types", diff --git a/core/bin/external_node/src/config/mod.rs b/core/bin/external_node/src/config/mod.rs index 56ee3edfd253..70803a663110 100644 --- a/core/bin/external_node/src/config/mod.rs +++ b/core/bin/external_node/src/config/mod.rs @@ -110,7 +110,12 @@ pub(crate) struct RemoteENConfig { // the `l2_erc20_bridge_addr` and `l2_shared_bridge_addr` are basically the same contract, but with // a different name, with names adapted only for consistency. pub l1_shared_bridge_proxy_addr: Option
, + /// Contract address that serves as a shared bridge on L2. + /// It is expected that `L2SharedBridge` is used before gateway upgrade, and `L2AssetRouter` is used after. pub l2_shared_bridge_addr: Option
, + /// Address of `L2SharedBridge` that was used before gateway upgrade. + /// `None` if chain genesis used post-gateway protocol version. + pub l2_legacy_shared_bridge_addr: Option
, pub l1_erc20_bridge_proxy_addr: Option
, pub l2_erc20_bridge_addr: Option
, pub l1_weth_bridge_addr: Option
, @@ -189,6 +194,7 @@ impl RemoteENConfig { l2_erc20_bridge_addr: l2_erc20_default_bridge, l1_shared_bridge_proxy_addr: bridges.l1_shared_default_bridge, l2_shared_bridge_addr: l2_erc20_shared_bridge, + l2_legacy_shared_bridge_addr: bridges.l2_legacy_shared_bridge, l1_weth_bridge_addr: bridges.l1_weth_bridge, l2_weth_bridge_addr: bridges.l2_weth_bridge, base_token_addr, @@ -218,6 +224,7 @@ impl RemoteENConfig { l1_shared_bridge_proxy_addr: Some(Address::repeat_byte(5)), l1_weth_bridge_addr: None, l2_shared_bridge_addr: Some(Address::repeat_byte(6)), + l2_legacy_shared_bridge_addr: Some(Address::repeat_byte(7)), l1_batch_commit_data_generator_mode: L1BatchCommitmentMode::Rollup, dummy_verifier: true, } @@ -1403,6 +1410,7 @@ impl From<&ExternalNodeConfig> for InternalApiConfig { l2_erc20_default_bridge: config.remote.l2_erc20_bridge_addr, l1_shared_default_bridge: config.remote.l1_shared_bridge_proxy_addr, l2_shared_default_bridge: config.remote.l2_shared_bridge_addr, + l2_legacy_shared_bridge: config.remote.l2_legacy_shared_bridge_addr, l1_weth_bridge: config.remote.l1_weth_bridge_addr, l2_weth_bridge: config.remote.l2_weth_bridge_addr, }, diff --git a/core/bin/external_node/src/node_builder.rs b/core/bin/external_node/src/node_builder.rs index 7d8489013535..883f3f8a5fae 100644 --- a/core/bin/external_node/src/node_builder.rs +++ b/core/bin/external_node/src/node_builder.rs @@ -55,6 +55,7 @@ use zksync_node_framework::{ service::{ZkStackService, ZkStackServiceBuilder}, }; use zksync_state::RocksdbStorageOptions; +use zksync_types::L2_NATIVE_TOKEN_VAULT_ADDRESS; use crate::{config::ExternalNodeConfig, metrics::framework::ExternalNodeMetricsLayer, Component}; @@ -192,11 +193,22 @@ impl ExternalNodeBuilder { // compression. const OPTIONAL_BYTECODE_COMPRESSION: bool = true; + let l2_shared_bridge_addr = self + .config + .remote + .l2_shared_bridge_addr + .context("Missing `l2_shared_bridge_addr`")?; + let l2_legacy_shared_bridge_addr = if l2_shared_bridge_addr == L2_NATIVE_TOKEN_VAULT_ADDRESS + { + // System has migrated to `L2_NATIVE_TOKEN_VAULT_ADDRESS`, use legacy shared bridge address from main node. + self.config.remote.l2_legacy_shared_bridge_addr + } else { + // System hasn't migrated on `L2_NATIVE_TOKEN_VAULT_ADDRESS`, we can safely use `l2_shared_bridge_addr`. + Some(l2_shared_bridge_addr) + }; + let persistence_layer = OutputHandlerLayer::new( - self.config - .remote - .l2_shared_bridge_addr - .expect("L2 shared bridge address is not set"), + l2_legacy_shared_bridge_addr, self.config.optional.l2_block_seal_queue_capacity, ) .with_pre_insert_txs(true) // EN requires txs to be pre-inserted. diff --git a/core/bin/snapshots_creator/src/tests.rs b/core/bin/snapshots_creator/src/tests.rs index a440d836b4c9..f3c191388803 100644 --- a/core/bin/snapshots_creator/src/tests.rs +++ b/core/bin/snapshots_creator/src/tests.rs @@ -167,6 +167,7 @@ async fn create_l2_block( base_fee_per_gas: 0, gas_per_pubdata_limit: 0, batch_fee_input: Default::default(), + pubdata_params: Default::default(), base_system_contracts_hashes: Default::default(), protocol_version: Some(Default::default()), virtual_blocks: 0, diff --git a/core/bin/system-constants-generator/src/utils.rs b/core/bin/system-constants-generator/src/utils.rs index 800da68ee50d..16167975cf0e 100644 --- a/core/bin/system-constants-generator/src/utils.rs +++ b/core/bin/system-constants-generator/src/utils.rs @@ -9,7 +9,7 @@ use zksync_multivm::{ interface::{ storage::{InMemoryStorage, StorageView, WriteStorage}, tracer::VmExecutionStopReason, - L1BatchEnv, L2BlockEnv, SystemEnv, TxExecutionMode, VmExecutionMode, VmFactory, + InspectExecutionMode, L1BatchEnv, L2BlockEnv, SystemEnv, TxExecutionMode, VmFactory, VmInterface, VmInterfaceExt, }, tracers::dynamic::vm_1_5_0::DynTracer, @@ -271,8 +271,9 @@ pub(super) fn execute_internal_transfer_test() -> u32 { output: tracer_result.clone(), } .into_tracer_pointer(); + let mut vm: Vm<_, HistoryEnabled> = Vm::new(l1_batch, system_env, storage_view.to_rc_ptr()); - let result = vm.inspect(&mut tracer.into(), VmExecutionMode::Bootloader); + let result = vm.inspect(&mut tracer.into(), InspectExecutionMode::Bootloader); assert!(!result.result.is_failed(), "The internal call has reverted"); tracer_result.take() @@ -331,7 +332,7 @@ pub(super) fn execute_user_txs_in_test_gas_vm( let mut total_gas_refunded = 0; for tx in txs { vm.push_transaction(tx); - let tx_execution_result = vm.execute(VmExecutionMode::OneTx); + let tx_execution_result = vm.execute(InspectExecutionMode::OneTx); total_gas_refunded += tx_execution_result.refunds.gas_refunded; if !accept_failure { @@ -343,7 +344,7 @@ pub(super) fn execute_user_txs_in_test_gas_vm( } } - let result = vm.execute(VmExecutionMode::Bootloader); + let result = vm.execute(InspectExecutionMode::Bootloader); let metrics = result.get_execution_metrics(None); VmSpentResourcesResult { diff --git a/core/bin/zksync_server/src/node_builder.rs b/core/bin/zksync_server/src/node_builder.rs index 234e22894240..e2bd487f22b6 100644 --- a/core/bin/zksync_server/src/node_builder.rs +++ b/core/bin/zksync_server/src/node_builder.rs @@ -238,9 +238,7 @@ impl MainNodeBuilder { let wallets = self.wallets.clone(); let sk_config = try_load_config!(self.configs.state_keeper_config); let persistence_layer = OutputHandlerLayer::new( - self.contracts_config - .l2_shared_bridge_addr - .context("L2 shared bridge address")?, + self.contracts_config.l2_legacy_shared_bridge_addr, sk_config.l2_block_seal_queue_capacity, ) .with_protective_reads_persistence_enabled(sk_config.protective_reads_persistence_enabled); @@ -249,6 +247,8 @@ impl MainNodeBuilder { sk_config.clone(), try_load_config!(self.configs.mempool_config), try_load_config!(wallets.state_keeper), + self.contracts_config.l2_da_validator_addr, + self.genesis_config.l1_batch_commit_data_generator_mode, ); let db_config = try_load_config!(self.configs.db_config); let experimental_vm_config = self diff --git a/core/lib/basic_types/src/commitment.rs b/core/lib/basic_types/src/commitment.rs index eca339f40f42..0eed46aad782 100644 --- a/core/lib/basic_types/src/commitment.rs +++ b/core/lib/basic_types/src/commitment.rs @@ -1,10 +1,12 @@ +use std::str::FromStr; + use serde::{Deserialize, Serialize}; use strum::{Display, EnumIter}; use crate::{ ethabi, web3::contract::{Detokenize, Error as ContractError}, - U256, + Address, U256, }; #[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Serialize, Deserialize, EnumIter, Display)] @@ -41,3 +43,23 @@ impl Detokenize for L1BatchCommitmentMode { } } } + +impl FromStr for L1BatchCommitmentMode { + type Err = &'static str; + + fn from_str(s: &str) -> Result { + match s { + "Rollup" => Ok(Self::Rollup), + "Validium" => Ok(Self::Validium), + _ => { + Err("Incorrect l1 batch commitment mode type; expected one of `Rollup`, `Validium`") + } + } + } +} + +#[derive(Default, Copy, Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct PubdataParams { + pub l2_da_validator_address: Address, + pub pubdata_type: L1BatchCommitmentMode, +} diff --git a/core/lib/basic_types/src/protocol_version.rs b/core/lib/basic_types/src/protocol_version.rs index e01586cdad7d..ebecfaa1b872 100644 --- a/core/lib/basic_types/src/protocol_version.rs +++ b/core/lib/basic_types/src/protocol_version.rs @@ -69,6 +69,7 @@ pub enum ProtocolVersionId { Version24, Version25, Version26, + Version27, } impl ProtocolVersionId { @@ -122,6 +123,7 @@ impl ProtocolVersionId { ProtocolVersionId::Version24 => VmVersion::Vm1_5_0IncreasedBootloaderMemory, ProtocolVersionId::Version25 => VmVersion::Vm1_5_0IncreasedBootloaderMemory, ProtocolVersionId::Version26 => VmVersion::Vm1_5_0IncreasedBootloaderMemory, + ProtocolVersionId::Version27 => VmVersion::VmGateway, } } @@ -139,6 +141,10 @@ impl ProtocolVersionId { self <= &Self::Version22 } + pub fn is_pre_gateway(&self) -> bool { + self <= &Self::Version26 + } + pub fn is_1_4_0(&self) -> bool { self >= &ProtocolVersionId::Version18 && self < &ProtocolVersionId::Version20 } @@ -278,6 +284,7 @@ impl From for VmVersion { ProtocolVersionId::Version24 => VmVersion::Vm1_5_0IncreasedBootloaderMemory, ProtocolVersionId::Version25 => VmVersion::Vm1_5_0IncreasedBootloaderMemory, ProtocolVersionId::Version26 => VmVersion::Vm1_5_0IncreasedBootloaderMemory, + ProtocolVersionId::Version27 => VmVersion::VmGateway, } } } diff --git a/core/lib/basic_types/src/vm.rs b/core/lib/basic_types/src/vm.rs index c753bbfc8183..f11f98596f18 100644 --- a/core/lib/basic_types/src/vm.rs +++ b/core/lib/basic_types/src/vm.rs @@ -16,6 +16,7 @@ pub enum VmVersion { Vm1_4_2, Vm1_5_0SmallBootloaderMemory, Vm1_5_0IncreasedBootloaderMemory, + VmGateway, } impl VmVersion { diff --git a/core/lib/config/src/configs/contracts.rs b/core/lib/config/src/configs/contracts.rs index b68720ebaefe..0bf7aab3bcab 100644 --- a/core/lib/config/src/configs/contracts.rs +++ b/core/lib/config/src/configs/contracts.rs @@ -29,7 +29,13 @@ pub struct ContractsConfig { pub diamond_proxy_addr: Address, pub validator_timelock_addr: Address, pub l1_shared_bridge_proxy_addr: Option
, + /// Contract address that serves as a shared bridge on L2. + /// It is expected that `L2SharedBridge` is used before gateway upgrade, and `L2AssetRouter` is used after. pub l2_shared_bridge_addr: Option
, + /// Address of `L2SharedBridge` that was used before gateway upgrade. + /// `None` if chain genesis used post-gateway protocol version. + /// If present it will be used as L2 token deployer address. + pub l2_legacy_shared_bridge_addr: Option
, pub l1_erc20_bridge_proxy_addr: Option
, pub l2_erc20_bridge_addr: Option
, pub l1_weth_bridge_proxy_addr: Option
, @@ -40,6 +46,7 @@ pub struct ContractsConfig { // Used by the RPC API and by the node builder in wiring the BaseTokenRatioProvider layer. pub base_token_addr: Option
, pub chain_admin_addr: Option
, + pub l2_da_validator_addr: Option
, } impl ContractsConfig { @@ -53,6 +60,7 @@ impl ContractsConfig { l2_erc20_bridge_addr: Some(Address::repeat_byte(0x0c)), l1_shared_bridge_proxy_addr: Some(Address::repeat_byte(0x0e)), l2_shared_bridge_addr: Some(Address::repeat_byte(0x0f)), + l2_legacy_shared_bridge_addr: Some(Address::repeat_byte(0x19)), l1_weth_bridge_proxy_addr: Some(Address::repeat_byte(0x0b)), l2_weth_bridge_addr: Some(Address::repeat_byte(0x0c)), l2_testnet_paymaster_addr: Some(Address::repeat_byte(0x11)), @@ -61,6 +69,7 @@ impl ContractsConfig { base_token_addr: Some(Address::repeat_byte(0x14)), ecosystem_contracts: Some(EcosystemContracts::for_tests()), chain_admin_addr: Some(Address::repeat_byte(0x18)), + l2_da_validator_addr: Some(Address::repeat_byte(0x1a)), } } } diff --git a/core/lib/config/src/testonly.rs b/core/lib/config/src/testonly.rs index 880bc5aa98d2..ce681cc0cc43 100644 --- a/core/lib/config/src/testonly.rs +++ b/core/lib/config/src/testonly.rs @@ -262,6 +262,7 @@ impl Distribution for EncodeDist { l2_erc20_bridge_addr: self.sample_opt(|| rng.gen()), l1_shared_bridge_proxy_addr: self.sample_opt(|| rng.gen()), l2_shared_bridge_addr: self.sample_opt(|| rng.gen()), + l2_legacy_shared_bridge_addr: self.sample_opt(|| rng.gen()), l1_weth_bridge_proxy_addr: self.sample_opt(|| rng.gen()), l2_weth_bridge_addr: self.sample_opt(|| rng.gen()), l2_testnet_paymaster_addr: self.sample_opt(|| rng.gen()), @@ -269,6 +270,7 @@ impl Distribution for EncodeDist { ecosystem_contracts: self.sample(rng), base_token_addr: self.sample_opt(|| rng.gen()), chain_admin_addr: self.sample_opt(|| rng.gen()), + l2_da_validator_addr: self.sample_opt(|| rng.gen()), } } } diff --git a/core/lib/constants/src/contracts.rs b/core/lib/constants/src/contracts.rs index fe37ef6c69fd..4f0f362d9149 100644 --- a/core/lib/constants/src/contracts.rs +++ b/core/lib/constants/src/contracts.rs @@ -135,12 +135,36 @@ pub const EVM_GAS_MANAGER_ADDRESS: Address = H160([ 0x00, 0x00, 0x80, 0x13, ]); -/// Note, that the `Create2Factory` is explicitly deployed on a non-system-contract address. pub const CREATE2_FACTORY_ADDRESS: Address = H160([ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, ]); +pub const L2_GENESIS_UPGRADE_ADDRESS: Address = H160([ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x01, +]); + +pub const L2_BRIDGEHUB_ADDRESS: Address = H160([ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x02, +]); + +pub const L2_ASSET_ROUTER_ADDRESS: Address = H160([ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x03, +]); + +pub const L2_NATIVE_TOKEN_VAULT_ADDRESS: Address = H160([ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x04, +]); + +pub const L2_MESSAGE_ROOT_ADDRESS: Address = H160([ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x05, +]); + pub const ERC20_TRANSFER_TOPIC: H256 = H256([ 221, 242, 82, 173, 27, 226, 200, 155, 105, 194, 176, 104, 252, 55, 141, 170, 149, 43, 167, 241, 99, 196, 161, 22, 40, 245, 90, 77, 245, 35, 179, 239, diff --git a/core/lib/constants/src/lib.rs b/core/lib/constants/src/lib.rs index 6aab79ad71f3..30ae6a7b582a 100644 --- a/core/lib/constants/src/lib.rs +++ b/core/lib/constants/src/lib.rs @@ -3,6 +3,7 @@ pub mod contracts; pub mod crypto; pub mod ethereum; pub mod fees; +pub mod message_root; pub mod system_context; pub mod system_logs; pub mod trusted_slots; diff --git a/core/lib/constants/src/message_root.rs b/core/lib/constants/src/message_root.rs new file mode 100644 index 000000000000..a8f4a034fb99 --- /dev/null +++ b/core/lib/constants/src/message_root.rs @@ -0,0 +1,5 @@ +// Position of `FullTree::_height` in `MessageRoot`'s storage layout. +pub const AGG_TREE_HEIGHT_KEY: usize = 3; + +// Position of `FullTree::nodes` in `MessageRoot`'s storage layout. +pub const AGG_TREE_NODES_KEY: usize = 5; diff --git a/core/lib/constants/src/system_logs.rs b/core/lib/constants/src/system_logs.rs index bd4167b3d02c..aa2c2cc156cc 100644 --- a/core/lib/constants/src/system_logs.rs +++ b/core/lib/constants/src/system_logs.rs @@ -1,11 +1,8 @@ /// The key of the system log with value of the L2->L1 logs tree root hash pub const L2_TO_L1_LOGS_TREE_ROOT_KEY: u32 = 0; -/// The key of the system log with value of the state diff hash -pub const STATE_DIFF_HASH_KEY: u32 = 2; +/// The key of the system log with value of the state diff hash for pre-gateway protocol versions +pub const STATE_DIFF_HASH_KEY_PRE_GATEWAY: u32 = 2; -/// The key of the system log with value of the first blob linear hash -pub const BLOB1_LINEAR_HASH_KEY: u32 = 7; - -/// The key of the system log with value of the second blob linear hash -pub const BLOB2_LINEAR_HASH_KEY: u32 = 8; +/// The key of the system log with value of the first blob linear hash for pre-gateway protocol versions +pub const BLOB1_LINEAR_HASH_KEY_PRE_GATEWAY: u32 = 7; diff --git a/core/lib/contracts/src/lib.rs b/core/lib/contracts/src/lib.rs index 0ee773abcd4a..cb5be504c8a0 100644 --- a/core/lib/contracts/src/lib.rs +++ b/core/lib/contracts/src/lib.rs @@ -516,6 +516,13 @@ impl BaseSystemContracts { BaseSystemContracts::load_with_bootloader(bootloader_bytecode) } + pub fn playground_gateway() -> Self { + let bootloader_bytecode = read_zbin_bytecode( + "etc/multivm_bootloaders/vm_gateway/playground_batch.yul/playground_batch.yul.zbin", + ); + BaseSystemContracts::load_with_bootloader(bootloader_bytecode) + } + pub fn estimate_gas_pre_virtual_blocks() -> Self { let bootloader_bytecode = read_zbin_bytecode( "etc/multivm_bootloaders/vm_1_3_2/fee_estimate.yul/fee_estimate.yul.zbin", @@ -586,6 +593,13 @@ impl BaseSystemContracts { BaseSystemContracts::load_with_bootloader(bootloader_bytecode) } + pub fn estimate_gas_gateway() -> Self { + let bootloader_bytecode = read_zbin_bytecode( + "etc/multivm_bootloaders/vm_gateway/fee_estimate.yul/fee_estimate.yul.zbin", + ); + BaseSystemContracts::load_with_bootloader(bootloader_bytecode) + } + pub fn hashes(&self) -> BaseSystemContractsHashes { BaseSystemContractsHashes { bootloader: self.bootloader.hash, diff --git a/core/lib/dal/.sqlx/query-7aebc0d8eb43bd835c4f175edc4c0371bdc118b25d64fcf526bd6575e4d675c8.json b/core/lib/dal/.sqlx/query-1cb61327bed4d65a3fc81aa2229e01396dacefc0cea8cbcf5807185eb00fc0f7.json similarity index 78% rename from core/lib/dal/.sqlx/query-7aebc0d8eb43bd835c4f175edc4c0371bdc118b25d64fcf526bd6575e4d675c8.json rename to core/lib/dal/.sqlx/query-1cb61327bed4d65a3fc81aa2229e01396dacefc0cea8cbcf5807185eb00fc0f7.json index dffd3ed8f9d2..48adcd412676 100644 --- a/core/lib/dal/.sqlx/query-7aebc0d8eb43bd835c4f175edc4c0371bdc118b25d64fcf526bd6575e4d675c8.json +++ b/core/lib/dal/.sqlx/query-1cb61327bed4d65a3fc81aa2229e01396dacefc0cea8cbcf5807185eb00fc0f7.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "\n SELECT\n number,\n timestamp,\n l1_tx_count,\n l2_tx_count,\n bloom,\n priority_ops_onchain_data,\n hash,\n commitment,\n l2_to_l1_messages,\n used_contract_hashes,\n compressed_initial_writes,\n compressed_repeated_writes,\n l2_l1_merkle_root,\n rollup_last_leaf_index,\n zkporter_is_available,\n bootloader_code_hash,\n default_aa_code_hash,\n evm_emulator_code_hash,\n aux_data_hash,\n pass_through_data_hash,\n meta_parameters_hash,\n protocol_version,\n compressed_state_diffs,\n system_logs,\n events_queue_commitment,\n bootloader_initial_content_commitment,\n pubdata_input,\n fee_address\n FROM\n l1_batches\n LEFT JOIN commitments ON commitments.l1_batch_number = l1_batches.number\n WHERE\n number = 0\n OR eth_commit_tx_id IS NOT NULL\n AND commitment IS NOT NULL\n ORDER BY\n number DESC\n LIMIT\n 1\n ", + "query": "\n SELECT\n number,\n timestamp,\n l1_tx_count,\n l2_tx_count,\n bloom,\n priority_ops_onchain_data,\n hash,\n commitment,\n l2_to_l1_messages,\n used_contract_hashes,\n compressed_initial_writes,\n compressed_repeated_writes,\n l2_l1_merkle_root,\n rollup_last_leaf_index,\n zkporter_is_available,\n bootloader_code_hash,\n default_aa_code_hash,\n evm_emulator_code_hash,\n aux_data_hash,\n pass_through_data_hash,\n meta_parameters_hash,\n protocol_version,\n compressed_state_diffs,\n system_logs,\n events_queue_commitment,\n bootloader_initial_content_commitment,\n pubdata_input,\n fee_address,\n aggregation_root,\n local_root,\n state_diff_hash,\n data_availability.inclusion_data\n FROM\n l1_batches\n LEFT JOIN commitments ON commitments.l1_batch_number = l1_batches.number\n LEFT JOIN\n data_availability\n ON data_availability.l1_batch_number = l1_batches.number\n WHERE\n number = 0\n OR eth_commit_tx_id IS NOT NULL\n AND commitment IS NOT NULL\n ORDER BY\n number DESC\n LIMIT\n 1\n ", "describe": { "columns": [ { @@ -142,6 +142,26 @@ "ordinal": 27, "name": "fee_address", "type_info": "Bytea" + }, + { + "ordinal": 28, + "name": "aggregation_root", + "type_info": "Bytea" + }, + { + "ordinal": 29, + "name": "local_root", + "type_info": "Bytea" + }, + { + "ordinal": 30, + "name": "state_diff_hash", + "type_info": "Bytea" + }, + { + "ordinal": 31, + "name": "inclusion_data", + "type_info": "Bytea" } ], "parameters": { @@ -175,8 +195,12 @@ true, true, true, - false + false, + true, + true, + true, + true ] }, - "hash": "7aebc0d8eb43bd835c4f175edc4c0371bdc118b25d64fcf526bd6575e4d675c8" + "hash": "1cb61327bed4d65a3fc81aa2229e01396dacefc0cea8cbcf5807185eb00fc0f7" } diff --git a/core/lib/dal/.sqlx/query-a62f400a5b0b66300f5febf762c7e0c8a39a49d1cea78ef771d4c64fbbc16756.json b/core/lib/dal/.sqlx/query-250cc655f48144137906a72490680cc9e176729744c779fee97ca9392ae8a8c8.json similarity index 83% rename from core/lib/dal/.sqlx/query-a62f400a5b0b66300f5febf762c7e0c8a39a49d1cea78ef771d4c64fbbc16756.json rename to core/lib/dal/.sqlx/query-250cc655f48144137906a72490680cc9e176729744c779fee97ca9392ae8a8c8.json index c8c438295e49..5c4ce3d6a4e3 100644 --- a/core/lib/dal/.sqlx/query-a62f400a5b0b66300f5febf762c7e0c8a39a49d1cea78ef771d4c64fbbc16756.json +++ b/core/lib/dal/.sqlx/query-250cc655f48144137906a72490680cc9e176729744c779fee97ca9392ae8a8c8.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "\n SELECT\n number,\n timestamp,\n hash,\n l1_tx_count,\n l2_tx_count,\n fee_account_address AS \"fee_account_address!\",\n base_fee_per_gas,\n l1_gas_price,\n l2_fair_gas_price,\n gas_per_pubdata_limit,\n bootloader_code_hash,\n default_aa_code_hash,\n evm_emulator_code_hash,\n protocol_version,\n virtual_blocks,\n fair_pubdata_price,\n gas_limit,\n logs_bloom\n FROM\n miniblocks\n ORDER BY\n number DESC\n LIMIT\n 1\n ", + "query": "\n SELECT\n number,\n timestamp,\n hash,\n l1_tx_count,\n l2_tx_count,\n fee_account_address AS \"fee_account_address!\",\n base_fee_per_gas,\n l1_gas_price,\n l2_fair_gas_price,\n gas_per_pubdata_limit,\n bootloader_code_hash,\n default_aa_code_hash,\n evm_emulator_code_hash,\n protocol_version,\n virtual_blocks,\n fair_pubdata_price,\n gas_limit,\n logs_bloom,\n l2_da_validator_address,\n pubdata_type\n FROM\n miniblocks\n ORDER BY\n number DESC\n LIMIT\n 1\n ", "describe": { "columns": [ { @@ -92,6 +92,16 @@ "ordinal": 17, "name": "logs_bloom", "type_info": "Bytea" + }, + { + "ordinal": 18, + "name": "l2_da_validator_address", + "type_info": "Bytea" + }, + { + "ordinal": 19, + "name": "pubdata_type", + "type_info": "Text" } ], "parameters": { @@ -115,8 +125,10 @@ false, true, true, - true + true, + false, + false ] }, - "hash": "a62f400a5b0b66300f5febf762c7e0c8a39a49d1cea78ef771d4c64fbbc16756" + "hash": "250cc655f48144137906a72490680cc9e176729744c779fee97ca9392ae8a8c8" } diff --git a/core/lib/dal/.sqlx/query-55f4585be3d0f1a147cb10f6e59325fad494a512ba92df95439d2d7fe0f3a285.json b/core/lib/dal/.sqlx/query-398598e20f1892b47bf749b220f611345ef888824e0ca3c5f39befbbc5bd0388.json similarity index 65% rename from core/lib/dal/.sqlx/query-55f4585be3d0f1a147cb10f6e59325fad494a512ba92df95439d2d7fe0f3a285.json rename to core/lib/dal/.sqlx/query-398598e20f1892b47bf749b220f611345ef888824e0ca3c5f39befbbc5bd0388.json index ecf54f0417b8..ffe785d754ca 100644 --- a/core/lib/dal/.sqlx/query-55f4585be3d0f1a147cb10f6e59325fad494a512ba92df95439d2d7fe0f3a285.json +++ b/core/lib/dal/.sqlx/query-398598e20f1892b47bf749b220f611345ef888824e0ca3c5f39befbbc5bd0388.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "\n UPDATE l1_batches\n SET\n commitment = $1,\n aux_data_hash = $2,\n pass_through_data_hash = $3,\n meta_parameters_hash = $4,\n l2_l1_merkle_root = $5,\n zkporter_is_available = $6,\n compressed_state_diffs = $7,\n compressed_initial_writes = $8,\n compressed_repeated_writes = $9,\n updated_at = NOW()\n WHERE\n number = $10\n AND commitment IS NULL\n ", + "query": "\n UPDATE l1_batches\n SET\n commitment = $1,\n aux_data_hash = $2,\n pass_through_data_hash = $3,\n meta_parameters_hash = $4,\n l2_l1_merkle_root = $5,\n zkporter_is_available = $6,\n compressed_state_diffs = $7,\n compressed_initial_writes = $8,\n compressed_repeated_writes = $9,\n state_diff_hash = $10,\n aggregation_root = $11,\n local_root = $12,\n updated_at = NOW()\n WHERE\n number = $13\n AND commitment IS NULL\n ", "describe": { "columns": [], "parameters": { @@ -14,10 +14,13 @@ "Bytea", "Bytea", "Bytea", + "Bytea", + "Bytea", + "Bytea", "Int8" ] }, "nullable": [] }, - "hash": "55f4585be3d0f1a147cb10f6e59325fad494a512ba92df95439d2d7fe0f3a285" + "hash": "398598e20f1892b47bf749b220f611345ef888824e0ca3c5f39befbbc5bd0388" } diff --git a/core/lib/dal/.sqlx/query-942d6d948770c374ba4d3566c50e56e43137ac0cf45312d70dec0c407cadc1bf.json b/core/lib/dal/.sqlx/query-45154c2efc8d07c4f83ae3e229f9892118f5732374e62f35e27800422afb5746.json similarity index 70% rename from core/lib/dal/.sqlx/query-942d6d948770c374ba4d3566c50e56e43137ac0cf45312d70dec0c407cadc1bf.json rename to core/lib/dal/.sqlx/query-45154c2efc8d07c4f83ae3e229f9892118f5732374e62f35e27800422afb5746.json index 8c22b4f92c4e..11bff1102932 100644 --- a/core/lib/dal/.sqlx/query-942d6d948770c374ba4d3566c50e56e43137ac0cf45312d70dec0c407cadc1bf.json +++ b/core/lib/dal/.sqlx/query-45154c2efc8d07c4f83ae3e229f9892118f5732374e62f35e27800422afb5746.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "\n SELECT\n number,\n l1_batches.timestamp,\n l1_tx_count,\n l2_tx_count,\n bloom,\n priority_ops_onchain_data,\n hash,\n commitment,\n l2_to_l1_messages,\n used_contract_hashes,\n compressed_initial_writes,\n compressed_repeated_writes,\n l2_l1_merkle_root,\n rollup_last_leaf_index,\n zkporter_is_available,\n l1_batches.bootloader_code_hash,\n l1_batches.default_aa_code_hash,\n l1_batches.evm_emulator_code_hash,\n aux_data_hash,\n pass_through_data_hash,\n meta_parameters_hash,\n protocol_version,\n compressed_state_diffs,\n system_logs,\n events_queue_commitment,\n bootloader_initial_content_commitment,\n pubdata_input,\n fee_address\n FROM\n l1_batches\n LEFT JOIN commitments ON commitments.l1_batch_number = l1_batches.number\n LEFT JOIN\n data_availability\n ON data_availability.l1_batch_number = l1_batches.number\n JOIN protocol_versions ON protocol_versions.id = l1_batches.protocol_version\n WHERE\n eth_commit_tx_id IS NULL\n AND number != 0\n AND protocol_versions.bootloader_code_hash = $1\n AND protocol_versions.default_account_code_hash = $2\n AND commitment IS NOT NULL\n AND (\n protocol_versions.id = $3\n OR protocol_versions.upgrade_tx_hash IS NULL\n )\n AND events_queue_commitment IS NOT NULL\n AND bootloader_initial_content_commitment IS NOT NULL\n AND (\n data_availability.inclusion_data IS NOT NULL\n OR $4 IS FALSE\n )\n ORDER BY\n number\n LIMIT\n $5\n ", + "query": "\n SELECT\n number,\n l1_batches.timestamp,\n l1_tx_count,\n l2_tx_count,\n bloom,\n priority_ops_onchain_data,\n hash,\n commitment,\n l2_to_l1_messages,\n used_contract_hashes,\n compressed_initial_writes,\n compressed_repeated_writes,\n l2_l1_merkle_root,\n rollup_last_leaf_index,\n zkporter_is_available,\n l1_batches.bootloader_code_hash,\n l1_batches.default_aa_code_hash,\n l1_batches.evm_emulator_code_hash,\n aux_data_hash,\n pass_through_data_hash,\n meta_parameters_hash,\n protocol_version,\n compressed_state_diffs,\n system_logs,\n events_queue_commitment,\n bootloader_initial_content_commitment,\n pubdata_input,\n fee_address,\n aggregation_root,\n local_root,\n state_diff_hash,\n data_availability.inclusion_data\n FROM\n l1_batches\n LEFT JOIN commitments ON commitments.l1_batch_number = l1_batches.number\n LEFT JOIN\n data_availability\n ON data_availability.l1_batch_number = l1_batches.number\n JOIN protocol_versions ON protocol_versions.id = l1_batches.protocol_version\n WHERE\n eth_commit_tx_id IS NULL\n AND number != 0\n AND protocol_versions.bootloader_code_hash = $1\n AND protocol_versions.default_account_code_hash = $2\n AND commitment IS NOT NULL\n AND (\n protocol_versions.id = $3\n OR protocol_versions.upgrade_tx_hash IS NULL\n )\n AND events_queue_commitment IS NOT NULL\n AND bootloader_initial_content_commitment IS NOT NULL\n AND (\n data_availability.inclusion_data IS NOT NULL\n OR $4 IS FALSE\n )\n ORDER BY\n number\n LIMIT\n $5\n ", "describe": { "columns": [ { @@ -142,6 +142,26 @@ "ordinal": 27, "name": "fee_address", "type_info": "Bytea" + }, + { + "ordinal": 28, + "name": "aggregation_root", + "type_info": "Bytea" + }, + { + "ordinal": 29, + "name": "local_root", + "type_info": "Bytea" + }, + { + "ordinal": 30, + "name": "state_diff_hash", + "type_info": "Bytea" + }, + { + "ordinal": 31, + "name": "inclusion_data", + "type_info": "Bytea" } ], "parameters": { @@ -181,8 +201,12 @@ true, true, true, - false + false, + true, + true, + true, + true ] }, - "hash": "942d6d948770c374ba4d3566c50e56e43137ac0cf45312d70dec0c407cadc1bf" + "hash": "45154c2efc8d07c4f83ae3e229f9892118f5732374e62f35e27800422afb5746" } diff --git a/core/lib/dal/.sqlx/query-e2d0bd978f76e0ce09b36b0e4b0a2baec4b2531ecaa8da234863e2eb810761c7.json b/core/lib/dal/.sqlx/query-4bd1a4e612d10f2ca26068c140442f38816f163a3e3fba4fdbb81076b969e970.json similarity index 79% rename from core/lib/dal/.sqlx/query-e2d0bd978f76e0ce09b36b0e4b0a2baec4b2531ecaa8da234863e2eb810761c7.json rename to core/lib/dal/.sqlx/query-4bd1a4e612d10f2ca26068c140442f38816f163a3e3fba4fdbb81076b969e970.json index e55d10d6f9a8..66d3e18075bf 100644 --- a/core/lib/dal/.sqlx/query-e2d0bd978f76e0ce09b36b0e4b0a2baec4b2531ecaa8da234863e2eb810761c7.json +++ b/core/lib/dal/.sqlx/query-4bd1a4e612d10f2ca26068c140442f38816f163a3e3fba4fdbb81076b969e970.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "\n SELECT\n number,\n timestamp,\n l1_tx_count,\n l2_tx_count,\n bloom,\n priority_ops_onchain_data,\n hash,\n commitment,\n l2_to_l1_messages,\n used_contract_hashes,\n compressed_initial_writes,\n compressed_repeated_writes,\n l2_l1_merkle_root,\n rollup_last_leaf_index,\n zkporter_is_available,\n bootloader_code_hash,\n default_aa_code_hash,\n evm_emulator_code_hash,\n aux_data_hash,\n pass_through_data_hash,\n meta_parameters_hash,\n protocol_version,\n compressed_state_diffs,\n system_logs,\n events_queue_commitment,\n bootloader_initial_content_commitment,\n pubdata_input,\n fee_address\n FROM\n l1_batches\n LEFT JOIN commitments ON commitments.l1_batch_number = l1_batches.number\n WHERE\n number BETWEEN $1 AND $2\n ORDER BY\n number\n LIMIT\n $3\n ", + "query": "\n SELECT\n number,\n timestamp,\n l1_tx_count,\n l2_tx_count,\n bloom,\n priority_ops_onchain_data,\n hash,\n commitment,\n l2_to_l1_messages,\n used_contract_hashes,\n compressed_initial_writes,\n compressed_repeated_writes,\n l2_l1_merkle_root,\n rollup_last_leaf_index,\n zkporter_is_available,\n bootloader_code_hash,\n default_aa_code_hash,\n evm_emulator_code_hash,\n aux_data_hash,\n pass_through_data_hash,\n meta_parameters_hash,\n protocol_version,\n compressed_state_diffs,\n system_logs,\n events_queue_commitment,\n bootloader_initial_content_commitment,\n pubdata_input,\n fee_address,\n aggregation_root,\n local_root,\n state_diff_hash,\n data_availability.inclusion_data\n FROM\n l1_batches\n LEFT JOIN commitments ON commitments.l1_batch_number = l1_batches.number\n LEFT JOIN\n data_availability\n ON data_availability.l1_batch_number = l1_batches.number\n WHERE\n number BETWEEN $1 AND $2\n ORDER BY\n number\n LIMIT\n $3\n ", "describe": { "columns": [ { @@ -142,6 +142,26 @@ "ordinal": 27, "name": "fee_address", "type_info": "Bytea" + }, + { + "ordinal": 28, + "name": "aggregation_root", + "type_info": "Bytea" + }, + { + "ordinal": 29, + "name": "local_root", + "type_info": "Bytea" + }, + { + "ordinal": 30, + "name": "state_diff_hash", + "type_info": "Bytea" + }, + { + "ordinal": 31, + "name": "inclusion_data", + "type_info": "Bytea" } ], "parameters": { @@ -179,8 +199,12 @@ true, true, true, - false + false, + true, + true, + true, + true ] }, - "hash": "e2d0bd978f76e0ce09b36b0e4b0a2baec4b2531ecaa8da234863e2eb810761c7" + "hash": "4bd1a4e612d10f2ca26068c140442f38816f163a3e3fba4fdbb81076b969e970" } diff --git a/core/lib/dal/.sqlx/query-0784f2cc13f85763cc7da29902850fa76a03907957b7a0d87ea55a7873f3312e.json b/core/lib/dal/.sqlx/query-62e8330881b73917394384adbf73911add046315e5f8877bc57a34e3dadf9e37.json similarity index 79% rename from core/lib/dal/.sqlx/query-0784f2cc13f85763cc7da29902850fa76a03907957b7a0d87ea55a7873f3312e.json rename to core/lib/dal/.sqlx/query-62e8330881b73917394384adbf73911add046315e5f8877bc57a34e3dadf9e37.json index 84f677a36c86..dfdb4b6c82e7 100644 --- a/core/lib/dal/.sqlx/query-0784f2cc13f85763cc7da29902850fa76a03907957b7a0d87ea55a7873f3312e.json +++ b/core/lib/dal/.sqlx/query-62e8330881b73917394384adbf73911add046315e5f8877bc57a34e3dadf9e37.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "\n SELECT\n number,\n timestamp,\n l1_tx_count,\n l2_tx_count,\n bloom,\n priority_ops_onchain_data,\n hash,\n commitment,\n l2_to_l1_messages,\n used_contract_hashes,\n compressed_initial_writes,\n compressed_repeated_writes,\n l2_l1_merkle_root,\n rollup_last_leaf_index,\n zkporter_is_available,\n bootloader_code_hash,\n default_aa_code_hash,\n evm_emulator_code_hash,\n aux_data_hash,\n pass_through_data_hash,\n meta_parameters_hash,\n protocol_version,\n compressed_state_diffs,\n system_logs,\n events_queue_commitment,\n bootloader_initial_content_commitment,\n pubdata_input,\n fee_address\n FROM\n l1_batches\n LEFT JOIN commitments ON commitments.l1_batch_number = l1_batches.number\n WHERE\n eth_commit_tx_id IS NOT NULL\n AND eth_prove_tx_id IS NULL\n ORDER BY\n number\n LIMIT\n $1\n ", + "query": "\n SELECT\n number,\n timestamp,\n l1_tx_count,\n l2_tx_count,\n bloom,\n priority_ops_onchain_data,\n hash,\n commitment,\n l2_to_l1_messages,\n used_contract_hashes,\n compressed_initial_writes,\n compressed_repeated_writes,\n l2_l1_merkle_root,\n rollup_last_leaf_index,\n zkporter_is_available,\n bootloader_code_hash,\n default_aa_code_hash,\n evm_emulator_code_hash,\n aux_data_hash,\n pass_through_data_hash,\n meta_parameters_hash,\n protocol_version,\n compressed_state_diffs,\n system_logs,\n events_queue_commitment,\n bootloader_initial_content_commitment,\n pubdata_input,\n fee_address,\n aggregation_root,\n local_root,\n state_diff_hash,\n data_availability.inclusion_data\n FROM\n l1_batches\n LEFT JOIN commitments ON commitments.l1_batch_number = l1_batches.number\n LEFT JOIN\n data_availability\n ON data_availability.l1_batch_number = l1_batches.number\n WHERE\n eth_commit_tx_id IS NOT NULL\n AND eth_prove_tx_id IS NULL\n ORDER BY\n number\n LIMIT\n $1\n ", "describe": { "columns": [ { @@ -142,6 +142,26 @@ "ordinal": 27, "name": "fee_address", "type_info": "Bytea" + }, + { + "ordinal": 28, + "name": "aggregation_root", + "type_info": "Bytea" + }, + { + "ordinal": 29, + "name": "local_root", + "type_info": "Bytea" + }, + { + "ordinal": 30, + "name": "state_diff_hash", + "type_info": "Bytea" + }, + { + "ordinal": 31, + "name": "inclusion_data", + "type_info": "Bytea" } ], "parameters": { @@ -177,8 +197,12 @@ true, true, true, - false + false, + true, + true, + true, + true ] }, - "hash": "0784f2cc13f85763cc7da29902850fa76a03907957b7a0d87ea55a7873f3312e" + "hash": "62e8330881b73917394384adbf73911add046315e5f8877bc57a34e3dadf9e37" } diff --git a/core/lib/dal/.sqlx/query-2049362aad5e32981e48e5c5ef7a00a91254ec6c8a68a359d22b02df5a40911f.json b/core/lib/dal/.sqlx/query-7553d8013d101af0451830d26b7d7bd02627ebaf2df7c5ad517cb60a243182d2.json similarity index 83% rename from core/lib/dal/.sqlx/query-2049362aad5e32981e48e5c5ef7a00a91254ec6c8a68a359d22b02df5a40911f.json rename to core/lib/dal/.sqlx/query-7553d8013d101af0451830d26b7d7bd02627ebaf2df7c5ad517cb60a243182d2.json index b8f8db874b63..6cc2e22382dd 100644 --- a/core/lib/dal/.sqlx/query-2049362aad5e32981e48e5c5ef7a00a91254ec6c8a68a359d22b02df5a40911f.json +++ b/core/lib/dal/.sqlx/query-7553d8013d101af0451830d26b7d7bd02627ebaf2df7c5ad517cb60a243182d2.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "\n SELECT\n miniblocks.number,\n COALESCE(\n miniblocks.l1_batch_number,\n (\n SELECT\n (MAX(number) + 1)\n FROM\n l1_batches\n WHERE\n is_sealed\n ),\n (\n SELECT\n MAX(l1_batch_number) + 1\n FROM\n snapshot_recovery\n )\n ) AS \"l1_batch_number!\",\n (miniblocks.l1_tx_count + miniblocks.l2_tx_count) AS \"tx_count!\",\n miniblocks.timestamp,\n miniblocks.l1_gas_price,\n miniblocks.l2_fair_gas_price,\n miniblocks.fair_pubdata_price,\n miniblocks.bootloader_code_hash,\n miniblocks.default_aa_code_hash,\n miniblocks.evm_emulator_code_hash,\n miniblocks.virtual_blocks,\n miniblocks.hash,\n miniblocks.protocol_version AS \"protocol_version!\",\n miniblocks.fee_account_address AS \"fee_account_address!\"\n FROM\n miniblocks\n WHERE\n miniblocks.number BETWEEN $1 AND $2\n ", + "query": "\n SELECT\n miniblocks.number,\n COALESCE(\n miniblocks.l1_batch_number,\n (\n SELECT\n (MAX(number) + 1)\n FROM\n l1_batches\n WHERE\n is_sealed\n ),\n (\n SELECT\n MAX(l1_batch_number) + 1\n FROM\n snapshot_recovery\n )\n ) AS \"l1_batch_number!\",\n (miniblocks.l1_tx_count + miniblocks.l2_tx_count) AS \"tx_count!\",\n miniblocks.timestamp,\n miniblocks.l1_gas_price,\n miniblocks.l2_fair_gas_price,\n miniblocks.fair_pubdata_price,\n miniblocks.bootloader_code_hash,\n miniblocks.default_aa_code_hash,\n miniblocks.evm_emulator_code_hash,\n miniblocks.virtual_blocks,\n miniblocks.hash,\n miniblocks.protocol_version AS \"protocol_version!\",\n miniblocks.fee_account_address AS \"fee_account_address!\",\n miniblocks.l2_da_validator_address AS \"l2_da_validator_address!\",\n miniblocks.pubdata_type AS \"pubdata_type!\"\n FROM\n miniblocks\n WHERE\n miniblocks.number BETWEEN $1 AND $2\n ", "describe": { "columns": [ { @@ -72,6 +72,16 @@ "ordinal": 13, "name": "fee_account_address!", "type_info": "Bytea" + }, + { + "ordinal": 14, + "name": "l2_da_validator_address!", + "type_info": "Bytea" + }, + { + "ordinal": 15, + "name": "pubdata_type!", + "type_info": "Text" } ], "parameters": { @@ -94,8 +104,10 @@ false, false, true, + false, + false, false ] }, - "hash": "2049362aad5e32981e48e5c5ef7a00a91254ec6c8a68a359d22b02df5a40911f" + "hash": "7553d8013d101af0451830d26b7d7bd02627ebaf2df7c5ad517cb60a243182d2" } diff --git a/core/lib/dal/.sqlx/query-b456147560b107640abdc10f7ac76b563ff2f0f3a818e8c8a02c2ef632d0b960.json b/core/lib/dal/.sqlx/query-77864e5eb5eada8edf8f4457aa153369701d7cd5f75ca031bf77ca27d0437cb9.json similarity index 80% rename from core/lib/dal/.sqlx/query-b456147560b107640abdc10f7ac76b563ff2f0f3a818e8c8a02c2ef632d0b960.json rename to core/lib/dal/.sqlx/query-77864e5eb5eada8edf8f4457aa153369701d7cd5f75ca031bf77ca27d0437cb9.json index 80a6946026b0..f4e08abe31c5 100644 --- a/core/lib/dal/.sqlx/query-b456147560b107640abdc10f7ac76b563ff2f0f3a818e8c8a02c2ef632d0b960.json +++ b/core/lib/dal/.sqlx/query-77864e5eb5eada8edf8f4457aa153369701d7cd5f75ca031bf77ca27d0437cb9.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "\n SELECT\n number,\n timestamp,\n l1_tx_count,\n l2_tx_count,\n bloom,\n priority_ops_onchain_data,\n hash,\n commitment,\n l2_to_l1_messages,\n used_contract_hashes,\n compressed_initial_writes,\n compressed_repeated_writes,\n l2_l1_merkle_root,\n rollup_last_leaf_index,\n zkporter_is_available,\n bootloader_code_hash,\n default_aa_code_hash,\n evm_emulator_code_hash,\n aux_data_hash,\n pass_through_data_hash,\n meta_parameters_hash,\n protocol_version,\n system_logs,\n compressed_state_diffs,\n events_queue_commitment,\n bootloader_initial_content_commitment,\n pubdata_input,\n fee_address\n FROM\n l1_batches\n LEFT JOIN commitments ON commitments.l1_batch_number = l1_batches.number\n WHERE\n is_sealed\n AND number = $1\n ", + "query": "\n SELECT\n number,\n timestamp,\n l1_tx_count,\n l2_tx_count,\n bloom,\n priority_ops_onchain_data,\n hash,\n commitment,\n l2_to_l1_messages,\n used_contract_hashes,\n compressed_initial_writes,\n compressed_repeated_writes,\n l2_l1_merkle_root,\n rollup_last_leaf_index,\n zkporter_is_available,\n bootloader_code_hash,\n default_aa_code_hash,\n evm_emulator_code_hash,\n aux_data_hash,\n pass_through_data_hash,\n meta_parameters_hash,\n protocol_version,\n system_logs,\n compressed_state_diffs,\n events_queue_commitment,\n bootloader_initial_content_commitment,\n pubdata_input,\n fee_address,\n aggregation_root,\n local_root,\n state_diff_hash,\n data_availability.inclusion_data\n FROM\n l1_batches\n LEFT JOIN commitments ON commitments.l1_batch_number = l1_batches.number\n LEFT JOIN\n data_availability\n ON data_availability.l1_batch_number = l1_batches.number\n WHERE\n is_sealed\n AND number = $1\n ", "describe": { "columns": [ { @@ -142,6 +142,26 @@ "ordinal": 27, "name": "fee_address", "type_info": "Bytea" + }, + { + "ordinal": 28, + "name": "aggregation_root", + "type_info": "Bytea" + }, + { + "ordinal": 29, + "name": "local_root", + "type_info": "Bytea" + }, + { + "ordinal": 30, + "name": "state_diff_hash", + "type_info": "Bytea" + }, + { + "ordinal": 31, + "name": "inclusion_data", + "type_info": "Bytea" } ], "parameters": { @@ -177,8 +197,12 @@ true, true, true, - false + false, + true, + true, + true, + true ] }, - "hash": "b456147560b107640abdc10f7ac76b563ff2f0f3a818e8c8a02c2ef632d0b960" + "hash": "77864e5eb5eada8edf8f4457aa153369701d7cd5f75ca031bf77ca27d0437cb9" } diff --git a/core/lib/dal/.sqlx/query-34910600545933d85931d41bfe2dfcb3522a0772ac3d2476652df4216d823e04.json b/core/lib/dal/.sqlx/query-7d8c19c3568c03ec3e4a788b22c233f6503bc79cc9f809d35c558e275ba117ba.json similarity index 55% rename from core/lib/dal/.sqlx/query-34910600545933d85931d41bfe2dfcb3522a0772ac3d2476652df4216d823e04.json rename to core/lib/dal/.sqlx/query-7d8c19c3568c03ec3e4a788b22c233f6503bc79cc9f809d35c558e275ba117ba.json index 35c606bf22bb..f89f531c4463 100644 --- a/core/lib/dal/.sqlx/query-34910600545933d85931d41bfe2dfcb3522a0772ac3d2476652df4216d823e04.json +++ b/core/lib/dal/.sqlx/query-7d8c19c3568c03ec3e4a788b22c233f6503bc79cc9f809d35c558e275ba117ba.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "\n INSERT INTO\n miniblocks (\n number,\n timestamp,\n hash,\n l1_tx_count,\n l2_tx_count,\n fee_account_address,\n base_fee_per_gas,\n l1_gas_price,\n l2_fair_gas_price,\n gas_per_pubdata_limit,\n bootloader_code_hash,\n default_aa_code_hash,\n evm_emulator_code_hash,\n protocol_version,\n virtual_blocks,\n fair_pubdata_price,\n gas_limit,\n logs_bloom,\n created_at,\n updated_at\n )\n VALUES\n (\n $1,\n $2,\n $3,\n $4,\n $5,\n $6,\n $7,\n $8,\n $9,\n $10,\n $11,\n $12,\n $13,\n $14,\n $15,\n $16,\n $17,\n $18,\n NOW(),\n NOW()\n )\n ", + "query": "\n INSERT INTO\n miniblocks (\n number,\n timestamp,\n hash,\n l1_tx_count,\n l2_tx_count,\n fee_account_address,\n base_fee_per_gas,\n l1_gas_price,\n l2_fair_gas_price,\n gas_per_pubdata_limit,\n bootloader_code_hash,\n default_aa_code_hash,\n evm_emulator_code_hash,\n protocol_version,\n virtual_blocks,\n fair_pubdata_price,\n gas_limit,\n logs_bloom,\n l2_da_validator_address,\n pubdata_type,\n created_at,\n updated_at\n )\n VALUES\n (\n $1,\n $2,\n $3,\n $4,\n $5,\n $6,\n $7,\n $8,\n $9,\n $10,\n $11,\n $12,\n $13,\n $14,\n $15,\n $16,\n $17,\n $18,\n $19,\n $20,\n NOW(),\n NOW()\n )\n ", "describe": { "columns": [], "parameters": { @@ -22,10 +22,12 @@ "Int8", "Int8", "Int8", - "Bytea" + "Bytea", + "Bytea", + "Text" ] }, "nullable": [] }, - "hash": "34910600545933d85931d41bfe2dfcb3522a0772ac3d2476652df4216d823e04" + "hash": "7d8c19c3568c03ec3e4a788b22c233f6503bc79cc9f809d35c558e275ba117ba" } diff --git a/core/lib/dal/.sqlx/query-f30748bef5f8d08b60739cdfd9508c8132d0958e4e25f4954e93d2095b4f11e8.json b/core/lib/dal/.sqlx/query-a42121cd85daeb95ee268ba5cff1806fcc54d73216a7dc54be6ba210ef02d789.json similarity index 73% rename from core/lib/dal/.sqlx/query-f30748bef5f8d08b60739cdfd9508c8132d0958e4e25f4954e93d2095b4f11e8.json rename to core/lib/dal/.sqlx/query-a42121cd85daeb95ee268ba5cff1806fcc54d73216a7dc54be6ba210ef02d789.json index 4f138822ad1b..9a93ba45978e 100644 --- a/core/lib/dal/.sqlx/query-f30748bef5f8d08b60739cdfd9508c8132d0958e4e25f4954e93d2095b4f11e8.json +++ b/core/lib/dal/.sqlx/query-a42121cd85daeb95ee268ba5cff1806fcc54d73216a7dc54be6ba210ef02d789.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "\n SELECT\n number,\n timestamp,\n l1_tx_count,\n l2_tx_count,\n bloom,\n priority_ops_onchain_data,\n hash,\n commitment,\n l2_to_l1_messages,\n used_contract_hashes,\n compressed_initial_writes,\n compressed_repeated_writes,\n l2_l1_merkle_root,\n rollup_last_leaf_index,\n zkporter_is_available,\n bootloader_code_hash,\n default_aa_code_hash,\n evm_emulator_code_hash,\n aux_data_hash,\n pass_through_data_hash,\n meta_parameters_hash,\n system_logs,\n compressed_state_diffs,\n protocol_version,\n events_queue_commitment,\n bootloader_initial_content_commitment,\n pubdata_input,\n fee_address\n FROM\n (\n SELECT\n l1_batches.*,\n ROW_NUMBER() OVER (\n ORDER BY\n number ASC\n ) AS row_number\n FROM\n l1_batches\n WHERE\n eth_commit_tx_id IS NOT NULL\n AND l1_batches.skip_proof = TRUE\n AND l1_batches.number > $1\n ORDER BY\n number\n LIMIT\n $2\n ) inn\n LEFT JOIN commitments ON commitments.l1_batch_number = inn.number\n WHERE\n number - row_number = $1\n ", + "query": "\n SELECT\n number,\n timestamp,\n l1_tx_count,\n l2_tx_count,\n bloom,\n priority_ops_onchain_data,\n hash,\n commitment,\n l2_to_l1_messages,\n used_contract_hashes,\n compressed_initial_writes,\n compressed_repeated_writes,\n l2_l1_merkle_root,\n rollup_last_leaf_index,\n zkporter_is_available,\n bootloader_code_hash,\n default_aa_code_hash,\n evm_emulator_code_hash,\n aux_data_hash,\n pass_through_data_hash,\n meta_parameters_hash,\n system_logs,\n compressed_state_diffs,\n protocol_version,\n events_queue_commitment,\n bootloader_initial_content_commitment,\n pubdata_input,\n fee_address,\n aggregation_root,\n local_root,\n state_diff_hash,\n data_availability.inclusion_data\n FROM\n (\n SELECT\n l1_batches.*,\n ROW_NUMBER() OVER (\n ORDER BY\n number ASC\n ) AS row_number\n FROM\n l1_batches\n WHERE\n eth_commit_tx_id IS NOT NULL\n AND l1_batches.skip_proof = TRUE\n AND l1_batches.number > $1\n ORDER BY\n number\n LIMIT\n $2\n ) inn\n LEFT JOIN commitments ON commitments.l1_batch_number = inn.number\n LEFT JOIN data_availability ON data_availability.l1_batch_number = inn.number\n WHERE\n number - row_number = $1\n ", "describe": { "columns": [ { @@ -142,6 +142,26 @@ "ordinal": 27, "name": "fee_address", "type_info": "Bytea" + }, + { + "ordinal": 28, + "name": "aggregation_root", + "type_info": "Bytea" + }, + { + "ordinal": 29, + "name": "local_root", + "type_info": "Bytea" + }, + { + "ordinal": 30, + "name": "state_diff_hash", + "type_info": "Bytea" + }, + { + "ordinal": 31, + "name": "inclusion_data", + "type_info": "Bytea" } ], "parameters": { @@ -178,8 +198,12 @@ true, true, true, - false + false, + true, + true, + true, + true ] }, - "hash": "f30748bef5f8d08b60739cdfd9508c8132d0958e4e25f4954e93d2095b4f11e8" + "hash": "a42121cd85daeb95ee268ba5cff1806fcc54d73216a7dc54be6ba210ef02d789" } diff --git a/core/lib/dal/.sqlx/query-2def67eb8372245ed59e76e07d615598f5d22a3aebd893afddded0e3c6b94a3b.json b/core/lib/dal/.sqlx/query-b7d448837439a3e3dfe73070d3c20e9c138d0a6d35e9ce7fc396c5e76fbc25dd.json similarity index 73% rename from core/lib/dal/.sqlx/query-2def67eb8372245ed59e76e07d615598f5d22a3aebd893afddded0e3c6b94a3b.json rename to core/lib/dal/.sqlx/query-b7d448837439a3e3dfe73070d3c20e9c138d0a6d35e9ce7fc396c5e76fbc25dd.json index afac14e6d5cd..8a68b1a9b9bd 100644 --- a/core/lib/dal/.sqlx/query-2def67eb8372245ed59e76e07d615598f5d22a3aebd893afddded0e3c6b94a3b.json +++ b/core/lib/dal/.sqlx/query-b7d448837439a3e3dfe73070d3c20e9c138d0a6d35e9ce7fc396c5e76fbc25dd.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "\n SELECT\n number,\n l1_batches.timestamp,\n l1_tx_count,\n l2_tx_count,\n bloom,\n priority_ops_onchain_data,\n hash,\n commitment,\n l2_to_l1_messages,\n used_contract_hashes,\n compressed_initial_writes,\n compressed_repeated_writes,\n l2_l1_merkle_root,\n rollup_last_leaf_index,\n zkporter_is_available,\n l1_batches.bootloader_code_hash,\n l1_batches.default_aa_code_hash,\n l1_batches.evm_emulator_code_hash,\n aux_data_hash,\n pass_through_data_hash,\n meta_parameters_hash,\n protocol_version,\n compressed_state_diffs,\n system_logs,\n events_queue_commitment,\n bootloader_initial_content_commitment,\n pubdata_input,\n fee_address\n FROM\n l1_batches\n LEFT JOIN commitments ON commitments.l1_batch_number = l1_batches.number\n JOIN protocol_versions ON protocol_versions.id = l1_batches.protocol_version\n WHERE\n eth_commit_tx_id IS NULL\n AND number != 0\n AND protocol_versions.bootloader_code_hash = $1\n AND protocol_versions.default_account_code_hash = $2\n AND commitment IS NOT NULL\n AND (\n protocol_versions.id = $3\n OR protocol_versions.upgrade_tx_hash IS NULL\n )\n ORDER BY\n number\n LIMIT\n $4\n ", + "query": "\n SELECT\n number,\n l1_batches.timestamp,\n l1_tx_count,\n l2_tx_count,\n bloom,\n priority_ops_onchain_data,\n hash,\n commitment,\n l2_to_l1_messages,\n used_contract_hashes,\n compressed_initial_writes,\n compressed_repeated_writes,\n l2_l1_merkle_root,\n rollup_last_leaf_index,\n zkporter_is_available,\n l1_batches.bootloader_code_hash,\n l1_batches.default_aa_code_hash,\n l1_batches.evm_emulator_code_hash,\n aux_data_hash,\n pass_through_data_hash,\n meta_parameters_hash,\n protocol_version,\n compressed_state_diffs,\n system_logs,\n events_queue_commitment,\n bootloader_initial_content_commitment,\n pubdata_input,\n fee_address,\n aggregation_root,\n local_root,\n state_diff_hash,\n data_availability.inclusion_data\n FROM\n l1_batches\n LEFT JOIN commitments ON commitments.l1_batch_number = l1_batches.number\n JOIN protocol_versions ON protocol_versions.id = l1_batches.protocol_version\n LEFT JOIN\n data_availability\n ON data_availability.l1_batch_number = l1_batches.number\n WHERE\n eth_commit_tx_id IS NULL\n AND number != 0\n AND protocol_versions.bootloader_code_hash = $1\n AND protocol_versions.default_account_code_hash = $2\n AND commitment IS NOT NULL\n AND (\n protocol_versions.id = $3\n OR protocol_versions.upgrade_tx_hash IS NULL\n )\n ORDER BY\n number\n LIMIT\n $4\n ", "describe": { "columns": [ { @@ -142,6 +142,26 @@ "ordinal": 27, "name": "fee_address", "type_info": "Bytea" + }, + { + "ordinal": 28, + "name": "aggregation_root", + "type_info": "Bytea" + }, + { + "ordinal": 29, + "name": "local_root", + "type_info": "Bytea" + }, + { + "ordinal": 30, + "name": "state_diff_hash", + "type_info": "Bytea" + }, + { + "ordinal": 31, + "name": "inclusion_data", + "type_info": "Bytea" } ], "parameters": { @@ -180,8 +200,12 @@ true, true, true, - false + false, + true, + true, + true, + true ] }, - "hash": "2def67eb8372245ed59e76e07d615598f5d22a3aebd893afddded0e3c6b94a3b" + "hash": "b7d448837439a3e3dfe73070d3c20e9c138d0a6d35e9ce7fc396c5e76fbc25dd" } diff --git a/core/lib/dal/.sqlx/query-5aa487a98dff53a5d32a5916a26cbf3ffb03b3791c0e9a9f39fb85cfffc65db2.json b/core/lib/dal/.sqlx/query-c5aedd2b1871d8f6276a31482caa673e4b5bba059ebe07bbbb64578881db030b.json similarity index 77% rename from core/lib/dal/.sqlx/query-5aa487a98dff53a5d32a5916a26cbf3ffb03b3791c0e9a9f39fb85cfffc65db2.json rename to core/lib/dal/.sqlx/query-c5aedd2b1871d8f6276a31482caa673e4b5bba059ebe07bbbb64578881db030b.json index 4eae4f778cee..f97ea8a6ccd5 100644 --- a/core/lib/dal/.sqlx/query-5aa487a98dff53a5d32a5916a26cbf3ffb03b3791c0e9a9f39fb85cfffc65db2.json +++ b/core/lib/dal/.sqlx/query-c5aedd2b1871d8f6276a31482caa673e4b5bba059ebe07bbbb64578881db030b.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "\n SELECT\n number,\n timestamp,\n l1_tx_count,\n l2_tx_count,\n bloom,\n priority_ops_onchain_data,\n hash,\n commitment,\n l2_to_l1_messages,\n used_contract_hashes,\n compressed_initial_writes,\n compressed_repeated_writes,\n l2_l1_merkle_root,\n rollup_last_leaf_index,\n zkporter_is_available,\n bootloader_code_hash,\n default_aa_code_hash,\n evm_emulator_code_hash,\n aux_data_hash,\n pass_through_data_hash,\n meta_parameters_hash,\n protocol_version,\n compressed_state_diffs,\n system_logs,\n events_queue_commitment,\n bootloader_initial_content_commitment,\n pubdata_input,\n fee_address\n FROM\n l1_batches\n LEFT JOIN commitments ON commitments.l1_batch_number = l1_batches.number\n WHERE\n eth_prove_tx_id IS NOT NULL\n AND eth_execute_tx_id IS NULL\n ORDER BY\n number\n LIMIT\n $1\n ", + "query": "\n SELECT\n number,\n timestamp,\n l1_tx_count,\n l2_tx_count,\n bloom,\n priority_ops_onchain_data,\n hash,\n commitment,\n l2_to_l1_messages,\n used_contract_hashes,\n compressed_initial_writes,\n compressed_repeated_writes,\n l2_l1_merkle_root,\n rollup_last_leaf_index,\n zkporter_is_available,\n bootloader_code_hash,\n default_aa_code_hash,\n evm_emulator_code_hash,\n aux_data_hash,\n pass_through_data_hash,\n meta_parameters_hash,\n protocol_version,\n compressed_state_diffs,\n system_logs,\n events_queue_commitment,\n bootloader_initial_content_commitment,\n pubdata_input,\n fee_address,\n aggregation_root,\n local_root,\n state_diff_hash,\n data_availability.inclusion_data\n FROM\n l1_batches\n LEFT JOIN commitments ON commitments.l1_batch_number = l1_batches.number\n LEFT JOIN\n data_availability\n ON data_availability.l1_batch_number = l1_batches.number\n WHERE\n eth_prove_tx_id IS NOT NULL\n AND eth_execute_tx_id IS NULL\n ORDER BY\n number\n LIMIT\n $1\n ", "describe": { "columns": [ { @@ -142,6 +142,26 @@ "ordinal": 27, "name": "fee_address", "type_info": "Bytea" + }, + { + "ordinal": 28, + "name": "aggregation_root", + "type_info": "Bytea" + }, + { + "ordinal": 29, + "name": "local_root", + "type_info": "Bytea" + }, + { + "ordinal": 30, + "name": "state_diff_hash", + "type_info": "Bytea" + }, + { + "ordinal": 31, + "name": "inclusion_data", + "type_info": "Bytea" } ], "parameters": { @@ -177,8 +197,12 @@ true, true, true, - false + false, + true, + true, + true, + true ] }, - "hash": "5aa487a98dff53a5d32a5916a26cbf3ffb03b3791c0e9a9f39fb85cfffc65db2" + "hash": "c5aedd2b1871d8f6276a31482caa673e4b5bba059ebe07bbbb64578881db030b" } diff --git a/core/lib/dal/.sqlx/query-f208ac4d454220cdd5cf8fa1405b21ca4cc94c38a7d18023ef1e89de484e60d8.json b/core/lib/dal/.sqlx/query-d4cdd4eed07dfdad2757c480903f7999eabb611338925abe9dc9e64c837183d9.json similarity index 84% rename from core/lib/dal/.sqlx/query-f208ac4d454220cdd5cf8fa1405b21ca4cc94c38a7d18023ef1e89de484e60d8.json rename to core/lib/dal/.sqlx/query-d4cdd4eed07dfdad2757c480903f7999eabb611338925abe9dc9e64c837183d9.json index 700352c1a8bf..111234e02b75 100644 --- a/core/lib/dal/.sqlx/query-f208ac4d454220cdd5cf8fa1405b21ca4cc94c38a7d18023ef1e89de484e60d8.json +++ b/core/lib/dal/.sqlx/query-d4cdd4eed07dfdad2757c480903f7999eabb611338925abe9dc9e64c837183d9.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "\n SELECT\n number,\n timestamp,\n hash,\n l1_tx_count,\n l2_tx_count,\n fee_account_address AS \"fee_account_address!\",\n base_fee_per_gas,\n l1_gas_price,\n l2_fair_gas_price,\n gas_per_pubdata_limit,\n bootloader_code_hash,\n default_aa_code_hash,\n evm_emulator_code_hash,\n protocol_version,\n virtual_blocks,\n fair_pubdata_price,\n gas_limit,\n logs_bloom\n FROM\n miniblocks\n WHERE\n number = $1\n ", + "query": "\n SELECT\n number,\n timestamp,\n hash,\n l1_tx_count,\n l2_tx_count,\n fee_account_address AS \"fee_account_address!\",\n base_fee_per_gas,\n l1_gas_price,\n l2_fair_gas_price,\n gas_per_pubdata_limit,\n bootloader_code_hash,\n default_aa_code_hash,\n evm_emulator_code_hash,\n protocol_version,\n virtual_blocks,\n fair_pubdata_price,\n gas_limit,\n logs_bloom,\n l2_da_validator_address,\n pubdata_type\n FROM\n miniblocks\n WHERE\n number = $1\n ", "describe": { "columns": [ { @@ -92,6 +92,16 @@ "ordinal": 17, "name": "logs_bloom", "type_info": "Bytea" + }, + { + "ordinal": 18, + "name": "l2_da_validator_address", + "type_info": "Bytea" + }, + { + "ordinal": 19, + "name": "pubdata_type", + "type_info": "Text" } ], "parameters": { @@ -117,8 +127,10 @@ false, true, true, - true + true, + false, + false ] }, - "hash": "f208ac4d454220cdd5cf8fa1405b21ca4cc94c38a7d18023ef1e89de484e60d8" + "hash": "d4cdd4eed07dfdad2757c480903f7999eabb611338925abe9dc9e64c837183d9" } diff --git a/core/lib/dal/migrations/20240925103531_gateway_upgrade.down.sql b/core/lib/dal/migrations/20240925103531_gateway_upgrade.down.sql new file mode 100644 index 000000000000..9af34d7dc8ee --- /dev/null +++ b/core/lib/dal/migrations/20240925103531_gateway_upgrade.down.sql @@ -0,0 +1,8 @@ +ALTER TABLE l1_batches DROP COLUMN IF EXISTS state_diff_hash BYTEA; + +ALTER TABLE l1_batches DROP COLUMN IF EXISTS aggregation_root; +ALTER TABLE l1_batches DROP COLUMN IF EXISTS local_root; + +ALTER TABLE miniblocks + DROP COLUMN IF EXISTS l2_da_validator_address, + DROP COLUMN IF EXISTS pubdata_type; diff --git a/core/lib/dal/migrations/20240925103531_gateway_upgrade.up.sql b/core/lib/dal/migrations/20240925103531_gateway_upgrade.up.sql new file mode 100644 index 000000000000..a58464f6ebb3 --- /dev/null +++ b/core/lib/dal/migrations/20240925103531_gateway_upgrade.up.sql @@ -0,0 +1,11 @@ +ALTER TABLE l1_batches ADD COLUMN IF NOT EXISTS state_diff_hash BYTEA; + +ALTER TABLE l1_batches ADD COLUMN IF NOT EXISTS aggregation_root BYTEA; +ALTER TABLE l1_batches ADD COLUMN IF NOT EXISTS local_root BYTEA; + +ALTER TABLE miniblocks + ADD COLUMN IF NOT EXISTS l2_da_validator_address BYTEA NOT NULL DEFAULT '\x0000000000000000000000000000000000000000'::bytea, + -- There are miniblocks that used the `Rollup' type, but were actually used on a Validium chain. + -- This is okay, since this field represents how the VM works with the DA, rather what is committed on L1. + ADD COLUMN IF NOT EXISTS pubdata_type TEXT NOT NULL DEFAULT 'Rollup'; +-- ^ Add a default value so that DB queries don't fail even if the DB migration is not completed. diff --git a/core/lib/dal/src/blocks_dal.rs b/core/lib/dal/src/blocks_dal.rs index f71dc68ce757..943aa12caf75 100644 --- a/core/lib/dal/src/blocks_dal.rs +++ b/core/lib/dal/src/blocks_dal.rs @@ -344,10 +344,17 @@ impl BlocksDal<'_, '_> { events_queue_commitment, bootloader_initial_content_commitment, pubdata_input, - fee_address + fee_address, + aggregation_root, + local_root, + state_diff_hash, + data_availability.inclusion_data FROM l1_batches LEFT JOIN commitments ON commitments.l1_batch_number = l1_batches.number + LEFT JOIN + data_availability + ON data_availability.l1_batch_number = l1_batches.number WHERE is_sealed AND number = $1 @@ -841,6 +848,8 @@ impl BlocksDal<'_, '_> { fair_pubdata_price, gas_limit, logs_bloom, + l2_da_validator_address, + pubdata_type, created_at, updated_at ) @@ -864,6 +873,8 @@ impl BlocksDal<'_, '_> { $16, $17, $18, + $19, + $20, NOW(), NOW() ) @@ -896,6 +907,11 @@ impl BlocksDal<'_, '_> { l2_block_header.batch_fee_input.fair_pubdata_price() as i64, l2_block_header.gas_limit as i64, l2_block_header.logs_bloom.as_bytes(), + l2_block_header + .pubdata_params + .l2_da_validator_address + .as_bytes(), + l2_block_header.pubdata_params.pubdata_type.to_string(), ); instrumentation.with(query).execute(self.storage).await?; @@ -924,7 +940,9 @@ impl BlocksDal<'_, '_> { virtual_blocks, fair_pubdata_price, gas_limit, - logs_bloom + logs_bloom, + l2_da_validator_address, + pubdata_type FROM miniblocks ORDER BY @@ -965,7 +983,9 @@ impl BlocksDal<'_, '_> { virtual_blocks, fair_pubdata_price, gas_limit, - logs_bloom + logs_bloom, + l2_da_validator_address, + pubdata_type FROM miniblocks WHERE @@ -1062,9 +1082,12 @@ impl BlocksDal<'_, '_> { compressed_state_diffs = $7, compressed_initial_writes = $8, compressed_repeated_writes = $9, + state_diff_hash = $10, + aggregation_root = $11, + local_root = $12, updated_at = NOW() WHERE - number = $10 + number = $13 AND commitment IS NULL "#, commitment_artifacts.commitment_hash.commitment.as_bytes(), @@ -1082,6 +1105,9 @@ impl BlocksDal<'_, '_> { commitment_artifacts.compressed_state_diffs, commitment_artifacts.compressed_initial_writes, commitment_artifacts.compressed_repeated_writes, + commitment_artifacts.state_diff_hash.as_bytes(), + commitment_artifacts.aggregation_root.as_bytes(), + commitment_artifacts.local_root.as_bytes(), i64::from(number.0), ) .instrument("save_l1_batch_commitment_artifacts") @@ -1189,10 +1215,17 @@ impl BlocksDal<'_, '_> { events_queue_commitment, bootloader_initial_content_commitment, pubdata_input, - fee_address + fee_address, + aggregation_root, + local_root, + state_diff_hash, + data_availability.inclusion_data FROM l1_batches LEFT JOIN commitments ON commitments.l1_batch_number = l1_batches.number + LEFT JOIN + data_availability + ON data_availability.l1_batch_number = l1_batches.number WHERE number = 0 OR eth_commit_tx_id IS NOT NULL @@ -1377,10 +1410,17 @@ impl BlocksDal<'_, '_> { events_queue_commitment, bootloader_initial_content_commitment, pubdata_input, - fee_address + fee_address, + aggregation_root, + local_root, + state_diff_hash, + data_availability.inclusion_data FROM l1_batches LEFT JOIN commitments ON commitments.l1_batch_number = l1_batches.number + LEFT JOIN + data_availability + ON data_availability.l1_batch_number = l1_batches.number WHERE eth_commit_tx_id IS NOT NULL AND eth_prove_tx_id IS NULL @@ -1459,7 +1499,11 @@ impl BlocksDal<'_, '_> { events_queue_commitment, bootloader_initial_content_commitment, pubdata_input, - fee_address + fee_address, + aggregation_root, + local_root, + state_diff_hash, + data_availability.inclusion_data FROM ( SELECT @@ -1480,6 +1524,7 @@ impl BlocksDal<'_, '_> { $2 ) inn LEFT JOIN commitments ON commitments.l1_batch_number = inn.number + LEFT JOIN data_availability ON data_availability.l1_batch_number = inn.number WHERE number - row_number = $1 "#, @@ -1534,10 +1579,17 @@ impl BlocksDal<'_, '_> { events_queue_commitment, bootloader_initial_content_commitment, pubdata_input, - fee_address + fee_address, + aggregation_root, + local_root, + state_diff_hash, + data_availability.inclusion_data FROM l1_batches LEFT JOIN commitments ON commitments.l1_batch_number = l1_batches.number + LEFT JOIN + data_availability + ON data_availability.l1_batch_number = l1_batches.number WHERE eth_prove_tx_id IS NOT NULL AND eth_execute_tx_id IS NULL @@ -1663,10 +1715,17 @@ impl BlocksDal<'_, '_> { events_queue_commitment, bootloader_initial_content_commitment, pubdata_input, - fee_address + fee_address, + aggregation_root, + local_root, + state_diff_hash, + data_availability.inclusion_data FROM l1_batches LEFT JOIN commitments ON commitments.l1_batch_number = l1_batches.number + LEFT JOIN + data_availability + ON data_availability.l1_batch_number = l1_batches.number WHERE number BETWEEN $1 AND $2 ORDER BY @@ -1729,11 +1788,18 @@ impl BlocksDal<'_, '_> { events_queue_commitment, bootloader_initial_content_commitment, pubdata_input, - fee_address + fee_address, + aggregation_root, + local_root, + state_diff_hash, + data_availability.inclusion_data FROM l1_batches LEFT JOIN commitments ON commitments.l1_batch_number = l1_batches.number JOIN protocol_versions ON protocol_versions.id = l1_batches.protocol_version + LEFT JOIN + data_availability + ON data_availability.l1_batch_number = l1_batches.number WHERE eth_commit_tx_id IS NULL AND number != 0 @@ -1809,7 +1875,11 @@ impl BlocksDal<'_, '_> { events_queue_commitment, bootloader_initial_content_commitment, pubdata_input, - fee_address + fee_address, + aggregation_root, + local_root, + state_diff_hash, + data_availability.inclusion_data FROM l1_batches LEFT JOIN commitments ON commitments.l1_batch_number = l1_batches.number diff --git a/core/lib/dal/src/consensus/conv.rs b/core/lib/dal/src/consensus/conv.rs index 269c47fa2dd1..2b8488dd0c2a 100644 --- a/core/lib/dal/src/consensus/conv.rs +++ b/core/lib/dal/src/consensus/conv.rs @@ -4,7 +4,9 @@ use zksync_concurrency::net; use zksync_consensus_roles::{attester, node}; use zksync_protobuf::{read_required, required, ProtoFmt, ProtoRepr}; use zksync_types::{ - abi, ethabi, + abi, + commitment::{L1BatchCommitmentMode, PubdataParams}, + ethabi, fee::Fee, l1::{OpProcessingType, PriorityQueueType}, l2::TransactionType, @@ -135,6 +137,20 @@ impl ProtoFmt for Payload { } } + let pubdata_params = if let Some(pubdata_params) = &r.pubdata_params { + Some(PubdataParams { + l2_da_validator_address: required(&pubdata_params.l2_da_validator_address) + .and_then(|a| parse_h160(a)) + .context("l2_da_validator_address")?, + pubdata_type: required(&pubdata_params.pubdata_type) + .and_then(|x| Ok(proto::L1BatchCommitDataGeneratorMode::try_from(*x)?)) + .context("pubdata_type")? + .parse(), + }) + } else { + None + }; + Ok(Self { protocol_version, hash: required(&r.hash) @@ -153,6 +169,7 @@ impl ProtoFmt for Payload { .context("operator_address")?, transactions, last_in_batch: *required(&r.last_in_batch).context("last_in_batch")?, + pubdata_params, }) } @@ -171,6 +188,16 @@ impl ProtoFmt for Payload { transactions: vec![], transactions_v25: vec![], last_in_batch: Some(self.last_in_batch), + pubdata_params: self + .pubdata_params + .map(|pubdata_params| proto::PubdataParams { + l2_da_validator_address: Some( + pubdata_params.l2_da_validator_address.as_bytes().into(), + ), + pubdata_type: Some(proto::L1BatchCommitDataGeneratorMode::new( + &pubdata_params.pubdata_type, + ) as i32), + }), }; match self.protocol_version { v if v >= ProtocolVersionId::Version25 => { @@ -517,3 +544,19 @@ impl ProtoRepr for proto::AttesterCommittee { } } } + +impl proto::L1BatchCommitDataGeneratorMode { + pub(crate) fn new(n: &L1BatchCommitmentMode) -> Self { + match n { + L1BatchCommitmentMode::Rollup => Self::Rollup, + L1BatchCommitmentMode::Validium => Self::Validium, + } + } + + pub(crate) fn parse(&self) -> L1BatchCommitmentMode { + match self { + Self::Rollup => L1BatchCommitmentMode::Rollup, + Self::Validium => L1BatchCommitmentMode::Validium, + } + } +} diff --git a/core/lib/dal/src/consensus/mod.rs b/core/lib/dal/src/consensus/mod.rs index 8e88265730e9..c7e46b2cf1b7 100644 --- a/core/lib/dal/src/consensus/mod.rs +++ b/core/lib/dal/src/consensus/mod.rs @@ -2,7 +2,9 @@ use std::collections::BTreeMap; use zksync_concurrency::net; use zksync_consensus_roles::{attester, node, validator}; -use zksync_types::{ethabi, Address, L1BatchNumber, ProtocolVersionId, Transaction, H256}; +use zksync_types::{ + commitment::PubdataParams, ethabi, Address, L1BatchNumber, ProtocolVersionId, Transaction, H256, +}; mod conv; pub mod proto; @@ -46,6 +48,7 @@ pub struct Payload { pub operator_address: Address, pub transactions: Vec, pub last_in_batch: bool, + pub pubdata_params: Option, } impl Payload { diff --git a/core/lib/dal/src/consensus/proto/mod.proto b/core/lib/dal/src/consensus/proto/mod.proto index 421904bf966b..49a69e8a36ec 100644 --- a/core/lib/dal/src/consensus/proto/mod.proto +++ b/core/lib/dal/src/consensus/proto/mod.proto @@ -26,6 +26,12 @@ message Payload { // Set for protocol_version >= 25. repeated TransactionV25 transactions_v25 = 12; optional bool last_in_batch = 10; // required + optional PubdataParams pubdata_params = 13; // optional +} + +message PubdataParams { + optional bytes l2_da_validator_address = 1; // required; H160 + optional L1BatchCommitDataGeneratorMode pubdata_type = 2; // required } message L1Transaction { @@ -142,3 +148,8 @@ message AttestationStatus { optional roles.validator.GenesisHash genesis = 1; // required optional uint64 next_batch_to_attest = 2; // required } + +enum L1BatchCommitDataGeneratorMode { + Rollup = 0; + Validium = 1; +} diff --git a/core/lib/dal/src/consensus/tests.rs b/core/lib/dal/src/consensus/tests.rs index e8342b7446cc..c9fd91748b2b 100644 --- a/core/lib/dal/src/consensus/tests.rs +++ b/core/lib/dal/src/consensus/tests.rs @@ -9,7 +9,9 @@ use zksync_protobuf::{ }; use zksync_test_account::Account; use zksync_types::{ - web3::Bytes, Execute, ExecuteTransactionCommon, L1BatchNumber, ProtocolVersionId, Transaction, + commitment::{L1BatchCommitmentMode, PubdataParams}, + web3::Bytes, + Execute, ExecuteTransactionCommon, L1BatchNumber, ProtocolVersionId, Transaction, }; use super::*; @@ -51,6 +53,13 @@ fn payload(rng: &mut impl Rng, protocol_version: ProtocolVersionId) -> Payload { }) .collect(), last_in_batch: rng.gen(), + pubdata_params: Some(PubdataParams { + pubdata_type: match rng.gen_range(0..2) { + 0 => L1BatchCommitmentMode::Rollup, + _ => L1BatchCommitmentMode::Validium, + }, + l2_da_validator_address: rng.gen(), + }), } } diff --git a/core/lib/dal/src/consensus_dal/tests.rs b/core/lib/dal/src/consensus_dal/tests.rs index 772e7b2bf5e7..694abc8508b6 100644 --- a/core/lib/dal/src/consensus_dal/tests.rs +++ b/core/lib/dal/src/consensus_dal/tests.rs @@ -131,6 +131,9 @@ async fn test_batch_certificate() { compressed_repeated_writes: None, zkporter_is_available: false, aux_commitments: None, + aggregation_root: rng.gen(), + local_root: rng.gen(), + state_diff_hash: rng.gen(), }, ) .await diff --git a/core/lib/dal/src/eth_watcher_dal.rs b/core/lib/dal/src/eth_watcher_dal.rs index bdfc7f24c7b5..062ad47219d8 100644 --- a/core/lib/dal/src/eth_watcher_dal.rs +++ b/core/lib/dal/src/eth_watcher_dal.rs @@ -107,7 +107,7 @@ mod tests { async fn test_get_or_set_next_block_to_process_with_different_event_types() { let pool = ConnectionPool::::test_pool().await; let mut conn = pool.connection().await.unwrap(); - let mut dal = conn.processed_events_dal(); + let mut dal = conn.eth_watcher_dal(); // Test with ProtocolUpgrades let next_block = dal diff --git a/core/lib/dal/src/lib.rs b/core/lib/dal/src/lib.rs index fbe225beb902..20b428adec44 100644 --- a/core/lib/dal/src/lib.rs +++ b/core/lib/dal/src/lib.rs @@ -131,7 +131,7 @@ where fn base_token_dal(&mut self) -> BaseTokenDal<'_, 'a>; - fn processed_events_dal(&mut self) -> EthWatcherDal<'_, 'a>; + fn eth_watcher_dal(&mut self) -> EthWatcherDal<'_, 'a>; } #[derive(Clone, Debug)] @@ -255,7 +255,7 @@ impl<'a> CoreDal<'a> for Connection<'a, Core> { BaseTokenDal { storage: self } } - fn processed_events_dal(&mut self) -> EthWatcherDal<'_, 'a> { + fn eth_watcher_dal(&mut self) -> EthWatcherDal<'_, 'a> { EthWatcherDal { storage: self } } } diff --git a/core/lib/dal/src/models/storage_block.rs b/core/lib/dal/src/models/storage_block.rs index 3bb433a05cf8..159ed71cc3e9 100644 --- a/core/lib/dal/src/models/storage_block.rs +++ b/core/lib/dal/src/models/storage_block.rs @@ -7,7 +7,7 @@ use zksync_contracts::BaseSystemContractsHashes; use zksync_types::{ api, block::{L1BatchHeader, L2BlockHeader, UnsealedL1BatchHeader}, - commitment::{L1BatchMetaParameters, L1BatchMetadata}, + commitment::{L1BatchCommitmentMode, L1BatchMetaParameters, L1BatchMetadata, PubdataParams}, fee_model::{BatchFeeInput, L1PeggedBatchFeeModelInput, PubdataIndependentBatchFeeModelInput}, l2_to_l1_log::{L2ToL1Log, SystemL2ToL1Log, UserL2ToL1Log}, Address, Bloom, L1BatchNumber, L2BlockNumber, ProtocolVersionId, H256, @@ -155,6 +155,10 @@ pub(crate) struct StorageL1Batch { pub bootloader_initial_content_commitment: Option>, pub pubdata_input: Option>, pub fee_address: Vec, + pub aggregation_root: Option>, + pub local_root: Option>, + pub state_diff_hash: Option>, + pub inclusion_data: Option>, } impl StorageL1Batch { @@ -263,6 +267,10 @@ impl TryFrom for L1BatchMetadata { bootloader_initial_content_commitment: batch .bootloader_initial_content_commitment .map(|v| H256::from_slice(&v)), + state_diff_hash: batch.state_diff_hash.map(|v| H256::from_slice(&v)), + local_root: batch.local_root.map(|v| H256::from_slice(&v)), + aggregation_root: batch.aggregation_root.map(|v| H256::from_slice(&v)), + da_inclusion_data: batch.inclusion_data, }) } } @@ -485,6 +493,8 @@ pub(crate) struct StorageL2BlockHeader { /// This value should bound the maximal amount of gas that can be spent by transactions in the miniblock. pub gas_limit: Option, pub logs_bloom: Option>, + pub l2_da_validator_address: Vec, + pub pubdata_type: String, } impl From for L2BlockHeader { @@ -532,6 +542,10 @@ impl From for L2BlockHeader { .logs_bloom .map(|b| Bloom::from_slice(&b)) .unwrap_or_default(), + pubdata_params: PubdataParams { + l2_da_validator_address: Address::from_slice(&row.l2_da_validator_address), + pubdata_type: L1BatchCommitmentMode::from_str(&row.pubdata_type).unwrap(), + }, } } } diff --git a/core/lib/dal/src/models/storage_sync.rs b/core/lib/dal/src/models/storage_sync.rs index 7a4ebe074fe0..0eb65a606d1f 100644 --- a/core/lib/dal/src/models/storage_sync.rs +++ b/core/lib/dal/src/models/storage_sync.rs @@ -1,7 +1,11 @@ +use std::str::FromStr; + use zksync_contracts::BaseSystemContractsHashes; use zksync_db_connection::error::SqlxContext; use zksync_types::{ - api::en, parse_h160, parse_h256, parse_h256_opt, Address, L1BatchNumber, L2BlockNumber, + api::en, + commitment::{L1BatchCommitmentMode, PubdataParams}, + parse_h160, parse_h256, parse_h256_opt, Address, L1BatchNumber, L2BlockNumber, ProtocolVersionId, Transaction, H256, }; @@ -25,6 +29,8 @@ pub(crate) struct StorageSyncBlock { pub protocol_version: i32, pub virtual_blocks: i64, pub hash: Vec, + pub l2_da_validator_address: Vec, + pub pubdata_type: String, } pub(crate) struct SyncBlock { @@ -40,6 +46,7 @@ pub(crate) struct SyncBlock { pub virtual_blocks: u32, pub hash: H256, pub protocol_version: ProtocolVersionId, + pub pubdata_params: PubdataParams, } impl TryFrom for SyncBlock { @@ -89,6 +96,12 @@ impl TryFrom for SyncBlock { .decode_column("virtual_blocks")?, hash: parse_h256(&block.hash).decode_column("hash")?, protocol_version: parse_protocol_version(block.protocol_version)?, + pubdata_params: PubdataParams { + pubdata_type: L1BatchCommitmentMode::from_str(&block.pubdata_type) + .decode_column("Invalid pubdata type")?, + l2_da_validator_address: parse_h160(&block.l2_da_validator_address) + .decode_column("l2_da_validator_address")?, + }, }) } } @@ -109,6 +122,7 @@ impl SyncBlock { virtual_blocks: Some(self.virtual_blocks), hash: Some(self.hash), protocol_version: self.protocol_version, + pubdata_params: Some(self.pubdata_params), } } @@ -125,6 +139,7 @@ impl SyncBlock { operator_address: self.fee_account_address, transactions, last_in_batch: self.last_in_batch, + pubdata_params: Some(self.pubdata_params), } } } diff --git a/core/lib/dal/src/sync_dal.rs b/core/lib/dal/src/sync_dal.rs index 265c61354887..55e6543c0285 100644 --- a/core/lib/dal/src/sync_dal.rs +++ b/core/lib/dal/src/sync_dal.rs @@ -56,7 +56,9 @@ impl SyncDal<'_, '_> { miniblocks.virtual_blocks, miniblocks.hash, miniblocks.protocol_version AS "protocol_version!", - miniblocks.fee_account_address AS "fee_account_address!" + miniblocks.fee_account_address AS "fee_account_address!", + miniblocks.l2_da_validator_address AS "l2_da_validator_address!", + miniblocks.pubdata_type AS "pubdata_type!" FROM miniblocks WHERE diff --git a/core/lib/dal/src/tests/mod.rs b/core/lib/dal/src/tests/mod.rs index bf85008f7b58..baa2ee584856 100644 --- a/core/lib/dal/src/tests/mod.rs +++ b/core/lib/dal/src/tests/mod.rs @@ -4,6 +4,7 @@ use zksync_contracts::BaseSystemContractsHashes; use zksync_db_connection::connection_pool::ConnectionPool; use zksync_types::{ block::{L1BatchHeader, L2BlockHasher, L2BlockHeader}, + commitment::PubdataParams, fee::Fee, fee_model::BatchFeeInput, helpers::unix_timestamp_ms, @@ -52,6 +53,7 @@ pub(crate) fn create_l2_block_header(number: u32) -> L2BlockHeader { virtual_blocks: 1, gas_limit: 0, logs_bloom: Default::default(), + pubdata_params: PubdataParams::default(), } } diff --git a/core/lib/env_config/src/contracts.rs b/core/lib/env_config/src/contracts.rs index 298c43b80ccd..3792f356be4e 100644 --- a/core/lib/env_config/src/contracts.rs +++ b/core/lib/env_config/src/contracts.rs @@ -63,6 +63,7 @@ mod tests { l2_weth_bridge_addr: Some(addr("8656770FA78c830456B00B4fFCeE6b1De0e1b888")), l1_shared_bridge_proxy_addr: Some(addr("8656770FA78c830456B00B4fFCeE6b1De0e1b888")), l2_shared_bridge_addr: Some(addr("8656770FA78c830456B00B4fFCeE6b1De0e1b888")), + l2_legacy_shared_bridge_addr: Some(addr("8656770FA78c830456B00B4fFCeE6b1De0e1b888")), l2_testnet_paymaster_addr: Some(addr("FC073319977e314F251EAE6ae6bE76B0B3BAeeCF")), l1_multicall3_addr: addr("0xcA11bde05977b3631167028862bE2a173976CA11"), ecosystem_contracts: Some(EcosystemContracts { @@ -72,6 +73,7 @@ mod tests { }), base_token_addr: Some(SHARED_BRIDGE_ETHER_TOKEN_ADDRESS), chain_admin_addr: Some(addr("0xdd6fa5c14e7550b4caf2aa2818d24c69cbc347ff")), + l2_da_validator_addr: Some(addr("0xed6fa5c14e7550b4caf2aa2818d24c69cbc347ff")), } } @@ -93,11 +95,13 @@ CONTRACTS_L2_CONSENSUS_REGISTRY_ADDR="D64e136566a9E04eb05B30184fF577F52682D182" CONTRACTS_L1_MULTICALL3_ADDR="0xcA11bde05977b3631167028862bE2a173976CA11" CONTRACTS_L1_SHARED_BRIDGE_PROXY_ADDR="0x8656770FA78c830456B00B4fFCeE6b1De0e1b888" CONTRACTS_L2_SHARED_BRIDGE_ADDR="0x8656770FA78c830456B00B4fFCeE6b1De0e1b888" +CONTRACTS_L2_LEGACY_SHARED_BRIDGE_ADDR="0x8656770FA78c830456B00B4fFCeE6b1De0e1b888" CONTRACTS_BRIDGEHUB_PROXY_ADDR="0x35ea7f92f4c5f433efe15284e99c040110cf6297" CONTRACTS_STATE_TRANSITION_PROXY_ADDR="0xd90f1c081c6117241624e97cb6147257c3cb2097" CONTRACTS_TRANSPARENT_PROXY_ADMIN_ADDR="0xdd6fa5c14e7550b4caf2aa2818d24c69cbc347e5" CONTRACTS_BASE_TOKEN_ADDR="0x0000000000000000000000000000000000000001" CONTRACTS_CHAIN_ADMIN_ADDR="0xdd6fa5c14e7550b4caf2aa2818d24c69cbc347ff" +CONTRACTS_L2_DA_VALIDATOR_ADDR="0xed6fa5c14e7550b4caf2aa2818d24c69cbc347ff" "#; lock.set_env(config); diff --git a/core/lib/eth_client/src/clients/http/query.rs b/core/lib/eth_client/src/clients/http/query.rs index 5e788509461d..de115cf6e7a6 100644 --- a/core/lib/eth_client/src/clients/http/query.rs +++ b/core/lib/eth_client/src/clients/http/query.rs @@ -15,7 +15,7 @@ use crate::{ BaseFees, EthFeeInterface, EthInterface, RawTransactionBytes, }; -const FEE_HISTORY_MAX_REQUEST_CHUNK: usize = 1024; +const FEE_HISTORY_MAX_REQUEST_CHUNK: usize = 1023; #[async_trait] impl EthInterface for T @@ -304,14 +304,14 @@ where COUNTERS.call[&(Method::BaseFeeHistory, client.component())].inc(); let latency = LATENCIES.direct[&Method::BaseFeeHistory].start(); let mut history = Vec::with_capacity(block_count); - let from_block = upto_block.saturating_sub(block_count); + let from_block = upto_block.saturating_sub(block_count - 1); // Here we are requesting `fee_history` from blocks // `(from_block; upto_block)` in chunks of size `MAX_REQUEST_CHUNK` // starting from the oldest block. for chunk_start in (from_block..=upto_block).step_by(FEE_HISTORY_MAX_REQUEST_CHUNK) { let chunk_end = (chunk_start + FEE_HISTORY_MAX_REQUEST_CHUNK).min(upto_block); - let chunk_size = chunk_end - chunk_start; + let chunk_size = chunk_end - chunk_start + 1; let fee_history = client .fee_history( @@ -324,22 +324,50 @@ where .with_arg("block", &chunk_end) .await?; - // Check that the lengths are the same. + if fee_history.oldest_block != web3::BlockNumber::Number(chunk_start.into()) { + let oldest_block = match fee_history.oldest_block { + web3::BlockNumber::Number(oldest_block) => oldest_block.to_string(), + _ => format!("{:?}", fee_history.oldest_block), + }; + let message = + format!("unexpected `oldest_block`, expected: {chunk_start}, got {oldest_block}"); + return Err(EnrichedClientError::custom(message, "l1_fee_history") + .with_arg("chunk_size", &chunk_size) + .with_arg("chunk_end", &chunk_end)); + } + + if fee_history.base_fee_per_gas.len() != chunk_size + 1 { + let message = format!( + "unexpected `base_fee_per_gas.len()`, expected: {}, got {}", + chunk_size + 1, + fee_history.base_fee_per_gas.len() + ); + return Err(EnrichedClientError::custom(message, "l1_fee_history") + .with_arg("chunk_size", &chunk_size) + .with_arg("chunk_end", &chunk_end)); + } + // Per specification, the values should always be provided, and must be 0 for blocks // prior to EIP-4844. // https://ethereum.github.io/execution-apis/api-documentation/ - if fee_history.base_fee_per_gas.len() != fee_history.base_fee_per_blob_gas.len() { - tracing::error!( - "base_fee_per_gas and base_fee_per_blob_gas have different lengths: {} and {}", - fee_history.base_fee_per_gas.len(), + if fee_history.base_fee_per_blob_gas.len() != chunk_size + 1 { + let message = format!( + "unexpected `base_fee_per_blob_gas.len()`, expected: {}, got {}", + chunk_size + 1, fee_history.base_fee_per_blob_gas.len() ); + return Err(EnrichedClientError::custom(message, "l1_fee_history") + .with_arg("chunk_size", &chunk_size) + .with_arg("chunk_end", &chunk_end)); } + // We take `chunk_size` entries for consistency with `l2_base_fee_history` which doesn't + // have correct data for block with number `upto_block + 1`. for (base, blob) in fee_history .base_fee_per_gas .into_iter() .zip(fee_history.base_fee_per_blob_gas) + .take(chunk_size) { let fees = BaseFees { base_fee_per_gas: cast_to_u64(base, "base_fee_per_gas")?, @@ -387,14 +415,14 @@ where COUNTERS.call[&(Method::L2FeeHistory, client.component())].inc(); let latency = LATENCIES.direct[&Method::BaseFeeHistory].start(); let mut history = Vec::with_capacity(block_count); - let from_block = upto_block.saturating_sub(block_count); + let from_block = upto_block.saturating_sub(block_count - 1); // Here we are requesting `fee_history` from blocks // `(from_block; upto_block)` in chunks of size `FEE_HISTORY_MAX_REQUEST_CHUNK` // starting from the oldest block. for chunk_start in (from_block..=upto_block).step_by(FEE_HISTORY_MAX_REQUEST_CHUNK) { let chunk_end = (chunk_start + FEE_HISTORY_MAX_REQUEST_CHUNK).min(upto_block); - let chunk_size = chunk_end - chunk_start; + let chunk_size = chunk_end - chunk_start + 1; let fee_history = client .fee_history(U64::from(chunk_size).into(), chunk_end.into(), vec![]) @@ -403,19 +431,46 @@ where .with_arg("block", &chunk_end) .await?; - // Check that the lengths are the same. - if fee_history.inner.base_fee_per_gas.len() != fee_history.l2_pubdata_price.len() { - tracing::error!( - "base_fee_per_gas and pubdata_price have different lengths: {} and {}", - fee_history.inner.base_fee_per_gas.len(), + if fee_history.inner.oldest_block != web3::BlockNumber::Number(chunk_start.into()) { + let oldest_block = match fee_history.inner.oldest_block { + web3::BlockNumber::Number(oldest_block) => oldest_block.to_string(), + _ => format!("{:?}", fee_history.inner.oldest_block), + }; + let message = + format!("unexpected `oldest_block`, expected: {chunk_start}, got {oldest_block}"); + return Err(EnrichedClientError::custom(message, "l2_fee_history") + .with_arg("chunk_size", &chunk_size) + .with_arg("chunk_end", &chunk_end)); + } + + if fee_history.inner.base_fee_per_gas.len() != chunk_size + 1 { + let message = format!( + "unexpected `base_fee_per_gas.len()`, expected: {}, got {}", + chunk_size + 1, + fee_history.inner.base_fee_per_gas.len() + ); + return Err(EnrichedClientError::custom(message, "l2_fee_history") + .with_arg("chunk_size", &chunk_size) + .with_arg("chunk_end", &chunk_end)); + } + + if fee_history.l2_pubdata_price.len() != chunk_size { + let message = format!( + "unexpected `l2_pubdata_price.len()`, expected: {}, got {}", + chunk_size + 1, fee_history.l2_pubdata_price.len() ); + return Err(EnrichedClientError::custom(message, "l2_fee_history") + .with_arg("chunk_size", &chunk_size) + .with_arg("chunk_end", &chunk_end)); } + // We take `chunk_size` entries because base fee for block `upto_block + 1` may change. for (base, l2_pubdata_price) in fee_history .inner .base_fee_per_gas .into_iter() + .take(chunk_size) .zip(fee_history.l2_pubdata_price) { let fees = BaseFees { diff --git a/core/lib/eth_client/src/clients/mock.rs b/core/lib/eth_client/src/clients/mock.rs index b33554b6292c..8e81b6c6f209 100644 --- a/core/lib/eth_client/src/clients/mock.rs +++ b/core/lib/eth_client/src/clients/mock.rs @@ -415,25 +415,35 @@ fn l2_eth_fee_history( let from_block = from_block.as_usize(); let start_block = from_block.saturating_sub(block_count.as_usize() - 1); + // duplicates last value to follow `feeHistory` response format, it should return `block_count + 1` values + let base_fee_per_gas = base_fee_history[start_block..=from_block] + .iter() + .chain([&base_fee_history[from_block]]) + .map(|fee| U256::from(fee.base_fee_per_gas)) + .collect(); + + // duplicates last value to follow `feeHistory` response format, it should return `block_count + 1` values + let base_fee_per_blob_gas = base_fee_history[start_block..=from_block] + .iter() + .chain([&base_fee_history[from_block]]) // duplicate last value + .map(|fee| fee.base_fee_per_blob_gas) + .collect(); + + let l2_pubdata_price = base_fee_history[start_block..=from_block] + .iter() + .map(|fee| fee.l2_pubdata_price) + .collect(); + FeeHistory { inner: web3::FeeHistory { oldest_block: start_block.into(), - base_fee_per_gas: base_fee_history[start_block..=from_block] - .iter() - .map(|fee| U256::from(fee.base_fee_per_gas)) - .collect(), - base_fee_per_blob_gas: base_fee_history[start_block..=from_block] - .iter() - .map(|fee| fee.base_fee_per_blob_gas) - .collect(), + base_fee_per_gas, + base_fee_per_blob_gas, gas_used_ratio: vec![], // not used blob_gas_used_ratio: vec![], // not used reward: None, }, - l2_pubdata_price: base_fee_history[start_block..=from_block] - .iter() - .map(|fee| fee.l2_pubdata_price) - .collect(), + l2_pubdata_price, } } diff --git a/core/lib/multivm/Cargo.toml b/core/lib/multivm/Cargo.toml index e49086a6b8b1..eb770bf9b57e 100644 --- a/core/lib/multivm/Cargo.toml +++ b/core/lib/multivm/Cargo.toml @@ -29,6 +29,7 @@ zksync_contracts.workspace = true zksync_utils.workspace = true zksync_system_constants.workspace = true zksync_vm_interface.workspace = true +zksync_mini_merkle_tree.workspace = true anyhow.workspace = true hex.workspace = true diff --git a/core/lib/multivm/src/lib.rs b/core/lib/multivm/src/lib.rs index 520274c14ae0..1cba2c0fb92b 100644 --- a/core/lib/multivm/src/lib.rs +++ b/core/lib/multivm/src/lib.rs @@ -20,6 +20,7 @@ pub use crate::{ }; mod glue; +pub mod pubdata_builders; pub mod tracers; pub mod utils; mod versions; diff --git a/core/lib/multivm/src/pubdata_builders/mod.rs b/core/lib/multivm/src/pubdata_builders/mod.rs new file mode 100644 index 000000000000..c52c4c70c86a --- /dev/null +++ b/core/lib/multivm/src/pubdata_builders/mod.rs @@ -0,0 +1,24 @@ +use std::rc::Rc; + +pub use rollup::RollupPubdataBuilder; +pub use validium::ValidiumPubdataBuilder; +use zksync_types::commitment::{L1BatchCommitmentMode, PubdataParams}; + +use crate::interface::pubdata::PubdataBuilder; + +mod rollup; +#[cfg(test)] +mod tests; +mod utils; +mod validium; + +pub fn pubdata_params_to_builder(params: PubdataParams) -> Rc { + match params.pubdata_type { + L1BatchCommitmentMode::Rollup => { + Rc::new(RollupPubdataBuilder::new(params.l2_da_validator_address)) + } + L1BatchCommitmentMode::Validium => { + Rc::new(ValidiumPubdataBuilder::new(params.l2_da_validator_address)) + } + } +} diff --git a/core/lib/multivm/src/pubdata_builders/rollup.rs b/core/lib/multivm/src/pubdata_builders/rollup.rs new file mode 100644 index 000000000000..4a818dfe2314 --- /dev/null +++ b/core/lib/multivm/src/pubdata_builders/rollup.rs @@ -0,0 +1,128 @@ +use zksync_types::{ + ethabi, + ethabi::{ParamType, Token}, + l2_to_l1_log::l2_to_l1_logs_tree_size, + writes::compress_state_diffs, + Address, ProtocolVersionId, +}; + +use super::utils::{ + build_chained_bytecode_hash, build_chained_log_hash, build_chained_message_hash, + build_logs_root, encode_user_logs, +}; +use crate::interface::pubdata::{PubdataBuilder, PubdataInput}; + +#[derive(Debug, Clone, Copy)] +pub struct RollupPubdataBuilder { + pub l2_da_validator: Address, +} + +impl RollupPubdataBuilder { + pub fn new(l2_da_validator: Address) -> Self { + Self { l2_da_validator } + } +} + +impl PubdataBuilder for RollupPubdataBuilder { + fn l2_da_validator(&self) -> Address { + self.l2_da_validator + } + + fn l1_messenger_operator_input( + &self, + input: &PubdataInput, + protocol_version: ProtocolVersionId, + ) -> Vec { + if protocol_version.is_pre_gateway() { + let mut operator_input = vec![]; + extend_from_pubdata_input(&mut operator_input, input); + + // Extend with uncompressed state diffs. + operator_input.extend((input.state_diffs.len() as u32).to_be_bytes()); + for state_diff in &input.state_diffs { + operator_input.extend(state_diff.encode_padded()); + } + + operator_input + } else { + let mut pubdata = vec![]; + extend_from_pubdata_input(&mut pubdata, input); + + // Extend with uncompressed state diffs. + pubdata.extend((input.state_diffs.len() as u32).to_be_bytes()); + for state_diff in &input.state_diffs { + pubdata.extend(state_diff.encode_padded()); + } + + let chained_log_hash = build_chained_log_hash(&input.user_logs); + let log_root_hash = + build_logs_root(&input.user_logs, l2_to_l1_logs_tree_size(protocol_version)); + let chained_msg_hash = build_chained_message_hash(&input.l2_to_l1_messages); + let chained_bytecodes_hash = build_chained_bytecode_hash(&input.published_bytecodes); + + let l2_da_header = vec![ + Token::FixedBytes(chained_log_hash), + Token::FixedBytes(log_root_hash), + Token::FixedBytes(chained_msg_hash), + Token::FixedBytes(chained_bytecodes_hash), + Token::Bytes(pubdata), + ]; + + // Selector of `IL2DAValidator::validatePubdata`. + let func_selector = ethabi::short_signature( + "validatePubdata", + &[ + ParamType::FixedBytes(32), + ParamType::FixedBytes(32), + ParamType::FixedBytes(32), + ParamType::FixedBytes(32), + ParamType::Bytes, + ], + ); + + [func_selector.to_vec(), ethabi::encode(&l2_da_header)].concat() + } + } + + fn settlement_layer_pubdata( + &self, + input: &PubdataInput, + _protocol_version: ProtocolVersionId, + ) -> Vec { + let mut pubdata = vec![]; + extend_from_pubdata_input(&mut pubdata, input); + + pubdata + } +} + +fn extend_from_pubdata_input(buffer: &mut Vec, pubdata_input: &PubdataInput) { + let PubdataInput { + user_logs, + l2_to_l1_messages, + published_bytecodes, + state_diffs, + } = pubdata_input; + + // Adding user L2->L1 logs. + buffer.extend(encode_user_logs(user_logs)); + + // Encoding L2->L1 messages + // Format: `[(numberOfMessages as u32) || (messages[1].len() as u32) || messages[1] || ... || (messages[n].len() as u32) || messages[n]]` + buffer.extend((l2_to_l1_messages.len() as u32).to_be_bytes()); + for message in l2_to_l1_messages { + buffer.extend((message.len() as u32).to_be_bytes()); + buffer.extend(message); + } + // Encoding bytecodes + // Format: `[(numberOfBytecodes as u32) || (bytecodes[1].len() as u32) || bytecodes[1] || ... || (bytecodes[n].len() as u32) || bytecodes[n]]` + buffer.extend((published_bytecodes.len() as u32).to_be_bytes()); + for bytecode in published_bytecodes { + buffer.extend((bytecode.len() as u32).to_be_bytes()); + buffer.extend(bytecode); + } + // Encoding state diffs + // Format: `[size of compressed state diffs u32 || compressed state diffs || (# state diffs: intial + repeated) as u32 || sorted state diffs by ]` + let state_diffs_compressed = compress_state_diffs(state_diffs.clone()); + buffer.extend(state_diffs_compressed); +} diff --git a/core/lib/multivm/src/pubdata_builders/tests.rs b/core/lib/multivm/src/pubdata_builders/tests.rs new file mode 100644 index 000000000000..bc24b8e47346 --- /dev/null +++ b/core/lib/multivm/src/pubdata_builders/tests.rs @@ -0,0 +1,123 @@ +use zksync_types::{ + writes::StateDiffRecord, Address, ProtocolVersionId, ACCOUNT_CODE_STORAGE_ADDRESS, + BOOTLOADER_ADDRESS, +}; +use zksync_utils::u256_to_h256; + +use super::{rollup::RollupPubdataBuilder, validium::ValidiumPubdataBuilder}; +use crate::interface::pubdata::{L1MessengerL2ToL1Log, PubdataBuilder, PubdataInput}; + +fn mock_input() -> PubdataInput { + // Just using some constant addresses for tests + let addr1 = BOOTLOADER_ADDRESS; + let addr2 = ACCOUNT_CODE_STORAGE_ADDRESS; + + let user_logs = vec![L1MessengerL2ToL1Log { + l2_shard_id: 0, + is_service: false, + tx_number_in_block: 0, + sender: addr1, + key: 1.into(), + value: 128.into(), + }]; + + let l2_to_l1_messages = vec![hex::decode("deadbeef").unwrap()]; + + let published_bytecodes = vec![hex::decode("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb").unwrap()]; + + // For covering more cases, we have two state diffs: + // One with enumeration index present (and so it is a repeated write) and the one without it. + let state_diffs = vec![ + StateDiffRecord { + address: addr2, + key: 155.into(), + derived_key: u256_to_h256(125.into()).0, + enumeration_index: 12, + initial_value: 11.into(), + final_value: 12.into(), + }, + StateDiffRecord { + address: addr2, + key: 156.into(), + derived_key: u256_to_h256(126.into()).0, + enumeration_index: 0, + initial_value: 0.into(), + final_value: 14.into(), + }, + ]; + + PubdataInput { + user_logs, + l2_to_l1_messages, + published_bytecodes, + state_diffs, + } +} + +#[test] +fn test_rollup_pubdata_building() { + let input = mock_input(); + + let rollup_pubdata_builder = RollupPubdataBuilder::new(Address::zero()); + + let actual = + rollup_pubdata_builder.l1_messenger_operator_input(&input, ProtocolVersionId::Version24); + let expected = "00000001000000000000000000000000000000000000000000008001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000800000000100000004deadbeef0000000100000060bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb0100002a040001000000000000000000000000000000000000000000000000000000000000007e090e0000000c0901000000020000000000000000000000000000000000008002000000000000000000000000000000000000000000000000000000000000009b000000000000000000000000000000000000000000000000000000000000007d000000000000000c000000000000000000000000000000000000000000000000000000000000000b000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008002000000000000000000000000000000000000000000000000000000000000009c000000000000000000000000000000000000000000000000000000000000007e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + assert_eq!( + &hex::encode(actual), + expected, + "mismatch for `l1_messenger_operator_input` (pre gateway)" + ); + + let actual = + rollup_pubdata_builder.settlement_layer_pubdata(&input, ProtocolVersionId::Version24); + let expected = "00000001000000000000000000000000000000000000000000008001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000800000000100000004deadbeef0000000100000060bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb0100002a040001000000000000000000000000000000000000000000000000000000000000007e090e0000000c0901"; + assert_eq!( + &hex::encode(actual), + expected, + "mismatch for `settlement_layer_pubdata` (pre gateway)" + ); + + let actual = + rollup_pubdata_builder.l1_messenger_operator_input(&input, ProtocolVersionId::Version27); + let expected = "89f9a07233e608561d90f7c4e7bcea24d718e425a6bd6c8eefb48a334366143694c75fae278944d856d68e33bbd32937cb3a1ea35cbf7d6eeeb1150f500dd0d64d0efe420d6dafe5897eab2fc27b2e47af303397ed285ace146d836d042717b0a3dc4b28a603a33b28ce1d5c52c593a46a15a99f1afa1c1d92715284288958fd54a93de700000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000032300000001000000000000000000000000000000000000000000008001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000800000000100000004deadbeef0000000100000060bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb0100002a040001000000000000000000000000000000000000000000000000000000000000007e090e0000000c0901000000020000000000000000000000000000000000008002000000000000000000000000000000000000000000000000000000000000009b000000000000000000000000000000000000000000000000000000000000007d000000000000000c000000000000000000000000000000000000000000000000000000000000000b000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008002000000000000000000000000000000000000000000000000000000000000009c000000000000000000000000000000000000000000000000000000000000007e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + assert_eq!( + &hex::encode(actual), + expected, + "mismatch for `l1_messenger_operator_input` (post gateway)" + ); + + let actual = + rollup_pubdata_builder.settlement_layer_pubdata(&input, ProtocolVersionId::Version27); + let expected = "00000001000000000000000000000000000000000000000000008001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000800000000100000004deadbeef0000000100000060bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb0100002a040001000000000000000000000000000000000000000000000000000000000000007e090e0000000c0901"; + assert_eq!( + &hex::encode(actual), + expected, + "mismatch for `settlement_layer_pubdata` (post gateway)" + ); +} + +#[test] +fn test_validium_pubdata_building() { + let input = mock_input(); + + let validium_pubdata_builder = ValidiumPubdataBuilder::new(Address::zero()); + + let actual = + validium_pubdata_builder.l1_messenger_operator_input(&input, ProtocolVersionId::Version27); + let expected = "89f9a07233e608561d90f7c4e7bcea24d718e425a6bd6c8eefb48a334366143694c75fae278944d856d68e33bbd32937cb3a1ea35cbf7d6eeeb1150f500dd0d64d0efe420d6dafe5897eab2fc27b2e47af303397ed285ace146d836d042717b0a3dc4b28a603a33b28ce1d5c52c593a46a15a99f1afa1c1d92715284288958fd54a93de700000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000005c000000010000000000000000000000000000000000000000000080010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000008000000000"; + assert_eq!( + &hex::encode(actual), + expected, + "mismatch for `l1_messenger_operator_input`" + ); + + let actual = + validium_pubdata_builder.settlement_layer_pubdata(&input, ProtocolVersionId::Version27); + let expected = "fa96e2436e6fb4d668f5a06681a7c53fcb199b2747ee624ee52a13e85aac5f1e"; + assert_eq!( + &hex::encode(actual), + expected, + "mismatch for `settlement_layer_pubdata`" + ); +} diff --git a/core/lib/multivm/src/pubdata_builders/utils.rs b/core/lib/multivm/src/pubdata_builders/utils.rs new file mode 100644 index 000000000000..57361a674fb7 --- /dev/null +++ b/core/lib/multivm/src/pubdata_builders/utils.rs @@ -0,0 +1,70 @@ +use zksync_mini_merkle_tree::MiniMerkleTree; +use zksync_types::web3::keccak256; +use zksync_utils::bytecode::hash_bytecode; + +use crate::interface::pubdata::L1MessengerL2ToL1Log; + +pub(crate) fn build_chained_log_hash(user_logs: &[L1MessengerL2ToL1Log]) -> Vec { + let mut chained_log_hash = vec![0u8; 32]; + + for log in user_logs { + let log_bytes = log.packed_encoding(); + let hash = keccak256(&log_bytes); + + chained_log_hash = keccak256(&[chained_log_hash, hash.to_vec()].concat()).to_vec(); + } + + chained_log_hash +} + +pub(crate) fn build_logs_root( + user_logs: &[L1MessengerL2ToL1Log], + l2_to_l1_logs_tree_size: usize, +) -> Vec { + let logs = user_logs.iter().map(|log| { + let encoded = log.packed_encoding(); + let mut slice = [0u8; 88]; + slice.copy_from_slice(&encoded); + slice + }); + MiniMerkleTree::new(logs, Some(l2_to_l1_logs_tree_size)) + .merkle_root() + .as_bytes() + .to_vec() +} + +pub(crate) fn build_chained_message_hash(l2_to_l1_messages: &[Vec]) -> Vec { + let mut chained_msg_hash = vec![0u8; 32]; + + for msg in l2_to_l1_messages { + let hash = keccak256(msg); + + chained_msg_hash = keccak256(&[chained_msg_hash, hash.to_vec()].concat()).to_vec(); + } + + chained_msg_hash +} + +pub(crate) fn build_chained_bytecode_hash(published_bytecodes: &[Vec]) -> Vec { + let mut chained_bytecode_hash = vec![0u8; 32]; + + for bytecode in published_bytecodes { + let hash = hash_bytecode(bytecode).to_fixed_bytes(); + + chained_bytecode_hash = + keccak256(&[chained_bytecode_hash, hash.to_vec()].concat()).to_vec(); + } + + chained_bytecode_hash +} + +pub(crate) fn encode_user_logs(user_logs: &[L1MessengerL2ToL1Log]) -> Vec { + // Encoding user L2->L1 logs. + // Format: `[(numberOfL2ToL1Logs as u32) || l2tol1logs[1] || ... || l2tol1logs[n]]` + let mut result = vec![]; + result.extend((user_logs.len() as u32).to_be_bytes()); + for l2tol1log in user_logs { + result.extend(l2tol1log.packed_encoding()); + } + result +} diff --git a/core/lib/multivm/src/pubdata_builders/validium.rs b/core/lib/multivm/src/pubdata_builders/validium.rs new file mode 100644 index 000000000000..a9156e970aad --- /dev/null +++ b/core/lib/multivm/src/pubdata_builders/validium.rs @@ -0,0 +1,93 @@ +use zksync_types::{ + ethabi, + ethabi::{ParamType, Token}, + l2_to_l1_log::l2_to_l1_logs_tree_size, + web3::keccak256, + Address, ProtocolVersionId, +}; + +use super::utils::{ + build_chained_bytecode_hash, build_chained_log_hash, build_chained_message_hash, + build_logs_root, encode_user_logs, +}; +use crate::interface::pubdata::{PubdataBuilder, PubdataInput}; + +#[derive(Debug, Clone, Copy)] +pub struct ValidiumPubdataBuilder { + pub l2_da_validator: Address, +} + +impl ValidiumPubdataBuilder { + pub fn new(l2_da_validator: Address) -> Self { + Self { l2_da_validator } + } +} + +impl PubdataBuilder for ValidiumPubdataBuilder { + fn l2_da_validator(&self) -> Address { + self.l2_da_validator + } + + fn l1_messenger_operator_input( + &self, + input: &PubdataInput, + protocol_version: ProtocolVersionId, + ) -> Vec { + assert!( + !protocol_version.is_pre_gateway(), + "ValidiumPubdataBuilder must not be called for pre gateway" + ); + + let mut pubdata = vec![]; + pubdata.extend(encode_user_logs(&input.user_logs)); + + let chained_log_hash = build_chained_log_hash(&input.user_logs); + let log_root_hash = + build_logs_root(&input.user_logs, l2_to_l1_logs_tree_size(protocol_version)); + let chained_msg_hash = build_chained_message_hash(&input.l2_to_l1_messages); + let chained_bytecodes_hash = build_chained_bytecode_hash(&input.published_bytecodes); + + let l2_da_header = vec![ + Token::FixedBytes(chained_log_hash), + Token::FixedBytes(log_root_hash), + Token::FixedBytes(chained_msg_hash), + Token::FixedBytes(chained_bytecodes_hash), + Token::Bytes(pubdata), + ]; + + // Selector of `IL2DAValidator::validatePubdata`. + let func_selector = ethabi::short_signature( + "validatePubdata", + &[ + ParamType::FixedBytes(32), + ParamType::FixedBytes(32), + ParamType::FixedBytes(32), + ParamType::FixedBytes(32), + ParamType::Bytes, + ], + ); + + [func_selector.to_vec(), ethabi::encode(&l2_da_header)] + .concat() + .to_vec() + } + + fn settlement_layer_pubdata( + &self, + input: &PubdataInput, + protocol_version: ProtocolVersionId, + ) -> Vec { + assert!( + !protocol_version.is_pre_gateway(), + "ValidiumPubdataBuilder must not be called for pre gateway" + ); + + let state_diffs_packed = input + .state_diffs + .iter() + .flat_map(|diff| diff.encode_padded()) + .collect::>(); + + keccak256(&state_diffs_packed).to_vec() + } +} diff --git a/core/lib/multivm/src/utils/events.rs b/core/lib/multivm/src/utils/events.rs index 9720cb779142..d84651989e75 100644 --- a/core/lib/multivm/src/utils/events.rs +++ b/core/lib/multivm/src/utils/events.rs @@ -1,59 +1,10 @@ use zksync_system_constants::L1_MESSENGER_ADDRESS; use zksync_types::{ ethabi::{self, Token}, - l2_to_l1_log::L2ToL1Log, - Address, H256, U256, + H256, U256, }; -use zksync_utils::{u256_to_bytes_be, u256_to_h256}; -use crate::interface::VmEvent; - -/// Corresponds to the following solidity event: -/// ```solidity -/// struct L2ToL1Log { -/// uint8 l2ShardId; -/// bool isService; -/// uint16 txNumberInBlock; -/// address sender; -/// bytes32 key; -/// bytes32 value; -/// } -/// ``` -#[derive(Debug, Default, Clone, PartialEq)] -pub(crate) struct L1MessengerL2ToL1Log { - pub l2_shard_id: u8, - pub is_service: bool, - pub tx_number_in_block: u16, - pub sender: Address, - pub key: U256, - pub value: U256, -} - -impl L1MessengerL2ToL1Log { - pub fn packed_encoding(&self) -> Vec { - let mut res: Vec = vec![]; - res.push(self.l2_shard_id); - res.push(self.is_service as u8); - res.extend_from_slice(&self.tx_number_in_block.to_be_bytes()); - res.extend_from_slice(self.sender.as_bytes()); - res.extend(u256_to_bytes_be(&self.key)); - res.extend(u256_to_bytes_be(&self.value)); - res - } -} - -impl From for L2ToL1Log { - fn from(log: L1MessengerL2ToL1Log) -> Self { - L2ToL1Log { - shard_id: log.l2_shard_id, - is_service: log.is_service, - tx_number_in_block: log.tx_number_in_block, - sender: log.sender, - key: u256_to_h256(log.key), - value: u256_to_h256(log.value), - } - } -} +use crate::interface::{pubdata::L1MessengerL2ToL1Log, VmEvent}; #[derive(Debug, PartialEq)] pub(crate) struct L1MessengerBytecodePublicationRequest { @@ -142,7 +93,8 @@ mod tests { use zksync_system_constants::{ BOOTLOADER_ADDRESS, KNOWN_CODES_STORAGE_ADDRESS, L2_BASE_TOKEN_ADDRESS, }; - use zksync_types::L1BatchNumber; + use zksync_types::{Address, L1BatchNumber}; + use zksync_utils::u256_to_h256; use super::*; diff --git a/core/lib/multivm/src/utils/mod.rs b/core/lib/multivm/src/utils/mod.rs index 5d8fba7a2acd..a55adb16c85a 100644 --- a/core/lib/multivm/src/utils/mod.rs +++ b/core/lib/multivm/src/utils/mod.rs @@ -53,7 +53,9 @@ pub fn derive_base_fee_and_gas_per_pubdata( VmVersion::Vm1_4_2 => crate::vm_1_4_2::utils::fee::derive_base_fee_and_gas_per_pubdata( batch_fee_input.into_pubdata_independent(), ), - VmVersion::Vm1_5_0SmallBootloaderMemory | VmVersion::Vm1_5_0IncreasedBootloaderMemory => { + VmVersion::Vm1_5_0SmallBootloaderMemory + | VmVersion::Vm1_5_0IncreasedBootloaderMemory + | VmVersion::VmGateway => { crate::vm_latest::utils::fee::derive_base_fee_and_gas_per_pubdata( batch_fee_input.into_pubdata_independent(), ) @@ -81,9 +83,9 @@ pub fn get_batch_base_fee(l1_batch_env: &L1BatchEnv, vm_version: VmVersion) -> u } VmVersion::Vm1_4_1 => crate::vm_1_4_1::utils::fee::get_batch_base_fee(l1_batch_env), VmVersion::Vm1_4_2 => crate::vm_1_4_2::utils::fee::get_batch_base_fee(l1_batch_env), - VmVersion::Vm1_5_0SmallBootloaderMemory | VmVersion::Vm1_5_0IncreasedBootloaderMemory => { - crate::vm_latest::utils::fee::get_batch_base_fee(l1_batch_env) - } + VmVersion::Vm1_5_0SmallBootloaderMemory + | VmVersion::Vm1_5_0IncreasedBootloaderMemory + | VmVersion::VmGateway => crate::vm_latest::utils::fee::get_batch_base_fee(l1_batch_env), } } @@ -209,9 +211,9 @@ pub fn derive_overhead( } VmVersion::Vm1_4_1 => crate::vm_1_4_1::utils::overhead::derive_overhead(encoded_len), VmVersion::Vm1_4_2 => crate::vm_1_4_2::utils::overhead::derive_overhead(encoded_len), - VmVersion::Vm1_5_0SmallBootloaderMemory | VmVersion::Vm1_5_0IncreasedBootloaderMemory => { - crate::vm_latest::utils::overhead::derive_overhead(encoded_len) - } + VmVersion::Vm1_5_0SmallBootloaderMemory + | VmVersion::Vm1_5_0IncreasedBootloaderMemory + | VmVersion::VmGateway => crate::vm_latest::utils::overhead::derive_overhead(encoded_len), } } @@ -245,6 +247,9 @@ pub fn get_bootloader_encoding_space(version: VmVersion) -> u32 { crate::vm_latest::MultiVMSubversion::IncreasedBootloaderMemory, ) } + VmVersion::VmGateway => crate::vm_latest::constants::get_bootloader_tx_encoding_space( + crate::vm_latest::MultiVMSubversion::Gateway, + ), } } @@ -264,9 +269,9 @@ pub fn get_bootloader_max_txs_in_batch(version: VmVersion) -> usize { VmVersion::VmBoojumIntegration => crate::vm_boojum_integration::constants::MAX_TXS_IN_BLOCK, VmVersion::Vm1_4_1 => crate::vm_1_4_1::constants::MAX_TXS_IN_BATCH, VmVersion::Vm1_4_2 => crate::vm_1_4_2::constants::MAX_TXS_IN_BATCH, - VmVersion::Vm1_5_0SmallBootloaderMemory | VmVersion::Vm1_5_0IncreasedBootloaderMemory => { - crate::vm_latest::constants::MAX_TXS_IN_BATCH - } + VmVersion::Vm1_5_0SmallBootloaderMemory + | VmVersion::Vm1_5_0IncreasedBootloaderMemory + | VmVersion::VmGateway => crate::vm_latest::constants::MAX_TXS_IN_BATCH, } } @@ -287,9 +292,9 @@ pub fn gas_bootloader_batch_tip_overhead(version: VmVersion) -> u32 { } VmVersion::Vm1_4_1 => crate::vm_1_4_1::constants::BOOTLOADER_BATCH_TIP_OVERHEAD, VmVersion::Vm1_4_2 => crate::vm_1_4_2::constants::BOOTLOADER_BATCH_TIP_OVERHEAD, - VmVersion::Vm1_5_0SmallBootloaderMemory | VmVersion::Vm1_5_0IncreasedBootloaderMemory => { - crate::vm_latest::constants::BOOTLOADER_BATCH_TIP_OVERHEAD - } + VmVersion::Vm1_5_0SmallBootloaderMemory + | VmVersion::Vm1_5_0IncreasedBootloaderMemory + | VmVersion::VmGateway => crate::vm_latest::constants::BOOTLOADER_BATCH_TIP_OVERHEAD, } } @@ -310,7 +315,9 @@ pub fn circuit_statistics_bootloader_batch_tip_overhead(version: VmVersion) -> u VmVersion::Vm1_4_2 => { crate::vm_1_4_2::constants::BOOTLOADER_BATCH_TIP_CIRCUIT_STATISTICS_OVERHEAD as usize } - VmVersion::Vm1_5_0SmallBootloaderMemory | VmVersion::Vm1_5_0IncreasedBootloaderMemory => { + VmVersion::Vm1_5_0SmallBootloaderMemory + | VmVersion::Vm1_5_0IncreasedBootloaderMemory + | VmVersion::VmGateway => { crate::vm_latest::constants::BOOTLOADER_BATCH_TIP_CIRCUIT_STATISTICS_OVERHEAD as usize } } @@ -333,7 +340,9 @@ pub fn execution_metrics_bootloader_batch_tip_overhead(version: VmVersion) -> us VmVersion::Vm1_4_2 => { crate::vm_1_4_2::constants::BOOTLOADER_BATCH_TIP_METRICS_SIZE_OVERHEAD as usize } - VmVersion::Vm1_5_0SmallBootloaderMemory | VmVersion::Vm1_5_0IncreasedBootloaderMemory => { + VmVersion::Vm1_5_0SmallBootloaderMemory + | VmVersion::Vm1_5_0IncreasedBootloaderMemory + | VmVersion::VmGateway => { crate::vm_latest::constants::BOOTLOADER_BATCH_TIP_METRICS_SIZE_OVERHEAD as usize } } @@ -357,9 +366,9 @@ pub fn get_max_gas_per_pubdata_byte(version: VmVersion) -> u64 { } VmVersion::Vm1_4_1 => crate::vm_1_4_1::constants::MAX_GAS_PER_PUBDATA_BYTE, VmVersion::Vm1_4_2 => crate::vm_1_4_2::constants::MAX_GAS_PER_PUBDATA_BYTE, - VmVersion::Vm1_5_0SmallBootloaderMemory | VmVersion::Vm1_5_0IncreasedBootloaderMemory => { - crate::vm_latest::constants::MAX_GAS_PER_PUBDATA_BYTE - } + VmVersion::Vm1_5_0SmallBootloaderMemory + | VmVersion::Vm1_5_0IncreasedBootloaderMemory + | VmVersion::VmGateway => crate::vm_latest::constants::MAX_GAS_PER_PUBDATA_BYTE, } } @@ -393,6 +402,9 @@ pub fn get_used_bootloader_memory_bytes(version: VmVersion) -> usize { crate::vm_latest::MultiVMSubversion::IncreasedBootloaderMemory, ) } + VmVersion::VmGateway => crate::vm_latest::constants::get_used_bootloader_memory_bytes( + crate::vm_latest::MultiVMSubversion::Gateway, + ), } } @@ -426,6 +438,9 @@ pub fn get_used_bootloader_memory_words(version: VmVersion) -> usize { crate::vm_latest::MultiVMSubversion::IncreasedBootloaderMemory, ) } + VmVersion::VmGateway => crate::vm_latest::constants::get_used_bootloader_memory_bytes( + crate::vm_latest::MultiVMSubversion::Gateway, + ), } } @@ -447,9 +462,9 @@ pub fn get_max_batch_gas_limit(version: VmVersion) -> u64 { } VmVersion::Vm1_4_1 => crate::vm_1_4_1::constants::BLOCK_GAS_LIMIT as u64, VmVersion::Vm1_4_2 => crate::vm_1_4_2::constants::BLOCK_GAS_LIMIT as u64, - VmVersion::Vm1_5_0SmallBootloaderMemory | VmVersion::Vm1_5_0IncreasedBootloaderMemory => { - crate::vm_latest::constants::BATCH_GAS_LIMIT - } + VmVersion::Vm1_5_0SmallBootloaderMemory + | VmVersion::Vm1_5_0IncreasedBootloaderMemory + | VmVersion::VmGateway => crate::vm_latest::constants::BATCH_GAS_LIMIT, } } @@ -473,9 +488,9 @@ pub fn get_eth_call_gas_limit(version: VmVersion) -> u64 { } VmVersion::Vm1_4_1 => crate::vm_1_4_1::constants::ETH_CALL_GAS_LIMIT as u64, VmVersion::Vm1_4_2 => crate::vm_1_4_2::constants::ETH_CALL_GAS_LIMIT as u64, - VmVersion::Vm1_5_0SmallBootloaderMemory | VmVersion::Vm1_5_0IncreasedBootloaderMemory => { - crate::vm_latest::constants::ETH_CALL_GAS_LIMIT - } + VmVersion::Vm1_5_0SmallBootloaderMemory + | VmVersion::Vm1_5_0IncreasedBootloaderMemory + | VmVersion::VmGateway => crate::vm_latest::constants::ETH_CALL_GAS_LIMIT, } } @@ -496,9 +511,9 @@ pub fn get_max_batch_base_layer_circuits(version: VmVersion) -> usize { // We avoid providing `0` for the old versions to avoid potential errors when working with old versions. crate::vm_1_4_2::constants::MAX_BASE_LAYER_CIRCUITS } - VmVersion::Vm1_5_0SmallBootloaderMemory | VmVersion::Vm1_5_0IncreasedBootloaderMemory => { - crate::vm_latest::constants::MAX_BASE_LAYER_CIRCUITS - } + VmVersion::Vm1_5_0SmallBootloaderMemory + | VmVersion::Vm1_5_0IncreasedBootloaderMemory + | VmVersion::VmGateway => crate::vm_latest::constants::MAX_BASE_LAYER_CIRCUITS, } } diff --git a/core/lib/multivm/src/versions/shadow/mod.rs b/core/lib/multivm/src/versions/shadow/mod.rs index fe9ce8eefcb9..42a0fbb1b8ba 100644 --- a/core/lib/multivm/src/versions/shadow/mod.rs +++ b/core/lib/multivm/src/versions/shadow/mod.rs @@ -198,7 +198,6 @@ impl Harness { assert!(!exec_result.result.is_failed(), "{:#?}", exec_result); self.new_block(vm, &[deploy_tx.tx.hash(), load_test_tx.hash()]); - vm.finish_batch(); } } diff --git a/core/lib/multivm/src/versions/shadow/tests.rs b/core/lib/multivm/src/versions/shadow/tests.rs index 64179f59be16..6a39a28f7630 100644 --- a/core/lib/multivm/src/versions/shadow/tests.rs +++ b/core/lib/multivm/src/versions/shadow/tests.rs @@ -1,14 +1,15 @@ //! Unit tests from the `testonly` test suite. -use std::collections::HashSet; +use std::{collections::HashSet, rc::Rc}; use zksync_types::{writes::StateDiffRecord, StorageKey, Transaction, H256, U256}; +use zksync_vm_interface::pubdata::PubdataBuilder; use super::ShadowedFastVm; use crate::{ interface::{ utils::{ShadowMut, ShadowRef}, - CurrentExecutionState, L2BlockEnv, VmExecutionMode, VmExecutionResultAndLogs, + CurrentExecutionState, L2BlockEnv, VmExecutionResultAndLogs, }, versions::testonly::TestedVm, }; @@ -41,14 +42,25 @@ impl TestedVm for ShadowedFastVm { }) } - fn execute_with_state_diffs( + fn finish_batch_with_state_diffs( &mut self, diffs: Vec, - mode: VmExecutionMode, + pubdata_builder: Rc, ) -> VmExecutionResultAndLogs { - self.get_custom_mut("execute_with_state_diffs", |r| match r { - ShadowMut::Main(vm) => vm.execute_with_state_diffs(diffs.clone(), mode), - ShadowMut::Shadow(vm) => vm.execute_with_state_diffs(diffs.clone(), mode), + self.get_custom_mut("finish_batch_with_state_diffs", |r| match r { + ShadowMut::Main(vm) => { + vm.finish_batch_with_state_diffs(diffs.clone(), pubdata_builder.clone()) + } + ShadowMut::Shadow(vm) => { + vm.finish_batch_with_state_diffs(diffs.clone(), pubdata_builder.clone()) + } + }) + } + + fn finish_batch_without_pubdata(&mut self) -> VmExecutionResultAndLogs { + self.get_custom_mut("finish_batch_without_pubdata", |r| match r { + ShadowMut::Main(vm) => vm.finish_batch_without_pubdata(), + ShadowMut::Shadow(vm) => vm.finish_batch_without_pubdata(), }) } diff --git a/core/lib/multivm/src/versions/testonly/block_tip.rs b/core/lib/multivm/src/versions/testonly/block_tip.rs index 7700f347ca6a..220653308a7e 100644 --- a/core/lib/multivm/src/versions/testonly/block_tip.rs +++ b/core/lib/multivm/src/versions/testonly/block_tip.rs @@ -11,11 +11,11 @@ use zksync_types::{ use zksync_utils::{bytecode::hash_bytecode, u256_to_h256}; use super::{ - get_complex_upgrade_abi, get_empty_storage, read_complex_upgrade, + default_pubdata_builder, get_complex_upgrade_abi, get_empty_storage, read_complex_upgrade, tester::{TestedVm, VmTesterBuilder}, }; use crate::{ - interface::{L1BatchEnv, TxExecutionMode, VmExecutionMode, VmInterfaceExt}, + interface::{InspectExecutionMode, L1BatchEnv, TxExecutionMode, VmInterfaceExt}, versions::testonly::default_l1_batch, vm_latest::constants::{ BOOTLOADER_BATCH_TIP_CIRCUIT_STATISTICS_OVERHEAD, @@ -156,7 +156,7 @@ fn execute_test(test_data: L1MessengerTestData) -> TestStatistics vm.vm.push_transaction(tx); - let result = vm.vm.execute(VmExecutionMode::OneTx); + let result = vm.vm.execute(InspectExecutionMode::OneTx); assert!( !result.result.is_failed(), "Transaction {i} wasn't successful for input: {:#?}", @@ -169,7 +169,7 @@ fn execute_test(test_data: L1MessengerTestData) -> TestStatistics let gas_before = vm.vm.gas_remaining(); let result = vm .vm - .execute_with_state_diffs(test_data.state_diffs.clone(), VmExecutionMode::Batch); + .finish_batch_with_state_diffs(test_data.state_diffs.clone(), default_pubdata_builder()); assert!( !result.result.is_failed(), "Batch wasn't successful for input: {test_data:?}" diff --git a/core/lib/multivm/src/versions/testonly/bootloader.rs b/core/lib/multivm/src/versions/testonly/bootloader.rs index e3177e078518..4b9b63252d6a 100644 --- a/core/lib/multivm/src/versions/testonly/bootloader.rs +++ b/core/lib/multivm/src/versions/testonly/bootloader.rs @@ -2,7 +2,7 @@ use assert_matches::assert_matches; use zksync_types::U256; use super::{get_bootloader, tester::VmTesterBuilder, TestedVm, BASE_SYSTEM_CONTRACTS}; -use crate::interface::{ExecutionResult, Halt, TxExecutionMode, VmExecutionMode, VmInterfaceExt}; +use crate::interface::{ExecutionResult, Halt, TxExecutionMode}; pub(crate) fn test_dummy_bootloader() { let mut base_system_contracts = BASE_SYSTEM_CONTRACTS.clone(); @@ -14,7 +14,7 @@ pub(crate) fn test_dummy_bootloader() { .with_execution_mode(TxExecutionMode::VerifyExecute) .build::(); - let result = vm.vm.execute(VmExecutionMode::Batch); + let result = vm.vm.finish_batch_without_pubdata(); assert!(!result.result.is_failed()); let correct_first_cell = U256::from_str_radix("123123123", 16).unwrap(); @@ -33,7 +33,7 @@ pub(crate) fn test_bootloader_out_of_gas() { .with_execution_mode(TxExecutionMode::VerifyExecute) .build::(); - let res = vm.vm.execute(VmExecutionMode::Batch); + let res = vm.vm.finish_batch_without_pubdata(); assert_matches!( res.result, diff --git a/core/lib/multivm/src/versions/testonly/bytecode_publishing.rs b/core/lib/multivm/src/versions/testonly/bytecode_publishing.rs index 346241a96245..9da005b995d3 100644 --- a/core/lib/multivm/src/versions/testonly/bytecode_publishing.rs +++ b/core/lib/multivm/src/versions/testonly/bytecode_publishing.rs @@ -1,8 +1,8 @@ use zksync_test_account::TxType; -use super::{read_test_contract, tester::VmTesterBuilder, TestedVm}; +use super::{default_pubdata_builder, read_test_contract, tester::VmTesterBuilder, TestedVm}; use crate::{ - interface::{TxExecutionMode, VmEvent, VmExecutionMode, VmInterfaceExt}, + interface::{InspectExecutionMode, TxExecutionMode, VmEvent, VmInterfaceExt}, utils::bytecode, }; @@ -30,10 +30,10 @@ pub(crate) fn test_bytecode_publishing() { compressed_bytecode ); - let result = vm.vm.execute(VmExecutionMode::OneTx); + let result = vm.vm.execute(InspectExecutionMode::OneTx); assert!(!result.result.is_failed(), "Transaction wasn't successful"); - vm.vm.execute(VmExecutionMode::Batch); + vm.vm.finish_batch(default_pubdata_builder()); let state = vm.vm.get_current_execution_state(); let long_messages = VmEvent::extract_long_l2_to_l1_messages(&state.events); diff --git a/core/lib/multivm/src/versions/testonly/circuits.rs b/core/lib/multivm/src/versions/testonly/circuits.rs index 9503efe9208f..de987a8912db 100644 --- a/core/lib/multivm/src/versions/testonly/circuits.rs +++ b/core/lib/multivm/src/versions/testonly/circuits.rs @@ -2,7 +2,7 @@ use zksync_types::{Address, Execute, U256}; use super::tester::VmTesterBuilder; use crate::{ - interface::{TxExecutionMode, VmExecutionMode, VmInterfaceExt}, + interface::{InspectExecutionMode, TxExecutionMode, VmInterfaceExt}, versions::testonly::TestedVm, vm_latest::constants::BATCH_COMPUTATIONAL_GAS_LIMIT, }; @@ -28,7 +28,7 @@ pub(crate) fn test_circuits() { None, ); vm.vm.push_transaction(tx); - let res = vm.vm.execute(VmExecutionMode::OneTx); + let res = vm.vm.execute(InspectExecutionMode::OneTx); assert!(!res.result.is_failed(), "{res:#?}"); let s = res.statistics.circuit_statistic; diff --git a/core/lib/multivm/src/versions/testonly/code_oracle.rs b/core/lib/multivm/src/versions/testonly/code_oracle.rs index b786539329b9..767a294f44ab 100644 --- a/core/lib/multivm/src/versions/testonly/code_oracle.rs +++ b/core/lib/multivm/src/versions/testonly/code_oracle.rs @@ -9,7 +9,7 @@ use super::{ tester::VmTesterBuilder, TestedVm, }; use crate::{ - interface::{TxExecutionMode, VmExecutionMode, VmInterfaceExt}, + interface::{InspectExecutionMode, TxExecutionMode, VmInterfaceExt}, versions::testonly::ContractToDeploy, }; @@ -68,7 +68,7 @@ pub(crate) fn test_code_oracle() { ); vm.vm.push_transaction(tx1); - let result = vm.vm.execute(VmExecutionMode::OneTx); + let result = vm.vm.execute(InspectExecutionMode::OneTx); assert!( !result.result.is_failed(), "Transaction wasn't successful: {result:#?}" @@ -91,7 +91,7 @@ pub(crate) fn test_code_oracle() { None, ); vm.vm.push_transaction(tx2); - let result = vm.vm.execute(VmExecutionMode::OneTx); + let result = vm.vm.execute(InspectExecutionMode::OneTx); assert!( !result.result.is_failed(), "Transaction wasn't successful: {result:#?}" @@ -160,7 +160,7 @@ pub(crate) fn test_code_oracle_big_bytecode() { ); vm.vm.push_transaction(tx1); - let result = vm.vm.execute(VmExecutionMode::OneTx); + let result = vm.vm.execute(InspectExecutionMode::OneTx); assert!( !result.result.is_failed(), "Transaction wasn't successful: {result:#?}" @@ -222,7 +222,7 @@ pub(crate) fn test_refunds_in_code_oracle() { ); vm.vm.push_transaction(tx); - let result = vm.vm.execute(VmExecutionMode::OneTx); + let result = vm.vm.execute(InspectExecutionMode::OneTx); assert!( !result.result.is_failed(), "Transaction wasn't successful: {result:#?}" diff --git a/core/lib/multivm/src/versions/testonly/default_aa.rs b/core/lib/multivm/src/versions/testonly/default_aa.rs index 3f121dcf7e6c..c69c00de4508 100644 --- a/core/lib/multivm/src/versions/testonly/default_aa.rs +++ b/core/lib/multivm/src/versions/testonly/default_aa.rs @@ -7,9 +7,9 @@ use zksync_types::{ }; use zksync_utils::h256_to_u256; -use super::{read_test_contract, tester::VmTesterBuilder, TestedVm}; +use super::{default_pubdata_builder, read_test_contract, tester::VmTesterBuilder, TestedVm}; use crate::{ - interface::{TxExecutionMode, VmExecutionMode, VmInterfaceExt}, + interface::{InspectExecutionMode, TxExecutionMode, VmInterfaceExt}, vm_latest::utils::fee::get_batch_base_fee, }; @@ -32,10 +32,10 @@ pub(crate) fn test_default_aa_interaction() { let maximal_fee = tx.gas_limit() * get_batch_base_fee(&vm.l1_batch_env); vm.vm.push_transaction(tx); - let result = vm.vm.execute(VmExecutionMode::OneTx); + let result = vm.vm.execute(InspectExecutionMode::OneTx); assert!(!result.result.is_failed(), "Transaction wasn't successful"); - vm.vm.execute(VmExecutionMode::Batch); + vm.vm.finish_batch(default_pubdata_builder()); vm.vm.get_current_execution_state(); diff --git a/core/lib/multivm/src/versions/testonly/get_used_contracts.rs b/core/lib/multivm/src/versions/testonly/get_used_contracts.rs index d3ffee20c344..9d0908807e21 100644 --- a/core/lib/multivm/src/versions/testonly/get_used_contracts.rs +++ b/core/lib/multivm/src/versions/testonly/get_used_contracts.rs @@ -15,7 +15,8 @@ use super::{ }; use crate::{ interface::{ - ExecutionResult, TxExecutionMode, VmExecutionMode, VmExecutionResultAndLogs, VmInterfaceExt, + ExecutionResult, InspectExecutionMode, TxExecutionMode, VmExecutionResultAndLogs, + VmInterfaceExt, }, versions::testonly::ContractToDeploy, }; @@ -35,7 +36,7 @@ pub(crate) fn test_get_used_contracts() { let account = &mut vm.rich_accounts[0]; let tx = account.get_deploy_tx(&contract_code, None, TxType::L1 { serial_id: 0 }); vm.vm.push_transaction(tx.tx.clone()); - let result = vm.vm.execute(VmExecutionMode::OneTx); + let result = vm.vm.execute(InspectExecutionMode::OneTx); assert!(!result.result.is_failed()); assert!(vm @@ -70,7 +71,7 @@ pub(crate) fn test_get_used_contracts() { vm.vm.push_transaction(tx2.clone()); - let res2 = vm.vm.execute(VmExecutionMode::OneTx); + let res2 = vm.vm.execute(InspectExecutionMode::OneTx); assert!(res2.result.is_failed()); diff --git a/core/lib/multivm/src/versions/testonly/is_write_initial.rs b/core/lib/multivm/src/versions/testonly/is_write_initial.rs index ef1fe2088c10..cac9be173639 100644 --- a/core/lib/multivm/src/versions/testonly/is_write_initial.rs +++ b/core/lib/multivm/src/versions/testonly/is_write_initial.rs @@ -2,7 +2,9 @@ use zksync_test_account::TxType; use zksync_types::get_nonce_key; use super::{read_test_contract, tester::VmTesterBuilder, TestedVm}; -use crate::interface::{storage::ReadStorage, TxExecutionMode, VmExecutionMode, VmInterfaceExt}; +use crate::interface::{ + storage::ReadStorage, InspectExecutionMode, TxExecutionMode, VmInterfaceExt, +}; pub(crate) fn test_is_write_initial_behaviour() { // In this test, we check result of `is_write_initial` at different stages. @@ -27,7 +29,7 @@ pub(crate) fn test_is_write_initial_behaviour() { let tx = account.get_deploy_tx(&contract_code, None, TxType::L2).tx; vm.vm.push_transaction(tx); - vm.vm.execute(VmExecutionMode::OneTx); + vm.vm.execute(InspectExecutionMode::OneTx); // Check that `is_write_initial` still returns true for the nonce key. assert!(vm diff --git a/core/lib/multivm/src/versions/testonly/l1_tx_execution.rs b/core/lib/multivm/src/versions/testonly/l1_tx_execution.rs index 212b1f16f207..e98a8385f020 100644 --- a/core/lib/multivm/src/versions/testonly/l1_tx_execution.rs +++ b/core/lib/multivm/src/versions/testonly/l1_tx_execution.rs @@ -11,7 +11,7 @@ use zksync_utils::{h256_to_u256, u256_to_h256}; use super::{read_test_contract, tester::VmTesterBuilder, TestedVm, BASE_SYSTEM_CONTRACTS}; use crate::{ - interface::{TxExecutionMode, VmExecutionMode, VmInterfaceExt}, + interface::{InspectExecutionMode, TxExecutionMode, VmInterfaceExt}, utils::StorageWritesDeduplicator, }; @@ -60,7 +60,7 @@ pub(crate) fn test_l1_tx_execution() { vm.vm.push_transaction(deploy_tx.tx.clone()); - let res = vm.vm.execute(VmExecutionMode::OneTx); + let res = vm.vm.execute(InspectExecutionMode::OneTx); // The code hash of the deployed contract should be marked as republished. let known_codes_key = get_known_code_key(&deploy_tx.bytecode_hash); @@ -84,7 +84,7 @@ pub(crate) fn test_l1_tx_execution() { TxType::L1 { serial_id: 0 }, ); vm.vm.push_transaction(tx); - let res = vm.vm.execute(VmExecutionMode::OneTx); + let res = vm.vm.execute(InspectExecutionMode::OneTx); let storage_logs = res.logs.storage_logs; let res = StorageWritesDeduplicator::apply_on_empty_state(&storage_logs); @@ -99,7 +99,7 @@ pub(crate) fn test_l1_tx_execution() { TxType::L1 { serial_id: 0 }, ); vm.vm.push_transaction(tx.clone()); - let res = vm.vm.execute(VmExecutionMode::OneTx); + let res = vm.vm.execute(InspectExecutionMode::OneTx); let storage_logs = res.logs.storage_logs; let res = StorageWritesDeduplicator::apply_on_empty_state(&storage_logs); // We changed one slot inside contract. @@ -110,7 +110,7 @@ pub(crate) fn test_l1_tx_execution() { assert_eq!(res.repeated_storage_writes, 0); vm.vm.push_transaction(tx); - let storage_logs = vm.vm.execute(VmExecutionMode::OneTx).logs.storage_logs; + let storage_logs = vm.vm.execute(InspectExecutionMode::OneTx).logs.storage_logs; let res = StorageWritesDeduplicator::apply_on_empty_state(&storage_logs); // We do the same storage write, it will be deduplicated, so still 4 initial write and 0 repeated. // But now the base pubdata spent has changed too. @@ -125,7 +125,7 @@ pub(crate) fn test_l1_tx_execution() { TxType::L1 { serial_id: 1 }, ); vm.vm.push_transaction(tx); - let result = vm.vm.execute(VmExecutionMode::OneTx); + let result = vm.vm.execute(InspectExecutionMode::OneTx); // Method is not payable tx should fail assert!(result.result.is_failed(), "The transaction should fail"); @@ -176,7 +176,7 @@ pub(crate) fn test_l1_tx_execution_high_gas_limit() { vm.vm.push_transaction(tx); - let res = vm.vm.execute(VmExecutionMode::OneTx); + let res = vm.vm.execute(InspectExecutionMode::OneTx); assert!(res.result.is_failed(), "The transaction should've failed"); } diff --git a/core/lib/multivm/src/versions/testonly/l2_blocks.rs b/core/lib/multivm/src/versions/testonly/l2_blocks.rs index 634a9b34bf6d..947d8b5859f8 100644 --- a/core/lib/multivm/src/versions/testonly/l2_blocks.rs +++ b/core/lib/multivm/src/versions/testonly/l2_blocks.rs @@ -17,8 +17,8 @@ use zksync_utils::{h256_to_u256, u256_to_h256}; use super::{default_l1_batch, get_empty_storage, tester::VmTesterBuilder, TestedVm}; use crate::{ interface::{ - storage::StorageView, ExecutionResult, Halt, L2BlockEnv, TxExecutionMode, VmExecutionMode, - VmInterfaceExt, + storage::StorageView, ExecutionResult, Halt, InspectExecutionMode, L2BlockEnv, + TxExecutionMode, VmInterfaceExt, }, vm_latest::{ constants::{TX_OPERATOR_L2_BLOCK_INFO_OFFSET, TX_OPERATOR_SLOTS_PER_L2_BLOCK_INFO}, @@ -66,7 +66,7 @@ pub(crate) fn test_l2_block_initialization_timestamp() { let l1_tx = get_l1_noop(); vm.vm.push_transaction(l1_tx); - let res = vm.vm.execute(VmExecutionMode::OneTx); + let res = vm.vm.execute(InspectExecutionMode::OneTx); assert_matches!( res.result, @@ -100,7 +100,7 @@ pub(crate) fn test_l2_block_initialization_number_non_zero() { set_manual_l2_block_info(&mut vm.vm, 0, first_l2_block); - let res = vm.vm.execute(VmExecutionMode::OneTx); + let res = vm.vm.execute(InspectExecutionMode::OneTx); assert_eq!( res.result, @@ -128,7 +128,7 @@ fn test_same_l2_block( let l1_tx = get_l1_noop(); vm.vm.push_transaction(l1_tx.clone()); - let res = vm.vm.execute(VmExecutionMode::OneTx); + let res = vm.vm.execute(InspectExecutionMode::OneTx); assert!(!res.result.is_failed()); let mut current_l2_block = vm.l1_batch_env.first_l2_block; @@ -147,7 +147,7 @@ fn test_same_l2_block( vm.vm.push_transaction(l1_tx); set_manual_l2_block_info(&mut vm.vm, 1, current_l2_block); - let result = vm.vm.execute(VmExecutionMode::OneTx); + let result = vm.vm.execute(InspectExecutionMode::OneTx); if let Some(err) = expected_error { assert_eq!(result.result, ExecutionResult::Halt { reason: err }); @@ -203,7 +203,7 @@ fn test_new_l2_block( // Firstly we execute the first transaction vm.vm.push_transaction(l1_tx.clone()); - vm.vm.execute(VmExecutionMode::OneTx); + vm.vm.execute(InspectExecutionMode::OneTx); let mut second_l2_block = vm.l1_batch_env.first_l2_block; second_l2_block.number += 1; @@ -223,7 +223,7 @@ fn test_new_l2_block( vm.vm.push_l2_block_unchecked(second_l2_block); vm.vm.push_transaction(l1_tx); - let result = vm.vm.execute(VmExecutionMode::OneTx); + let result = vm.vm.execute(InspectExecutionMode::OneTx); if let Some(err) = expected_error { assert_eq!(result.result, ExecutionResult::Halt { reason: err }); } else { @@ -350,7 +350,7 @@ fn test_first_in_batch( vm.vm.push_transaction(l1_tx); set_manual_l2_block_info(&mut vm.vm, 0, proposed_block); - let result = vm.vm.execute(VmExecutionMode::OneTx); + let result = vm.vm.execute(InspectExecutionMode::OneTx); if let Some(err) = expected_error { assert_eq!(result.result, ExecutionResult::Halt { reason: err }); } else { diff --git a/core/lib/multivm/src/versions/testonly/mod.rs b/core/lib/multivm/src/versions/testonly/mod.rs index 74cda6a95229..eece1d475bba 100644 --- a/core/lib/multivm/src/versions/testonly/mod.rs +++ b/core/lib/multivm/src/versions/testonly/mod.rs @@ -9,7 +9,7 @@ //! - Tests use [`VmTester`] built using [`VmTesterBuilder`] to create a VM instance. This allows to set up storage for the VM, //! custom [`SystemEnv`] / [`L1BatchEnv`], deployed contracts, pre-funded accounts etc. -use std::collections::HashSet; +use std::{collections::HashSet, rc::Rc}; use ethabi::Contract; use once_cell::sync::Lazy; @@ -23,11 +23,14 @@ use zksync_types::{ ProtocolVersionId, U256, }; use zksync_utils::{bytecode::hash_bytecode, bytes_to_be_words, h256_to_u256, u256_to_h256}; -use zksync_vm_interface::{L1BatchEnv, L2BlockEnv, SystemEnv, TxExecutionMode}; +use zksync_vm_interface::{ + pubdata::PubdataBuilder, L1BatchEnv, L2BlockEnv, SystemEnv, TxExecutionMode, +}; pub(super) use self::tester::{TestedVm, VmTester, VmTesterBuilder}; use crate::{ - interface::storage::InMemoryStorage, vm_latest::constants::BATCH_COMPUTATIONAL_GAS_LIMIT, + interface::storage::InMemoryStorage, pubdata_builders::RollupPubdataBuilder, + vm_latest::constants::BATCH_COMPUTATIONAL_GAS_LIMIT, }; pub(super) mod block_tip; @@ -175,6 +178,10 @@ pub(super) fn default_l1_batch(number: L1BatchNumber) -> L1BatchEnv { } } +pub(super) fn default_pubdata_builder() -> Rc { + Rc::new(RollupPubdataBuilder::new(Address::zero())) +} + pub(super) fn make_address_rich(storage: &mut InMemoryStorage, address: Address) { let key = storage_key_for_eth_balance(&address); storage.set_value(key, u256_to_h256(U256::from(10_u64.pow(19)))); diff --git a/core/lib/multivm/src/versions/testonly/nonce_holder.rs b/core/lib/multivm/src/versions/testonly/nonce_holder.rs index 8ef120c693ca..36f736c0bbe5 100644 --- a/core/lib/multivm/src/versions/testonly/nonce_holder.rs +++ b/core/lib/multivm/src/versions/testonly/nonce_holder.rs @@ -3,7 +3,7 @@ use zksync_types::{Execute, ExecuteTransactionCommon, Nonce}; use super::{read_nonce_holder_tester, tester::VmTesterBuilder, ContractToDeploy, TestedVm}; use crate::interface::{ - ExecutionResult, Halt, TxExecutionMode, TxRevertReason, VmExecutionMode, VmInterfaceExt, + ExecutionResult, Halt, InspectExecutionMode, TxExecutionMode, TxRevertReason, VmInterfaceExt, VmRevertReason, }; @@ -53,7 +53,7 @@ fn run_nonce_test( }; tx_data.signature = vec![test_mode.into()]; vm.push_transaction(transaction); - let result = vm.execute(VmExecutionMode::OneTx); + let result = vm.execute(InspectExecutionMode::OneTx); if let Some(msg) = error_message { let expected_error = diff --git a/core/lib/multivm/src/versions/testonly/precompiles.rs b/core/lib/multivm/src/versions/testonly/precompiles.rs index 270afab07317..2e26dc134b07 100644 --- a/core/lib/multivm/src/versions/testonly/precompiles.rs +++ b/core/lib/multivm/src/versions/testonly/precompiles.rs @@ -3,7 +3,7 @@ use zksync_types::{Address, Execute}; use super::{read_precompiles_contract, tester::VmTesterBuilder, TestedVm}; use crate::{ - interface::{TxExecutionMode, VmExecutionMode, VmInterfaceExt}, + interface::{InspectExecutionMode, TxExecutionMode, VmInterfaceExt}, versions::testonly::ContractToDeploy, vm_latest::constants::BATCH_COMPUTATIONAL_GAS_LIMIT, }; @@ -36,7 +36,7 @@ pub(crate) fn test_keccak() { ); vm.vm.push_transaction(tx); - let exec_result = vm.vm.execute(VmExecutionMode::OneTx); + let exec_result = vm.vm.execute(InspectExecutionMode::OneTx); assert!(!exec_result.result.is_failed(), "{exec_result:#?}"); let keccak_count = exec_result.statistics.circuit_statistic.keccak256 @@ -72,7 +72,7 @@ pub(crate) fn test_sha256() { ); vm.vm.push_transaction(tx); - let exec_result = vm.vm.execute(VmExecutionMode::OneTx); + let exec_result = vm.vm.execute(InspectExecutionMode::OneTx); assert!(!exec_result.result.is_failed(), "{exec_result:#?}"); let sha_count = exec_result.statistics.circuit_statistic.sha256 @@ -101,7 +101,7 @@ pub(crate) fn test_ecrecover() { ); vm.vm.push_transaction(tx); - let exec_result = vm.vm.execute(VmExecutionMode::OneTx); + let exec_result = vm.vm.execute(InspectExecutionMode::OneTx); assert!(!exec_result.result.is_failed(), "{exec_result:#?}"); let ecrecover_count = exec_result.statistics.circuit_statistic.ecrecover diff --git a/core/lib/multivm/src/versions/testonly/refunds.rs b/core/lib/multivm/src/versions/testonly/refunds.rs index 565607dff105..874425fc435c 100644 --- a/core/lib/multivm/src/versions/testonly/refunds.rs +++ b/core/lib/multivm/src/versions/testonly/refunds.rs @@ -3,10 +3,10 @@ use zksync_test_account::TxType; use zksync_types::{Address, Execute, U256}; use super::{ - read_expensive_contract, read_test_contract, tester::VmTesterBuilder, ContractToDeploy, - TestedVm, + default_pubdata_builder, read_expensive_contract, read_test_contract, tester::VmTesterBuilder, + ContractToDeploy, TestedVm, }; -use crate::interface::{TxExecutionMode, VmExecutionMode, VmInterfaceExt}; +use crate::interface::{InspectExecutionMode, TxExecutionMode, VmInterfaceExt}; pub(crate) fn test_predetermined_refunded_gas() { // In this test, we compare the execution of the bootloader with the predefined @@ -24,7 +24,7 @@ pub(crate) fn test_predetermined_refunded_gas() { let tx = account.get_deploy_tx(&counter, None, TxType::L2).tx; vm.vm.push_transaction(tx.clone()); - let result = vm.vm.execute(VmExecutionMode::OneTx); + let result = vm.vm.execute(InspectExecutionMode::OneTx); assert!(!result.result.is_failed()); @@ -37,7 +37,10 @@ pub(crate) fn test_predetermined_refunded_gas() { ); assert!(result.refunds.gas_refunded > 0, "The final refund is 0"); - let result_without_predefined_refunds = vm.vm.execute(VmExecutionMode::Batch); + let result_without_predefined_refunds = vm + .vm + .finish_batch(default_pubdata_builder()) + .block_tip_execution_result; let mut current_state_without_predefined_refunds = vm.vm.get_current_execution_state(); assert!(!result_without_predefined_refunds.result.is_failed(),); @@ -56,7 +59,10 @@ pub(crate) fn test_predetermined_refunded_gas() { vm.vm .push_transaction_with_refund(tx.clone(), result.refunds.gas_refunded); - let result_with_predefined_refunds = vm.vm.execute(VmExecutionMode::Batch); + let result_with_predefined_refunds = vm + .vm + .finish_batch(default_pubdata_builder()) + .block_tip_execution_result; let mut current_state_with_predefined_refunds = vm.vm.get_current_execution_state(); assert!(!result_with_predefined_refunds.result.is_failed()); @@ -107,7 +113,10 @@ pub(crate) fn test_predetermined_refunded_gas() { let changed_operator_suggested_refund = result.refunds.gas_refunded + 1000; vm.vm .push_transaction_with_refund(tx, changed_operator_suggested_refund); - let result = vm.vm.execute(VmExecutionMode::Batch); + let result = vm + .vm + .finish_batch(default_pubdata_builder()) + .block_tip_execution_result; let mut current_state_with_changed_predefined_refunds = vm.vm.get_current_execution_state(); assert!(!result.result.is_failed()); @@ -185,7 +194,7 @@ pub(crate) fn test_negative_pubdata_for_transaction() { None, ); vm.vm.push_transaction(expensive_tx); - let result = vm.vm.execute(VmExecutionMode::OneTx); + let result = vm.vm.execute(InspectExecutionMode::OneTx); assert!( !result.result.is_failed(), "Transaction wasn't successful: {result:#?}" @@ -202,7 +211,7 @@ pub(crate) fn test_negative_pubdata_for_transaction() { None, ); vm.vm.push_transaction(clean_up_tx); - let result = vm.vm.execute(VmExecutionMode::OneTx); + let result = vm.vm.execute(InspectExecutionMode::OneTx); assert!( !result.result.is_failed(), "Transaction wasn't successful: {result:#?}" diff --git a/core/lib/multivm/src/versions/testonly/require_eip712.rs b/core/lib/multivm/src/versions/testonly/require_eip712.rs index 1ea3964d7cd1..e789fbda2902 100644 --- a/core/lib/multivm/src/versions/testonly/require_eip712.rs +++ b/core/lib/multivm/src/versions/testonly/require_eip712.rs @@ -8,7 +8,7 @@ use zksync_types::{ use super::{ read_many_owners_custom_account_contract, tester::VmTesterBuilder, ContractToDeploy, TestedVm, }; -use crate::interface::{TxExecutionMode, VmExecutionMode, VmInterfaceExt}; +use crate::interface::{InspectExecutionMode, TxExecutionMode, VmInterfaceExt}; /// This test deploys 'buggy' account abstraction code, and then tries accessing it both with legacy /// and EIP712 transactions. @@ -52,7 +52,7 @@ pub(crate) fn test_require_eip712() { ); vm.vm.push_transaction(tx); - let result = vm.vm.execute(VmExecutionMode::OneTx); + let result = vm.vm.execute(InspectExecutionMode::OneTx); assert!(!result.result.is_failed()); let private_account_balance = vm.get_eth_balance(private_account.address); @@ -85,7 +85,7 @@ pub(crate) fn test_require_eip712() { let transaction: Transaction = l2_tx.into(); vm.vm.push_transaction(transaction); - let result = vm.vm.execute(VmExecutionMode::OneTx); + let result = vm.vm.execute(InspectExecutionMode::OneTx); assert!(!result.result.is_failed()); assert_eq!( @@ -133,7 +133,7 @@ pub(crate) fn test_require_eip712() { let transaction: Transaction = l2_tx.into(); vm.vm.push_transaction(transaction); - vm.vm.execute(VmExecutionMode::OneTx); + vm.vm.execute(InspectExecutionMode::OneTx); assert_eq!( vm.get_eth_balance(beneficiary_address), diff --git a/core/lib/multivm/src/versions/testonly/secp256r1.rs b/core/lib/multivm/src/versions/testonly/secp256r1.rs index 60197913601e..37d428f82101 100644 --- a/core/lib/multivm/src/versions/testonly/secp256r1.rs +++ b/core/lib/multivm/src/versions/testonly/secp256r1.rs @@ -4,7 +4,7 @@ use zksync_types::{web3::keccak256, Execute, H256, U256}; use zksync_utils::h256_to_u256; use super::{tester::VmTesterBuilder, TestedVm}; -use crate::interface::{ExecutionResult, TxExecutionMode, VmExecutionMode, VmInterfaceExt}; +use crate::interface::{ExecutionResult, InspectExecutionMode, TxExecutionMode, VmInterfaceExt}; pub(crate) fn test_secp256r1() { // In this test, we aim to test whether a simple account interaction (without any fee logic) @@ -55,7 +55,7 @@ pub(crate) fn test_secp256r1() { vm.vm.push_transaction(tx); - let execution_result = vm.vm.execute(VmExecutionMode::Batch); + let execution_result = vm.vm.execute(InspectExecutionMode::OneTx); let ExecutionResult::Success { output } = execution_result.result else { panic!("batch failed") diff --git a/core/lib/multivm/src/versions/testonly/simple_execution.rs b/core/lib/multivm/src/versions/testonly/simple_execution.rs index fcd7a144ab1f..96239fb362d2 100644 --- a/core/lib/multivm/src/versions/testonly/simple_execution.rs +++ b/core/lib/multivm/src/versions/testonly/simple_execution.rs @@ -1,8 +1,8 @@ use assert_matches::assert_matches; use zksync_test_account::TxType; -use super::{tester::VmTesterBuilder, TestedVm}; -use crate::interface::{ExecutionResult, VmExecutionMode, VmInterfaceExt}; +use super::{default_pubdata_builder, tester::VmTesterBuilder, TestedVm}; +use crate::interface::{ExecutionResult, InspectExecutionMode, VmInterfaceExt}; pub(crate) fn test_estimate_fee() { let mut vm_tester = VmTesterBuilder::new() @@ -23,7 +23,7 @@ pub(crate) fn test_estimate_fee() { vm_tester.vm.push_transaction(tx); - let result = vm_tester.vm.execute(VmExecutionMode::OneTx); + let result = vm_tester.vm.execute(InspectExecutionMode::OneTx); assert_matches!(result.result, ExecutionResult::Success { .. }); } @@ -64,12 +64,14 @@ pub(crate) fn test_simple_execute() { vm.push_transaction(tx1); vm.push_transaction(tx2); vm.push_transaction(tx3); - let tx = vm.execute(VmExecutionMode::OneTx); + let tx = vm.execute(InspectExecutionMode::OneTx); assert_matches!(tx.result, ExecutionResult::Success { .. }); - let tx = vm.execute(VmExecutionMode::OneTx); + let tx = vm.execute(InspectExecutionMode::OneTx); assert_matches!(tx.result, ExecutionResult::Revert { .. }); - let tx = vm.execute(VmExecutionMode::OneTx); + let tx = vm.execute(InspectExecutionMode::OneTx); assert_matches!(tx.result, ExecutionResult::Success { .. }); - let block_tip = vm.execute(VmExecutionMode::Batch); + let block_tip = vm + .finish_batch(default_pubdata_builder()) + .block_tip_execution_result; assert_matches!(block_tip.result, ExecutionResult::Success { .. }); } diff --git a/core/lib/multivm/src/versions/testonly/storage.rs b/core/lib/multivm/src/versions/testonly/storage.rs index 4951272a60c4..efe7be1edbd1 100644 --- a/core/lib/multivm/src/versions/testonly/storage.rs +++ b/core/lib/multivm/src/versions/testonly/storage.rs @@ -3,7 +3,7 @@ use zksync_contracts::{load_contract, read_bytecode}; use zksync_types::{Address, Execute, U256}; use super::{tester::VmTesterBuilder, ContractToDeploy, TestedVm}; -use crate::interface::{TxExecutionMode, VmExecutionMode, VmInterfaceExt}; +use crate::interface::{InspectExecutionMode, TxExecutionMode, VmInterfaceExt}; fn test_storage(first_tx_calldata: Vec, second_tx_calldata: Vec) -> u32 { let bytecode = read_bytecode( @@ -45,20 +45,20 @@ fn test_storage(first_tx_calldata: Vec, second_tx_calldata: Ve vm.vm.make_snapshot(); vm.vm.push_transaction(tx1); - let result = vm.vm.execute(VmExecutionMode::OneTx); + let result = vm.vm.execute(InspectExecutionMode::OneTx); assert!(!result.result.is_failed(), "First tx failed"); vm.vm.pop_snapshot_no_rollback(); // We rollback once because transient storage and rollbacks are a tricky combination. vm.vm.make_snapshot(); vm.vm.push_transaction(tx2.clone()); - let result = vm.vm.execute(VmExecutionMode::OneTx); + let result = vm.vm.execute(InspectExecutionMode::OneTx); assert!(!result.result.is_failed(), "Second tx failed"); vm.vm.rollback_to_the_latest_snapshot(); vm.vm.make_snapshot(); vm.vm.push_transaction(tx2); - let result = vm.vm.execute(VmExecutionMode::OneTx); + let result = vm.vm.execute(InspectExecutionMode::OneTx); assert!(!result.result.is_failed(), "Second tx failed on second run"); result.statistics.pubdata_published diff --git a/core/lib/multivm/src/versions/testonly/tester/mod.rs b/core/lib/multivm/src/versions/testonly/tester/mod.rs index 7432322e0c8d..716b9386235f 100644 --- a/core/lib/multivm/src/versions/testonly/tester/mod.rs +++ b/core/lib/multivm/src/versions/testonly/tester/mod.rs @@ -1,4 +1,4 @@ -use std::{collections::HashSet, fmt}; +use std::{collections::HashSet, fmt, rc::Rc}; use zksync_contracts::BaseSystemContracts; use zksync_test_account::{Account, TxType}; @@ -8,7 +8,8 @@ use zksync_types::{ Address, L1BatchNumber, StorageKey, Transaction, H256, U256, }; use zksync_vm_interface::{ - CurrentExecutionState, VmExecutionResultAndLogs, VmInterfaceHistoryEnabled, + pubdata::PubdataBuilder, CurrentExecutionState, InspectExecutionMode, VmExecutionResultAndLogs, + VmInterfaceHistoryEnabled, }; pub(crate) use self::transaction_test_info::{ExpectedError, TransactionTestInfo, TxModifier}; @@ -16,8 +17,7 @@ use super::{get_empty_storage, read_test_contract}; use crate::{ interface::{ storage::{InMemoryStorage, StoragePtr, StorageView}, - L1BatchEnv, L2BlockEnv, SystemEnv, TxExecutionMode, VmExecutionMode, VmFactory, - VmInterfaceExt, + L1BatchEnv, L2BlockEnv, SystemEnv, TxExecutionMode, VmFactory, VmInterfaceExt, }, versions::testonly::{ default_l1_batch, default_system_env, make_address_rich, ContractToDeploy, @@ -44,7 +44,7 @@ impl VmTester { let tx = account.get_deploy_tx(&contract, None, TxType::L2).tx; let nonce = tx.nonce().unwrap().0.into(); self.vm.push_transaction(tx); - self.vm.execute(VmExecutionMode::OneTx); + self.vm.execute(InspectExecutionMode::OneTx); let deployed_address = deployed_address_create(account.address, nonce); self.test_contract = Some(deployed_address); } @@ -187,12 +187,14 @@ pub(crate) trait TestedVm: /// Unlike [`Self::known_bytecode_hashes()`], the output should only include successfully decommitted bytecodes. fn decommitted_hashes(&self) -> HashSet; - fn execute_with_state_diffs( + fn finish_batch_with_state_diffs( &mut self, diffs: Vec, - mode: VmExecutionMode, + pubdata_builder: Rc, ) -> VmExecutionResultAndLogs; + fn finish_batch_without_pubdata(&mut self) -> VmExecutionResultAndLogs; + fn insert_bytecodes(&mut self, bytecodes: &[&[u8]]); /// Includes bytecodes that have failed to decommit. Should exclude base system contract bytecodes (default AA / EVM emulator). diff --git a/core/lib/multivm/src/versions/testonly/tester/transaction_test_info.rs b/core/lib/multivm/src/versions/testonly/tester/transaction_test_info.rs index 87468d3e4d5f..b9373e331c30 100644 --- a/core/lib/multivm/src/versions/testonly/tester/transaction_test_info.rs +++ b/core/lib/multivm/src/versions/testonly/tester/transaction_test_info.rs @@ -1,9 +1,12 @@ use zksync_types::{ExecuteTransactionCommon, Nonce, Transaction, H160}; use super::{TestedVm, VmTester}; -use crate::interface::{ - CurrentExecutionState, ExecutionResult, Halt, TxRevertReason, VmExecutionMode, - VmExecutionResultAndLogs, VmInterfaceExt, VmRevertReason, +use crate::{ + interface::{ + CurrentExecutionState, ExecutionResult, Halt, InspectExecutionMode, TxRevertReason, + VmExecutionResultAndLogs, VmInterfaceExt, VmRevertReason, + }, + versions::testonly::default_pubdata_builder, }; #[derive(Debug, Clone)] @@ -181,7 +184,7 @@ impl VmTester { for tx_test_info in txs { self.execute_tx_and_verify(tx_test_info.clone()); } - self.vm.execute(VmExecutionMode::Batch); + self.vm.finish_batch(default_pubdata_builder()); let mut state = self.vm.get_current_execution_state(); state.used_contract_hashes.sort(); state @@ -202,7 +205,7 @@ fn execute_tx_and_verify( let inner_state_before = vm.dump_state(); vm.make_snapshot(); vm.push_transaction(tx_test_info.tx.clone()); - let result = vm.execute(VmExecutionMode::OneTx); + let result = vm.execute(InspectExecutionMode::OneTx); tx_test_info.verify_result(&result); if tx_test_info.should_rollback() { vm.rollback_to_the_latest_snapshot(); diff --git a/core/lib/multivm/src/versions/testonly/transfer.rs b/core/lib/multivm/src/versions/testonly/transfer.rs index 051826a64f24..3572adba147c 100644 --- a/core/lib/multivm/src/versions/testonly/transfer.rs +++ b/core/lib/multivm/src/versions/testonly/transfer.rs @@ -3,8 +3,10 @@ use zksync_contracts::{load_contract, read_bytecode}; use zksync_types::{utils::storage_key_for_eth_balance, Address, Execute, U256}; use zksync_utils::u256_to_h256; -use super::{get_empty_storage, tester::VmTesterBuilder, ContractToDeploy, TestedVm}; -use crate::interface::{TxExecutionMode, VmExecutionMode, VmInterfaceExt}; +use super::{ + default_pubdata_builder, get_empty_storage, tester::VmTesterBuilder, ContractToDeploy, TestedVm, +}; +use crate::interface::{InspectExecutionMode, TxExecutionMode, VmInterfaceExt}; enum TestOptions { Send(U256), @@ -72,13 +74,16 @@ fn test_send_or_transfer(test_option: TestOptions) { ); vm.vm.push_transaction(tx); - let tx_result = vm.vm.execute(VmExecutionMode::OneTx); + let tx_result = vm.vm.execute(InspectExecutionMode::OneTx); assert!( !tx_result.result.is_failed(), "Transaction wasn't successful" ); - let batch_result = vm.vm.execute(VmExecutionMode::Batch); + let batch_result = vm + .vm + .finish_batch(default_pubdata_builder()) + .block_tip_execution_result; assert!(!batch_result.result.is_failed(), "Batch wasn't successful"); let new_recipient_balance = vm.get_eth_balance(recipient_address); @@ -161,7 +166,7 @@ fn test_reentrancy_protection_send_or_transfer(test_option: TestOp ); vm.vm.push_transaction(tx1); - let tx1_result = vm.vm.execute(VmExecutionMode::OneTx); + let tx1_result = vm.vm.execute(InspectExecutionMode::OneTx); assert!( !tx1_result.result.is_failed(), "Transaction 1 wasn't successful" @@ -178,13 +183,16 @@ fn test_reentrancy_protection_send_or_transfer(test_option: TestOp ); vm.vm.push_transaction(tx2); - let tx2_result = vm.vm.execute(VmExecutionMode::OneTx); + let tx2_result = vm.vm.execute(InspectExecutionMode::OneTx); assert!( tx2_result.result.is_failed(), "Transaction 2 should have failed, but it succeeded" ); - let batch_result = vm.vm.execute(VmExecutionMode::Batch); + let batch_result = vm + .vm + .finish_batch(default_pubdata_builder()) + .block_tip_execution_result; assert!(!batch_result.result.is_failed(), "Batch wasn't successful"); } diff --git a/core/lib/multivm/src/versions/testonly/upgrade.rs b/core/lib/multivm/src/versions/testonly/upgrade.rs index 9401cbb4ba84..359f19faedb2 100644 --- a/core/lib/multivm/src/versions/testonly/upgrade.rs +++ b/core/lib/multivm/src/versions/testonly/upgrade.rs @@ -14,7 +14,9 @@ use super::{ get_complex_upgrade_abi, get_empty_storage, read_complex_upgrade, read_test_contract, tester::VmTesterBuilder, TestedVm, }; -use crate::interface::{ExecutionResult, Halt, TxExecutionMode, VmExecutionMode, VmInterfaceExt}; +use crate::interface::{ + ExecutionResult, Halt, InspectExecutionMode, TxExecutionMode, VmInterfaceExt, +}; /// In this test we ensure that the requirements for protocol upgrade transactions are enforced by the bootloader: /// - This transaction must be the only one in block @@ -71,9 +73,9 @@ pub(crate) fn test_protocol_upgrade_is_first() { vm.vm.push_transaction(normal_l1_transaction.clone()); vm.vm.push_transaction(another_protocol_upgrade_transaction); - vm.vm.execute(VmExecutionMode::OneTx); - vm.vm.execute(VmExecutionMode::OneTx); - let result = vm.vm.execute(VmExecutionMode::OneTx); + vm.vm.execute(InspectExecutionMode::OneTx); + vm.vm.execute(InspectExecutionMode::OneTx); + let result = vm.vm.execute(InspectExecutionMode::OneTx); assert_eq!( result.result, ExecutionResult::Halt { @@ -87,8 +89,8 @@ pub(crate) fn test_protocol_upgrade_is_first() { vm.vm.push_transaction(normal_l1_transaction.clone()); vm.vm.push_transaction(protocol_upgrade_transaction.clone()); - vm.vm.execute(VmExecutionMode::OneTx); - let result = vm.vm.execute(VmExecutionMode::OneTx); + vm.vm.execute(InspectExecutionMode::OneTx); + let result = vm.vm.execute(InspectExecutionMode::OneTx); assert_eq!( result.result, ExecutionResult::Halt { @@ -101,8 +103,8 @@ pub(crate) fn test_protocol_upgrade_is_first() { vm.vm.push_transaction(protocol_upgrade_transaction); vm.vm.push_transaction(normal_l1_transaction); - vm.vm.execute(VmExecutionMode::OneTx); - let result = vm.vm.execute(VmExecutionMode::OneTx); + vm.vm.execute(InspectExecutionMode::OneTx); + let result = vm.vm.execute(InspectExecutionMode::OneTx); assert!(!result.result.is_failed()); } @@ -137,7 +139,7 @@ pub(crate) fn test_force_deploy_upgrade() { vm.vm.push_transaction(transaction); - let result = vm.vm.execute(VmExecutionMode::OneTx); + let result = vm.vm.execute(InspectExecutionMode::OneTx); assert!( !result.result.is_failed(), "The force upgrade was not successful" @@ -186,7 +188,7 @@ pub(crate) fn test_complex_upgrader() { ); vm.vm.push_transaction(transaction); - let result = vm.vm.execute(VmExecutionMode::OneTx); + let result = vm.vm.execute(InspectExecutionMode::OneTx); assert!( !result.result.is_failed(), "The force upgrade was not successful" diff --git a/core/lib/multivm/src/versions/vm_1_3_2/vm.rs b/core/lib/multivm/src/versions/vm_1_3_2/vm.rs index 31457fc9676a..d9768652c2f3 100644 --- a/core/lib/multivm/src/versions/vm_1_3_2/vm.rs +++ b/core/lib/multivm/src/versions/vm_1_3_2/vm.rs @@ -1,16 +1,16 @@ -use std::collections::HashSet; +use std::{collections::HashSet, rc::Rc}; use zksync_types::Transaction; use zksync_utils::{bytecode::hash_bytecode, h256_to_u256}; +use zksync_vm_interface::{pubdata::PubdataBuilder, InspectExecutionMode}; use crate::{ glue::{history_mode::HistoryMode, GlueInto}, interface::{ storage::{StoragePtr, WriteStorage}, BytecodeCompressionError, BytecodeCompressionResult, FinishedL1Batch, L1BatchEnv, - L2BlockEnv, PushTransactionResult, SystemEnv, TxExecutionMode, VmExecutionMode, - VmExecutionResultAndLogs, VmFactory, VmInterface, VmInterfaceHistoryEnabled, - VmMemoryMetrics, + L2BlockEnv, PushTransactionResult, SystemEnv, TxExecutionMode, VmExecutionResultAndLogs, + VmFactory, VmInterface, VmInterfaceHistoryEnabled, VmMemoryMetrics, }, tracers::old::TracerDispatcher, utils::bytecode, @@ -61,7 +61,7 @@ impl VmInterface for Vm { fn inspect( &mut self, tracer: &mut Self::TracerDispatcher, - execution_mode: VmExecutionMode, + execution_mode: InspectExecutionMode, ) -> VmExecutionResultAndLogs { if let Some(storage_invocations) = tracer.storage_invocations { self.vm @@ -70,7 +70,7 @@ impl VmInterface for Vm { } match execution_mode { - VmExecutionMode::OneTx => { + InspectExecutionMode::OneTx => { match self.system_env.execution_mode { TxExecutionMode::VerifyExecute => { let enable_call_tracer = tracer @@ -93,8 +93,7 @@ impl VmInterface for Vm { .glue_into(), } } - VmExecutionMode::Batch => self.finish_batch().block_tip_execution_result, - VmExecutionMode::Bootloader => self.vm.execute_block_tip().glue_into(), + InspectExecutionMode::Bootloader => self.vm.execute_block_tip().glue_into(), } } @@ -184,7 +183,7 @@ impl VmInterface for Vm { } } - fn finish_batch(&mut self) -> FinishedL1Batch { + fn finish_batch(&mut self, _pubdata_builder: Rc) -> FinishedL1Batch { self.vm .execute_till_block_end( crate::vm_1_3_2::vm_with_bootloader::BootloaderJobType::BlockPostprocessing, diff --git a/core/lib/multivm/src/versions/vm_1_4_1/tracers/pubdata_tracer.rs b/core/lib/multivm/src/versions/vm_1_4_1/tracers/pubdata_tracer.rs index 238804bc7fca..6f927c5c99a8 100644 --- a/core/lib/multivm/src/versions/vm_1_4_1/tracers/pubdata_tracer.rs +++ b/core/lib/multivm/src/versions/vm_1_4_1/tracers/pubdata_tracer.rs @@ -10,6 +10,7 @@ use zksync_utils::{h256_to_u256, u256_to_bytes_be, u256_to_h256}; use crate::{ interface::{ + pubdata::L1MessengerL2ToL1Log, storage::{StoragePtr, WriteStorage}, tracer::{TracerExecutionStatus, TracerExecutionStopReason}, L1BatchEnv, VmEvent, VmExecutionMode, @@ -17,7 +18,7 @@ use crate::{ tracers::dynamic::vm_1_4_1::DynTracer, utils::events::{ extract_bytecode_publication_requests_from_l1_messenger, - extract_l2tol1logs_from_l1_messenger, L1MessengerL2ToL1Log, + extract_l2tol1logs_from_l1_messenger, }, vm_1_4_1::{ bootloader_state::{utils::apply_pubdata_to_memory, BootloaderState}, diff --git a/core/lib/multivm/src/versions/vm_1_4_1/types/internals/pubdata.rs b/core/lib/multivm/src/versions/vm_1_4_1/types/internals/pubdata.rs index d07732ae4350..c1ca93152a03 100644 --- a/core/lib/multivm/src/versions/vm_1_4_1/types/internals/pubdata.rs +++ b/core/lib/multivm/src/versions/vm_1_4_1/types/internals/pubdata.rs @@ -1,6 +1,6 @@ use zksync_types::writes::{compress_state_diffs, StateDiffRecord}; -use crate::utils::events::L1MessengerL2ToL1Log; +use crate::interface::pubdata::L1MessengerL2ToL1Log; /// Struct based on which the pubdata blob is formed #[derive(Debug, Clone, Default)] diff --git a/core/lib/multivm/src/versions/vm_1_4_1/vm.rs b/core/lib/multivm/src/versions/vm_1_4_1/vm.rs index 1c38958bb318..af483feedd7e 100644 --- a/core/lib/multivm/src/versions/vm_1_4_1/vm.rs +++ b/core/lib/multivm/src/versions/vm_1_4_1/vm.rs @@ -1,8 +1,11 @@ +use std::rc::Rc; + use circuit_sequencer_api_1_4_1::sort_storage_access::sort_storage_access_queries; use zksync_types::{ l2_to_l1_log::{SystemL2ToL1Log, UserL2ToL1Log}, Transaction, }; +use zksync_vm_interface::{pubdata::PubdataBuilder, InspectExecutionMode}; use crate::{ glue::GlueInto, @@ -95,9 +98,9 @@ impl VmInterface for Vm { fn inspect( &mut self, tracer: &mut Self::TracerDispatcher, - execution_mode: VmExecutionMode, + execution_mode: InspectExecutionMode, ) -> VmExecutionResultAndLogs { - self.inspect_inner(tracer, execution_mode, None) + self.inspect_inner(tracer, execution_mode.into(), None) } fn start_new_l2_block(&mut self, l2_block_env: L2BlockEnv) { @@ -128,8 +131,12 @@ impl VmInterface for Vm { } } - fn finish_batch(&mut self) -> FinishedL1Batch { - let result = self.inspect(&mut TracerDispatcher::default(), VmExecutionMode::Batch); + fn finish_batch(&mut self, _pubdata_builder: Rc) -> FinishedL1Batch { + let result = self.inspect_inner( + &mut TracerDispatcher::default(), + VmExecutionMode::Batch, + None, + ); let execution_state = self.get_current_execution_state(); let bootloader_memory = self.bootloader_state.bootloader_memory(); FinishedL1Batch { diff --git a/core/lib/multivm/src/versions/vm_1_4_2/tracers/pubdata_tracer.rs b/core/lib/multivm/src/versions/vm_1_4_2/tracers/pubdata_tracer.rs index ffe65b5e050b..6c4f737f9e94 100644 --- a/core/lib/multivm/src/versions/vm_1_4_2/tracers/pubdata_tracer.rs +++ b/core/lib/multivm/src/versions/vm_1_4_2/tracers/pubdata_tracer.rs @@ -10,6 +10,7 @@ use zksync_utils::{h256_to_u256, u256_to_bytes_be, u256_to_h256}; use crate::{ interface::{ + pubdata::L1MessengerL2ToL1Log, storage::{StoragePtr, WriteStorage}, tracer::{TracerExecutionStatus, TracerExecutionStopReason}, L1BatchEnv, VmEvent, VmExecutionMode, @@ -17,7 +18,7 @@ use crate::{ tracers::dynamic::vm_1_4_1::DynTracer, utils::events::{ extract_bytecode_publication_requests_from_l1_messenger, - extract_l2tol1logs_from_l1_messenger, L1MessengerL2ToL1Log, + extract_l2tol1logs_from_l1_messenger, }, vm_1_4_2::{ bootloader_state::{utils::apply_pubdata_to_memory, BootloaderState}, diff --git a/core/lib/multivm/src/versions/vm_1_4_2/types/internals/pubdata.rs b/core/lib/multivm/src/versions/vm_1_4_2/types/internals/pubdata.rs index d07732ae4350..c1ca93152a03 100644 --- a/core/lib/multivm/src/versions/vm_1_4_2/types/internals/pubdata.rs +++ b/core/lib/multivm/src/versions/vm_1_4_2/types/internals/pubdata.rs @@ -1,6 +1,6 @@ use zksync_types::writes::{compress_state_diffs, StateDiffRecord}; -use crate::utils::events::L1MessengerL2ToL1Log; +use crate::interface::pubdata::L1MessengerL2ToL1Log; /// Struct based on which the pubdata blob is formed #[derive(Debug, Clone, Default)] diff --git a/core/lib/multivm/src/versions/vm_1_4_2/vm.rs b/core/lib/multivm/src/versions/vm_1_4_2/vm.rs index ca69a191e26f..e7c8e7acdd95 100644 --- a/core/lib/multivm/src/versions/vm_1_4_2/vm.rs +++ b/core/lib/multivm/src/versions/vm_1_4_2/vm.rs @@ -1,10 +1,11 @@ -use std::mem; +use std::{mem, rc::Rc}; use circuit_sequencer_api_1_4_2::sort_storage_access::sort_storage_access_queries; use zksync_types::{ l2_to_l1_log::{SystemL2ToL1Log, UserL2ToL1Log}, Transaction, }; +use zksync_vm_interface::{pubdata::PubdataBuilder, InspectExecutionMode}; use crate::{ glue::GlueInto, @@ -97,9 +98,9 @@ impl VmInterface for Vm { fn inspect( &mut self, tracer: &mut Self::TracerDispatcher, - execution_mode: VmExecutionMode, + execution_mode: InspectExecutionMode, ) -> VmExecutionResultAndLogs { - self.inspect_inner(mem::take(tracer), execution_mode, None) + self.inspect_inner(mem::take(tracer), execution_mode.into(), None) } fn start_new_l2_block(&mut self, l2_block_env: L2BlockEnv) { @@ -130,8 +131,8 @@ impl VmInterface for Vm { } } - fn finish_batch(&mut self) -> FinishedL1Batch { - let result = self.inspect(&mut TracerDispatcher::default(), VmExecutionMode::Batch); + fn finish_batch(&mut self, _pubdata_builder: Rc) -> FinishedL1Batch { + let result = self.inspect_inner(TracerDispatcher::default(), VmExecutionMode::Batch, None); let execution_state = self.get_current_execution_state(); let bootloader_memory = self.bootloader_state.bootloader_memory(); FinishedL1Batch { diff --git a/core/lib/multivm/src/versions/vm_boojum_integration/tracers/pubdata_tracer.rs b/core/lib/multivm/src/versions/vm_boojum_integration/tracers/pubdata_tracer.rs index 326a57896124..2f7d141cb0a7 100644 --- a/core/lib/multivm/src/versions/vm_boojum_integration/tracers/pubdata_tracer.rs +++ b/core/lib/multivm/src/versions/vm_boojum_integration/tracers/pubdata_tracer.rs @@ -10,6 +10,7 @@ use zksync_utils::{h256_to_u256, u256_to_bytes_be, u256_to_h256}; use crate::{ interface::{ + pubdata::L1MessengerL2ToL1Log, storage::{StoragePtr, WriteStorage}, tracer::{TracerExecutionStatus, TracerExecutionStopReason}, L1BatchEnv, VmEvent, VmExecutionMode, @@ -17,7 +18,7 @@ use crate::{ tracers::dynamic::vm_1_4_0::DynTracer, utils::events::{ extract_bytecode_publication_requests_from_l1_messenger, - extract_l2tol1logs_from_l1_messenger, L1MessengerL2ToL1Log, + extract_l2tol1logs_from_l1_messenger, }, vm_boojum_integration::{ bootloader_state::{utils::apply_pubdata_to_memory, BootloaderState}, diff --git a/core/lib/multivm/src/versions/vm_boojum_integration/types/internals/pubdata.rs b/core/lib/multivm/src/versions/vm_boojum_integration/types/internals/pubdata.rs index 9df9009831f4..152ccad2fbcb 100644 --- a/core/lib/multivm/src/versions/vm_boojum_integration/types/internals/pubdata.rs +++ b/core/lib/multivm/src/versions/vm_boojum_integration/types/internals/pubdata.rs @@ -1,6 +1,6 @@ use zksync_types::writes::{compress_state_diffs, StateDiffRecord}; -use crate::utils::events::L1MessengerL2ToL1Log; +use crate::interface::pubdata::L1MessengerL2ToL1Log; /// Struct based on which the pubdata blob is formed #[derive(Debug, Clone, Default)] diff --git a/core/lib/multivm/src/versions/vm_boojum_integration/vm.rs b/core/lib/multivm/src/versions/vm_boojum_integration/vm.rs index bfd055a5cc84..43c9900486db 100644 --- a/core/lib/multivm/src/versions/vm_boojum_integration/vm.rs +++ b/core/lib/multivm/src/versions/vm_boojum_integration/vm.rs @@ -1,8 +1,11 @@ +use std::rc::Rc; + use circuit_sequencer_api_1_4_0::sort_storage_access::sort_storage_access_queries; use zksync_types::{ l2_to_l1_log::{SystemL2ToL1Log, UserL2ToL1Log}, Transaction, }; +use zksync_vm_interface::{pubdata::PubdataBuilder, InspectExecutionMode}; use crate::{ glue::GlueInto, @@ -95,9 +98,9 @@ impl VmInterface for Vm { fn inspect( &mut self, tracer: &mut Self::TracerDispatcher, - execution_mode: VmExecutionMode, + execution_mode: InspectExecutionMode, ) -> VmExecutionResultAndLogs { - self.inspect_inner(tracer, execution_mode) + self.inspect_inner(tracer, execution_mode.into()) } fn start_new_l2_block(&mut self, l2_block_env: L2BlockEnv) { @@ -129,8 +132,8 @@ impl VmInterface for Vm { } } - fn finish_batch(&mut self) -> FinishedL1Batch { - let result = self.inspect(&mut TracerDispatcher::default(), VmExecutionMode::Batch); + fn finish_batch(&mut self, _pubdata_builder: Rc) -> FinishedL1Batch { + let result = self.inspect_inner(&mut TracerDispatcher::default(), VmExecutionMode::Batch); let execution_state = self.get_current_execution_state(); let bootloader_memory = self.bootloader_state.bootloader_memory(); FinishedL1Batch { diff --git a/core/lib/multivm/src/versions/vm_fast/pubdata.rs b/core/lib/multivm/src/versions/vm_fast/pubdata.rs index d07732ae4350..c1ca93152a03 100644 --- a/core/lib/multivm/src/versions/vm_fast/pubdata.rs +++ b/core/lib/multivm/src/versions/vm_fast/pubdata.rs @@ -1,6 +1,6 @@ use zksync_types::writes::{compress_state_diffs, StateDiffRecord}; -use crate::utils::events::L1MessengerL2ToL1Log; +use crate::interface::pubdata::L1MessengerL2ToL1Log; /// Struct based on which the pubdata blob is formed #[derive(Debug, Clone, Default)] diff --git a/core/lib/multivm/src/versions/vm_fast/tests/mod.rs b/core/lib/multivm/src/versions/vm_fast/tests/mod.rs index f385ca2a438f..2b4665f82241 100644 --- a/core/lib/multivm/src/versions/vm_fast/tests/mod.rs +++ b/core/lib/multivm/src/versions/vm_fast/tests/mod.rs @@ -1,11 +1,11 @@ -use std::{any::Any, collections::HashSet, fmt}; +use std::{any::Any, collections::HashSet, fmt, rc::Rc}; use zksync_types::{writes::StateDiffRecord, StorageKey, Transaction, H160, H256, U256}; use zksync_utils::h256_to_u256; use zksync_vm2::interface::{Event, HeapId, StateInterface}; use zksync_vm_interface::{ - storage::ReadStorage, CurrentExecutionState, L2BlockEnv, VmExecutionMode, - VmExecutionResultAndLogs, VmInterfaceExt, + pubdata::PubdataBuilder, storage::ReadStorage, CurrentExecutionState, L2BlockEnv, + VmExecutionMode, VmExecutionResultAndLogs, VmInterface, }; use super::Vm; @@ -99,13 +99,18 @@ impl TestedVm for Vm> { self.decommitted_hashes().collect() } - fn execute_with_state_diffs( + fn finish_batch_with_state_diffs( &mut self, diffs: Vec, - mode: VmExecutionMode, + pubdata_builder: Rc, ) -> VmExecutionResultAndLogs { self.enforce_state_diffs(diffs); - self.execute(mode) + self.finish_batch(pubdata_builder) + .block_tip_execution_result + } + + fn finish_batch_without_pubdata(&mut self) -> VmExecutionResultAndLogs { + self.inspect_inner(&mut Default::default(), VmExecutionMode::Batch) } fn insert_bytecodes(&mut self, bytecodes: &[&[u8]]) { diff --git a/core/lib/multivm/src/versions/vm_fast/vm.rs b/core/lib/multivm/src/versions/vm_fast/vm.rs index 88e0b10b5eaf..a2114a339481 100644 --- a/core/lib/multivm/src/versions/vm_fast/vm.rs +++ b/core/lib/multivm/src/versions/vm_fast/vm.rs @@ -1,4 +1,4 @@ -use std::{collections::HashMap, fmt, mem}; +use std::{collections::HashMap, fmt, mem, rc::Rc}; use zk_evm_1_5_0::{ aux_structures::LogQuery, zkevm_opcode_defs::system_params::INITIAL_FRAME_FORMAL_EH_LOCATION, @@ -21,6 +21,7 @@ use zksync_vm2::{ interface::{CallframeInterface, HeapId, StateInterface, Tracer}, ExecutionEnd, FatPointer, Program, Settings, StorageSlot, VirtualMachine, }; +use zksync_vm_interface::{pubdata::PubdataBuilder, InspectExecutionMode}; use super::{ bootloader_state::{BootloaderState, BootloaderStateSnapshot}, @@ -103,7 +104,7 @@ pub struct Vm { enforced_state_diffs: Option>, } -impl Vm { +impl Vm { pub fn custom(batch_env: L1BatchEnv, system_env: SystemEnv, storage: S) -> Self { assert!( is_supported_by_fast_vm(system_env.version), @@ -533,39 +534,10 @@ impl Vm { pubdata_costs: world_diff.pubdata_costs().to_vec(), } } -} -impl VmFactory> for Vm, Tr> -where - S: ReadStorage, - Tr: Tracer + Default + 'static, -{ - fn new( - batch_env: L1BatchEnv, - system_env: SystemEnv, - storage: StoragePtr>, - ) -> Self { - let storage = ImmutableStorageView::new(storage); - Self::custom(batch_env, system_env, storage) - } -} - -impl VmInterface for Vm { - type TracerDispatcher = Tr; - - fn push_transaction(&mut self, tx: Transaction) -> PushTransactionResult<'_> { - self.push_transaction_inner(tx, 0, true); - PushTransactionResult { - compressed_bytecodes: self - .bootloader_state - .get_last_tx_compressed_bytecodes() - .into(), - } - } - - fn inspect( + pub(crate) fn inspect_inner( &mut self, - tracer: &mut Self::TracerDispatcher, + tracer: &mut Tr, execution_mode: VmExecutionMode, ) -> VmExecutionResultAndLogs { let mut track_refunds = false; @@ -655,6 +627,43 @@ impl VmInterface for Vm { new_known_factory_deps: None, } } +} + +impl VmFactory> for Vm, Tr> +where + S: ReadStorage, + Tr: Tracer + Default + 'static, +{ + fn new( + batch_env: L1BatchEnv, + system_env: SystemEnv, + storage: StoragePtr>, + ) -> Self { + let storage = ImmutableStorageView::new(storage); + Self::custom(batch_env, system_env, storage) + } +} + +impl VmInterface for Vm { + type TracerDispatcher = Tr; + + fn push_transaction(&mut self, tx: Transaction) -> PushTransactionResult<'_> { + self.push_transaction_inner(tx, 0, true); + PushTransactionResult { + compressed_bytecodes: self + .bootloader_state + .get_last_tx_compressed_bytecodes() + .into(), + } + } + + fn inspect( + &mut self, + tracer: &mut Self::TracerDispatcher, + execution_mode: InspectExecutionMode, + ) -> VmExecutionResultAndLogs { + self.inspect_inner(tracer, execution_mode.into()) + } fn inspect_transaction_with_bytecode_compression( &mut self, @@ -663,7 +672,7 @@ impl VmInterface for Vm { with_compression: bool, ) -> (BytecodeCompressionResult<'_>, VmExecutionResultAndLogs) { self.push_transaction_inner(tx, 0, with_compression); - let result = self.inspect(tracer, VmExecutionMode::OneTx); + let result = self.inspect(tracer, InspectExecutionMode::OneTx); let compression_result = if self.has_unpublished_bytecodes() { Err(BytecodeCompressionError::BytecodeCompressionFailed) @@ -680,8 +689,8 @@ impl VmInterface for Vm { self.bootloader_state.start_new_l2_block(l2_block_env) } - fn finish_batch(&mut self) -> FinishedL1Batch { - let result = self.inspect(&mut Tr::default(), VmExecutionMode::Batch); + fn finish_batch(&mut self, _pubdata_builder: Rc) -> FinishedL1Batch { + let result = self.inspect_inner(&mut Tr::default(), VmExecutionMode::Batch); let execution_state = self.get_current_execution_state(); let bootloader_memory = self.bootloader_state.bootloader_memory(); FinishedL1Batch { diff --git a/core/lib/multivm/src/versions/vm_latest/bootloader_state/state.rs b/core/lib/multivm/src/versions/vm_latest/bootloader_state/state.rs index 4ba27b14bad6..2085bbaba31f 100644 --- a/core/lib/multivm/src/versions/vm_latest/bootloader_state/state.rs +++ b/core/lib/multivm/src/versions/vm_latest/bootloader_state/state.rs @@ -1,11 +1,15 @@ use std::cmp::Ordering; use once_cell::sync::OnceCell; -use zksync_types::{L2ChainId, U256}; +use zksync_types::{L2ChainId, ProtocolVersionId, U256}; +use zksync_vm_interface::pubdata::PubdataBuilder; use super::{tx::BootloaderTx, utils::apply_pubdata_to_memory}; use crate::{ - interface::{BootloaderMemory, CompressedBytecodeInfo, L2BlockEnv, TxExecutionMode}, + interface::{ + pubdata::PubdataInput, BootloaderMemory, CompressedBytecodeInfo, L2BlockEnv, + TxExecutionMode, + }, vm_latest::{ bootloader_state::{ l2_block::BootloaderL2Block, @@ -13,7 +17,7 @@ use crate::{ utils::{apply_l2_block, apply_tx_to_memory}, }, constants::TX_DESCRIPTION_OFFSET, - types::internals::{PubdataInput, TransactionData}, + types::internals::TransactionData, utils::l2_blocks::assert_next_block, }, }; @@ -45,6 +49,8 @@ pub struct BootloaderState { free_tx_offset: usize, /// Information about the the pubdata that will be needed to supply to the L1Messenger pubdata_information: OnceCell, + /// Protocol version. + protocol_version: ProtocolVersionId, } impl BootloaderState { @@ -52,6 +58,7 @@ impl BootloaderState { execution_mode: TxExecutionMode, initial_memory: BootloaderMemory, first_l2_block: L2BlockEnv, + protocol_version: ProtocolVersionId, ) -> Self { let l2_block = BootloaderL2Block::new(first_l2_block, 0); Self { @@ -62,6 +69,7 @@ impl BootloaderState { execution_mode, free_tx_offset: 0, pubdata_information: Default::default(), + protocol_version, } } @@ -135,18 +143,31 @@ impl BootloaderState { pub(crate) fn last_l2_block(&self) -> &BootloaderL2Block { self.l2_blocks.last().unwrap() } + pub(crate) fn get_pubdata_information(&self) -> &PubdataInput { self.pubdata_information .get() .expect("Pubdata information is not set") } + pub(crate) fn settlement_layer_pubdata(&self, pubdata_builder: &dyn PubdataBuilder) -> Vec { + let pubdata_information = self + .pubdata_information + .get() + .expect("Pubdata information is not set"); + + pubdata_builder.settlement_layer_pubdata(pubdata_information, self.protocol_version) + } + fn last_mut_l2_block(&mut self) -> &mut BootloaderL2Block { self.l2_blocks.last_mut().unwrap() } /// Apply all bootloader transaction to the initial memory - pub(crate) fn bootloader_memory(&self) -> BootloaderMemory { + pub(crate) fn bootloader_memory( + &self, + pubdata_builder: &dyn PubdataBuilder, + ) -> BootloaderMemory { let mut initial_memory = self.initial_memory.clone(); let mut offset = 0; let mut compressed_bytecodes_offset = 0; @@ -174,11 +195,15 @@ impl BootloaderState { let pubdata_information = self .pubdata_information - .clone() - .into_inner() + .get() .expect("Empty pubdata information"); - apply_pubdata_to_memory(&mut initial_memory, pubdata_information); + apply_pubdata_to_memory( + &mut initial_memory, + pubdata_builder, + pubdata_information, + self.protocol_version, + ); initial_memory } @@ -291,4 +316,8 @@ impl BootloaderState { ); } } + + pub(crate) fn protocol_version(&self) -> ProtocolVersionId { + self.protocol_version + } } diff --git a/core/lib/multivm/src/versions/vm_latest/bootloader_state/utils.rs b/core/lib/multivm/src/versions/vm_latest/bootloader_state/utils.rs index 23c079202c1f..c409bda35c1d 100644 --- a/core/lib/multivm/src/versions/vm_latest/bootloader_state/utils.rs +++ b/core/lib/multivm/src/versions/vm_latest/bootloader_state/utils.rs @@ -1,9 +1,12 @@ -use zksync_types::{ethabi, U256}; +use zksync_types::{ethabi, ProtocolVersionId, U256}; use zksync_utils::{bytes_to_be_words, h256_to_u256}; use super::tx::BootloaderTx; use crate::{ - interface::{BootloaderMemory, CompressedBytecodeInfo, TxExecutionMode}, + interface::{ + pubdata::{PubdataBuilder, PubdataInput}, + BootloaderMemory, CompressedBytecodeInfo, TxExecutionMode, + }, utils::bytecode, vm_latest::{ bootloader_state::l2_block::BootloaderL2Block, @@ -14,7 +17,6 @@ use crate::{ TX_DESCRIPTION_OFFSET, TX_OPERATOR_L2_BLOCK_INFO_OFFSET, TX_OPERATOR_SLOTS_PER_L2_BLOCK_INFO, TX_OVERHEAD_OFFSET, TX_TRUSTED_GAS_LIMIT_OFFSET, }, - types::internals::PubdataInput, }, }; @@ -124,26 +126,61 @@ fn apply_l2_block_inner( ]) } +fn bootloader_memory_input( + pubdata_builder: &dyn PubdataBuilder, + input: &PubdataInput, + protocol_version: ProtocolVersionId, +) -> Vec { + let l2_da_validator_address = pubdata_builder.l2_da_validator(); + let operator_input = pubdata_builder.l1_messenger_operator_input(input, protocol_version); + + ethabi::encode(&[ + ethabi::Token::Address(l2_da_validator_address), + ethabi::Token::Bytes(operator_input), + ]) +} + pub(crate) fn apply_pubdata_to_memory( memory: &mut BootloaderMemory, - pubdata_information: PubdataInput, + pubdata_builder: &dyn PubdataBuilder, + pubdata_information: &PubdataInput, + protocol_version: ProtocolVersionId, ) { - // Skipping two slots as they will be filled by the bootloader itself: - // - One slot is for the selector of the call to the L1Messenger. - // - The other slot is for the 0x20 offset for the calldata. - let l1_messenger_pubdata_start_slot = OPERATOR_PROVIDED_L1_MESSENGER_PUBDATA_OFFSET + 2; - - // Need to skip first word as it represents array offset - // while bootloader expects only [len || data] - let pubdata = ethabi::encode(&[ethabi::Token::Bytes( - pubdata_information.build_pubdata(true), - )])[32..] - .to_vec(); - - assert!( - pubdata.len() / 32 <= OPERATOR_PROVIDED_L1_MESSENGER_PUBDATA_SLOTS - 2, - "The encoded pubdata is too big" - ); + let (l1_messenger_pubdata_start_slot, pubdata) = if protocol_version.is_pre_gateway() { + // Skipping two slots as they will be filled by the bootloader itself: + // - One slot is for the selector of the call to the L1Messenger. + // - The other slot is for the 0x20 offset for the calldata. + let l1_messenger_pubdata_start_slot = OPERATOR_PROVIDED_L1_MESSENGER_PUBDATA_OFFSET + 2; + + // Need to skip first word as it represents array offset + // while bootloader expects only [len || data] + let pubdata = ethabi::encode(&[ethabi::Token::Bytes( + pubdata_builder.l1_messenger_operator_input(pubdata_information, protocol_version), + )])[32..] + .to_vec(); + + assert!( + pubdata.len() / 32 <= OPERATOR_PROVIDED_L1_MESSENGER_PUBDATA_SLOTS - 2, + "The encoded pubdata is too big" + ); + + (l1_messenger_pubdata_start_slot, pubdata) + } else { + // Skipping the first slot as it will be filled by the bootloader itself: + // It is for the selector of the call to the L1Messenger. + let l1_messenger_pubdata_start_slot = OPERATOR_PROVIDED_L1_MESSENGER_PUBDATA_OFFSET + 1; + + let pubdata = + bootloader_memory_input(pubdata_builder, pubdata_information, protocol_version); + + assert!( + // Note that unlike the previous version, the difference is `1`, since now it also includes the offset + pubdata.len() / 32 < OPERATOR_PROVIDED_L1_MESSENGER_PUBDATA_SLOTS, + "The encoded pubdata is too big" + ); + + (l1_messenger_pubdata_start_slot, pubdata) + }; pubdata .chunks(32) diff --git a/core/lib/multivm/src/versions/vm_latest/constants.rs b/core/lib/multivm/src/versions/vm_latest/constants.rs index 01f697ec91a2..c047e6ffa3b0 100644 --- a/core/lib/multivm/src/versions/vm_latest/constants.rs +++ b/core/lib/multivm/src/versions/vm_latest/constants.rs @@ -26,6 +26,7 @@ pub(crate) const fn get_used_bootloader_memory_bytes(subversion: MultiVMSubversi match subversion { MultiVMSubversion::SmallBootloaderMemory => 59_000_000, MultiVMSubversion::IncreasedBootloaderMemory => 63_800_000, + MultiVMSubversion::Gateway => 63_800_000, } } @@ -201,6 +202,6 @@ pub(crate) const TX_SLOT_OVERHEAD_GAS: u32 = 10_000; /// getting often sealed due to the memory limit being reached, the L2 fair gas price will be increased. pub(crate) const TX_MEMORY_OVERHEAD_GAS: u32 = 10; -const ZK_SYNC_BYTES_PER_BLOB: usize = BLOB_CHUNK_SIZE * ELEMENTS_PER_4844_BLOCK; +pub(crate) const ZK_SYNC_BYTES_PER_BLOB: usize = BLOB_CHUNK_SIZE * ELEMENTS_PER_4844_BLOCK; pub const MAX_BLOBS_PER_BATCH: usize = 6; pub const MAX_VM_PUBDATA_PER_BATCH: usize = MAX_BLOBS_PER_BATCH * ZK_SYNC_BYTES_PER_BLOB; diff --git a/core/lib/multivm/src/versions/vm_latest/implementation/execution.rs b/core/lib/multivm/src/versions/vm_latest/implementation/execution.rs index e70f05f85ef2..d9331720ce28 100644 --- a/core/lib/multivm/src/versions/vm_latest/implementation/execution.rs +++ b/core/lib/multivm/src/versions/vm_latest/implementation/execution.rs @@ -69,6 +69,7 @@ impl Vm { self.batch_env.clone(), execution_mode, self.subversion, + None, )) }), self.subversion, diff --git a/core/lib/multivm/src/versions/vm_latest/tests/call_tracer.rs b/core/lib/multivm/src/versions/vm_latest/tests/call_tracer.rs index e1dfdc7e68c5..b502ea50b1af 100644 --- a/core/lib/multivm/src/versions/vm_latest/tests/call_tracer.rs +++ b/core/lib/multivm/src/versions/vm_latest/tests/call_tracer.rs @@ -5,7 +5,7 @@ use zksync_types::{Address, Execute}; use super::TestedLatestVm; use crate::{ - interface::{TxExecutionMode, VmExecutionMode, VmInterface}, + interface::{InspectExecutionMode, TxExecutionMode, VmInterface}, tracers::CallTracer, versions::testonly::{ read_max_depth_contract, read_test_contract, ContractToDeploy, VmTesterBuilder, @@ -43,7 +43,7 @@ fn test_max_depth() { vm.vm.push_transaction(tx); let res = vm .vm - .inspect(&mut call_tracer.into(), VmExecutionMode::OneTx); + .inspect(&mut call_tracer.into(), InspectExecutionMode::OneTx); assert!(result.get().is_some()); assert!(res.result.is_failed()); } @@ -79,7 +79,7 @@ fn test_basic_behavior() { vm.vm.push_transaction(tx); let res = vm .vm - .inspect(&mut call_tracer.into(), VmExecutionMode::OneTx); + .inspect(&mut call_tracer.into(), InspectExecutionMode::OneTx); let call_tracer_result = result.get().unwrap(); diff --git a/core/lib/multivm/src/versions/vm_latest/tests/mod.rs b/core/lib/multivm/src/versions/vm_latest/tests/mod.rs index 6f748d543d35..96d59f208b03 100644 --- a/core/lib/multivm/src/versions/vm_latest/tests/mod.rs +++ b/core/lib/multivm/src/versions/vm_latest/tests/mod.rs @@ -1,4 +1,7 @@ -use std::collections::{HashMap, HashSet}; +use std::{ + collections::{HashMap, HashSet}, + rc::Rc, +}; use zk_evm_1_5_0::{ aux_structures::{MemoryPage, Timestamp}, @@ -7,6 +10,7 @@ use zk_evm_1_5_0::{ }; use zksync_types::{writes::StateDiffRecord, StorageKey, StorageValue, Transaction, H256, U256}; use zksync_utils::{bytecode::hash_bytecode, bytes_to_be_words, h256_to_u256}; +use zksync_vm_interface::pubdata::PubdataBuilder; use super::{HistoryEnabled, Vm}; use crate::{ @@ -75,18 +79,31 @@ impl TestedVm for TestedLatestVm { self.get_used_contracts().into_iter().collect() } - fn execute_with_state_diffs( + fn finish_batch_with_state_diffs( &mut self, diffs: Vec, - mode: VmExecutionMode, + pubdata_builder: Rc, ) -> VmExecutionResultAndLogs { let pubdata_tracer = PubdataTracer::new_with_forced_state_diffs( self.batch_env.clone(), VmExecutionMode::Batch, diffs, crate::vm_latest::MultiVMSubversion::latest(), + Some(pubdata_builder), ); - self.inspect_inner(&mut TracerDispatcher::default(), mode, Some(pubdata_tracer)) + self.inspect_inner( + &mut TracerDispatcher::default(), + VmExecutionMode::Batch, + Some(pubdata_tracer), + ) + } + + fn finish_batch_without_pubdata(&mut self) -> VmExecutionResultAndLogs { + self.inspect_inner( + &mut TracerDispatcher::default(), + VmExecutionMode::Batch, + None, + ) } fn insert_bytecodes(&mut self, bytecodes: &[&[u8]]) { diff --git a/core/lib/multivm/src/versions/vm_latest/tests/prestate_tracer.rs b/core/lib/multivm/src/versions/vm_latest/tests/prestate_tracer.rs index 838c4e342dcb..7028f7a89711 100644 --- a/core/lib/multivm/src/versions/vm_latest/tests/prestate_tracer.rs +++ b/core/lib/multivm/src/versions/vm_latest/tests/prestate_tracer.rs @@ -6,7 +6,7 @@ use zksync_types::{utils::deployed_address_create, Execute, U256}; use super::TestedLatestVm; use crate::{ - interface::{TxExecutionMode, VmExecutionMode, VmInterface, VmInterfaceExt}, + interface::{InspectExecutionMode, TxExecutionMode, VmInterface, VmInterfaceExt}, tracers::PrestateTracer, versions::testonly::{read_simple_transfer_contract, VmTesterBuilder}, vm_latest::{constants::BATCH_COMPUTATIONAL_GAS_LIMIT, ToTracerPointer}, @@ -38,7 +38,7 @@ fn test_prestate_tracer() { let prestate_tracer = PrestateTracer::new(false, prestate_tracer_result.clone()); let tracer_ptr = prestate_tracer.into_tracer_pointer(); vm.vm - .inspect(&mut tracer_ptr.into(), VmExecutionMode::Batch); + .inspect(&mut tracer_ptr.into(), InspectExecutionMode::OneTx); let prestate_result = Arc::try_unwrap(prestate_tracer_result) .unwrap() @@ -61,7 +61,7 @@ fn test_prestate_tracer_diff_mode() { let tx = account.get_deploy_tx(&contract, None, TxType::L2).tx; let nonce = tx.nonce().unwrap().0.into(); vm.vm.push_transaction(tx); - vm.vm.execute(VmExecutionMode::OneTx); + vm.vm.execute(InspectExecutionMode::OneTx); let deployed_address = deployed_address_create(account.address, nonce); vm.test_contract = Some(deployed_address); @@ -69,7 +69,7 @@ fn test_prestate_tracer_diff_mode() { let tx2 = account.get_deploy_tx(&contract, None, TxType::L2).tx; let nonce2 = tx2.nonce().unwrap().0.into(); vm.vm.push_transaction(tx2); - vm.vm.execute(VmExecutionMode::OneTx); + vm.vm.execute(InspectExecutionMode::OneTx); let deployed_address2 = deployed_address_create(account.address, nonce2); let account = &mut vm.rich_accounts[0]; @@ -98,7 +98,7 @@ fn test_prestate_tracer_diff_mode() { let prestate_tracer = PrestateTracer::new(true, prestate_tracer_result.clone()); let tracer_ptr = prestate_tracer.into_tracer_pointer(); vm.vm - .inspect(&mut tracer_ptr.into(), VmExecutionMode::Bootloader); + .inspect(&mut tracer_ptr.into(), InspectExecutionMode::Bootloader); let prestate_result = Arc::try_unwrap(prestate_tracer_result) .unwrap() diff --git a/core/lib/multivm/src/versions/vm_latest/tests/rollbacks.rs b/core/lib/multivm/src/versions/vm_latest/tests/rollbacks.rs index c948315266ad..de674498427d 100644 --- a/core/lib/multivm/src/versions/vm_latest/tests/rollbacks.rs +++ b/core/lib/multivm/src/versions/vm_latest/tests/rollbacks.rs @@ -2,13 +2,14 @@ use ethabi::Token; use zksync_contracts::{get_loadnext_contract, test_contracts::LoadnextContractExecutionParams}; use zksync_test_account::{DeployContractsTx, TxType}; use zksync_types::{get_nonce_key, U256}; +use zksync_vm_interface::InspectExecutionMode; use super::TestedLatestVm; use crate::{ interface::{ storage::WriteStorage, tracer::{TracerExecutionStatus, TracerExecutionStopReason}, - TxExecutionMode, VmExecutionMode, VmInterface, VmInterfaceExt, VmInterfaceHistoryEnabled, + TxExecutionMode, VmInterface, VmInterfaceExt, VmInterfaceHistoryEnabled, }, tracers::dynamic::vm_1_5_0::DynTracer, versions::testonly::{ @@ -80,7 +81,7 @@ fn test_layered_rollback() { TxType::L2, ); vm.vm.push_transaction(deploy_tx); - let deployment_res = vm.vm.execute(VmExecutionMode::OneTx); + let deployment_res = vm.vm.execute(InspectExecutionMode::OneTx); assert!(!deployment_res.result.is_failed(), "transaction failed"); let loadnext_transaction = account.get_loadnext_transaction( @@ -107,7 +108,8 @@ fn test_layered_rollback() { max_recursion_depth: 15, } .into_tracer_pointer(); - vm.vm.inspect(&mut tracer.into(), VmExecutionMode::OneTx); + vm.vm + .inspect(&mut tracer.into(), InspectExecutionMode::OneTx); let nonce_val2 = vm .vm @@ -134,7 +136,7 @@ fn test_layered_rollback() { ); vm.vm.push_transaction(loadnext_transaction); - let result = vm.vm.execute(VmExecutionMode::OneTx); + let result = vm.vm.execute(InspectExecutionMode::OneTx); assert!(!result.result.is_failed(), "transaction must not fail"); } diff --git a/core/lib/multivm/src/versions/vm_latest/tracers/pubdata_tracer.rs b/core/lib/multivm/src/versions/vm_latest/tracers/pubdata_tracer.rs index 32f3984834c8..998e8a13ad25 100644 --- a/core/lib/multivm/src/versions/vm_latest/tracers/pubdata_tracer.rs +++ b/core/lib/multivm/src/versions/vm_latest/tracers/pubdata_tracer.rs @@ -1,4 +1,4 @@ -use std::marker::PhantomData; +use std::{marker::PhantomData, rc::Rc}; use circuit_sequencer_api_1_5_0::sort_storage_access::sort_storage_access_queries; use zk_evm_1_5_0::{ @@ -7,9 +7,11 @@ use zk_evm_1_5_0::{ }; use zksync_types::{writes::StateDiffRecord, AccountTreeId, StorageKey, L1_MESSENGER_ADDRESS}; use zksync_utils::{h256_to_u256, u256_to_bytes_be, u256_to_h256}; +use zksync_vm_interface::pubdata::PubdataBuilder; use crate::{ interface::{ + pubdata::{L1MessengerL2ToL1Log, PubdataInput}, storage::{StoragePtr, WriteStorage}, tracer::{TracerExecutionStatus, TracerExecutionStopReason}, L1BatchEnv, VmEvent, VmExecutionMode, @@ -17,14 +19,14 @@ use crate::{ tracers::dynamic::vm_1_5_0::DynTracer, utils::events::{ extract_bytecode_publication_requests_from_l1_messenger, - extract_l2tol1logs_from_l1_messenger, L1MessengerL2ToL1Log, + extract_l2tol1logs_from_l1_messenger, }, vm_latest::{ bootloader_state::{utils::apply_pubdata_to_memory, BootloaderState}, constants::BOOTLOADER_HEAP_PAGE, old_vm::{history_recorder::HistoryMode, memory::SimpleMemory}, tracers::{traits::VmTracer, utils::VmHook}, - types::internals::{PubdataInput, ZkSyncVmState}, + types::internals::ZkSyncVmState, utils::logs::collect_events_and_l1_system_logs_after_timestamp, vm::MultiVMSubversion, StorageOracle, @@ -41,6 +43,7 @@ pub(crate) struct PubdataTracer { // to the L1Messenger. enforced_state_diffs: Option>, subversion: MultiVMSubversion, + pubdata_builder: Option>, _phantom_data: PhantomData, } @@ -49,6 +52,7 @@ impl PubdataTracer { l1_batch_env: L1BatchEnv, execution_mode: VmExecutionMode, subversion: MultiVMSubversion, + pubdata_builder: Option>, ) -> Self { Self { l1_batch_env, @@ -56,6 +60,7 @@ impl PubdataTracer { execution_mode, enforced_state_diffs: None, subversion, + pubdata_builder, _phantom_data: Default::default(), } } @@ -68,6 +73,7 @@ impl PubdataTracer { execution_mode: VmExecutionMode, forced_state_diffs: Vec, subversion: MultiVMSubversion, + pubdata_builder: Option>, ) -> Self { Self { l1_batch_env, @@ -75,6 +81,7 @@ impl PubdataTracer { execution_mode, enforced_state_diffs: Some(forced_state_diffs), subversion, + pubdata_builder, _phantom_data: Default::default(), } } @@ -221,13 +228,22 @@ impl VmTracer for PubdataTracer { if self.pubdata_info_requested { let pubdata_input = self.build_pubdata_input(state); - // Save the pubdata for the future initial bootloader memory building - bootloader_state.set_pubdata_input(pubdata_input.clone()); - // Apply the pubdata to the current memory let mut memory_to_apply = vec![]; - apply_pubdata_to_memory(&mut memory_to_apply, pubdata_input); + apply_pubdata_to_memory( + &mut memory_to_apply, + self.pubdata_builder + .as_ref() + .expect("`pubdata_builder` is required to finish batch") + .as_ref(), + &pubdata_input, + bootloader_state.protocol_version(), + ); + + // Save the pubdata for the future initial bootloader memory building + bootloader_state.set_pubdata_input(pubdata_input); + state.memory.populate_page( BOOTLOADER_HEAP_PAGE as usize, memory_to_apply, diff --git a/core/lib/multivm/src/versions/vm_latest/types/internals/mod.rs b/core/lib/multivm/src/versions/vm_latest/types/internals/mod.rs index 7dc60ec5b0fb..601b7b8bd014 100644 --- a/core/lib/multivm/src/versions/vm_latest/types/internals/mod.rs +++ b/core/lib/multivm/src/versions/vm_latest/types/internals/mod.rs @@ -1,9 +1,7 @@ -pub(crate) use pubdata::PubdataInput; pub(crate) use snapshot::VmSnapshot; pub(crate) use transaction_data::TransactionData; pub(crate) use vm_state::new_vm_state; pub use vm_state::ZkSyncVmState; -mod pubdata; mod snapshot; mod transaction_data; mod vm_state; diff --git a/core/lib/multivm/src/versions/vm_latest/types/internals/pubdata.rs b/core/lib/multivm/src/versions/vm_latest/types/internals/pubdata.rs deleted file mode 100644 index d07732ae4350..000000000000 --- a/core/lib/multivm/src/versions/vm_latest/types/internals/pubdata.rs +++ /dev/null @@ -1,123 +0,0 @@ -use zksync_types::writes::{compress_state_diffs, StateDiffRecord}; - -use crate::utils::events::L1MessengerL2ToL1Log; - -/// Struct based on which the pubdata blob is formed -#[derive(Debug, Clone, Default)] -pub(crate) struct PubdataInput { - pub(crate) user_logs: Vec, - pub(crate) l2_to_l1_messages: Vec>, - pub(crate) published_bytecodes: Vec>, - pub(crate) state_diffs: Vec, -} - -impl PubdataInput { - pub(crate) fn build_pubdata(self, with_uncompressed_state_diffs: bool) -> Vec { - let mut l1_messenger_pubdata = vec![]; - - let PubdataInput { - user_logs, - l2_to_l1_messages, - published_bytecodes, - state_diffs, - } = self; - - // Encoding user L2->L1 logs. - // Format: `[(numberOfL2ToL1Logs as u32) || l2tol1logs[1] || ... || l2tol1logs[n]]` - l1_messenger_pubdata.extend((user_logs.len() as u32).to_be_bytes()); - for l2tol1log in user_logs { - l1_messenger_pubdata.extend(l2tol1log.packed_encoding()); - } - - // Encoding L2->L1 messages - // Format: `[(numberOfMessages as u32) || (messages[1].len() as u32) || messages[1] || ... || (messages[n].len() as u32) || messages[n]]` - l1_messenger_pubdata.extend((l2_to_l1_messages.len() as u32).to_be_bytes()); - for message in l2_to_l1_messages { - l1_messenger_pubdata.extend((message.len() as u32).to_be_bytes()); - l1_messenger_pubdata.extend(message); - } - - // Encoding bytecodes - // Format: `[(numberOfBytecodes as u32) || (bytecodes[1].len() as u32) || bytecodes[1] || ... || (bytecodes[n].len() as u32) || bytecodes[n]]` - l1_messenger_pubdata.extend((published_bytecodes.len() as u32).to_be_bytes()); - for bytecode in published_bytecodes { - l1_messenger_pubdata.extend((bytecode.len() as u32).to_be_bytes()); - l1_messenger_pubdata.extend(bytecode); - } - - // Encoding state diffs - // Format: `[size of compressed state diffs u32 || compressed state diffs || (# state diffs: intial + repeated) as u32 || sorted state diffs by ]` - let state_diffs_compressed = compress_state_diffs(state_diffs.clone()); - l1_messenger_pubdata.extend(state_diffs_compressed); - - if with_uncompressed_state_diffs { - l1_messenger_pubdata.extend((state_diffs.len() as u32).to_be_bytes()); - for state_diff in state_diffs { - l1_messenger_pubdata.extend(state_diff.encode_padded()); - } - } - - l1_messenger_pubdata - } -} - -#[cfg(test)] -mod tests { - use zksync_system_constants::{ACCOUNT_CODE_STORAGE_ADDRESS, BOOTLOADER_ADDRESS}; - use zksync_utils::u256_to_h256; - - use super::*; - - #[test] - fn test_basic_pubdata_building() { - // Just using some constant addresses for tests - let addr1 = BOOTLOADER_ADDRESS; - let addr2 = ACCOUNT_CODE_STORAGE_ADDRESS; - - let user_logs = vec![L1MessengerL2ToL1Log { - l2_shard_id: 0, - is_service: false, - tx_number_in_block: 0, - sender: addr1, - key: 1.into(), - value: 128.into(), - }]; - - let l2_to_l1_messages = vec![hex::decode("deadbeef").unwrap()]; - - let published_bytecodes = vec![hex::decode("aaaabbbb").unwrap()]; - - // For covering more cases, we have two state diffs: - // One with enumeration index present (and so it is a repeated write) and the one without it. - let state_diffs = vec![ - StateDiffRecord { - address: addr2, - key: 155.into(), - derived_key: u256_to_h256(125.into()).0, - enumeration_index: 12, - initial_value: 11.into(), - final_value: 12.into(), - }, - StateDiffRecord { - address: addr2, - key: 156.into(), - derived_key: u256_to_h256(126.into()).0, - enumeration_index: 0, - initial_value: 0.into(), - final_value: 14.into(), - }, - ]; - - let input = PubdataInput { - user_logs, - l2_to_l1_messages, - published_bytecodes, - state_diffs, - }; - - let pubdata = - ethabi::encode(&[ethabi::Token::Bytes(input.build_pubdata(true))])[32..].to_vec(); - - assert_eq!(hex::encode(pubdata), "00000000000000000000000000000000000000000000000000000000000002c700000001000000000000000000000000000000000000000000008001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000800000000100000004deadbeef0000000100000004aaaabbbb0100002a040001000000000000000000000000000000000000000000000000000000000000007e090e0000000c0901000000020000000000000000000000000000000000008002000000000000000000000000000000000000000000000000000000000000009b000000000000000000000000000000000000000000000000000000000000007d000000000000000c000000000000000000000000000000000000000000000000000000000000000b000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008002000000000000000000000000000000000000000000000000000000000000009c000000000000000000000000000000000000000000000000000000000000007e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"); - } -} diff --git a/core/lib/multivm/src/versions/vm_latest/types/internals/vm_state.rs b/core/lib/multivm/src/versions/vm_latest/types/internals/vm_state.rs index cb4b13eecdf0..d25f66361f1b 100644 --- a/core/lib/multivm/src/versions/vm_latest/types/internals/vm_state.rs +++ b/core/lib/multivm/src/versions/vm_latest/types/internals/vm_state.rs @@ -191,6 +191,7 @@ pub(crate) fn new_vm_state( system_env.execution_mode, bootloader_initial_memory, first_l2_block, + system_env.version, ); (vm, bootloader_state) diff --git a/core/lib/multivm/src/versions/vm_latest/vm.rs b/core/lib/multivm/src/versions/vm_latest/vm.rs index 3a36b008e884..ef6cee454a87 100644 --- a/core/lib/multivm/src/versions/vm_latest/vm.rs +++ b/core/lib/multivm/src/versions/vm_latest/vm.rs @@ -1,4 +1,4 @@ -use std::collections::HashMap; +use std::{collections::HashMap, rc::Rc}; use circuit_sequencer_api_1_5_0::sort_storage_access::sort_storage_access_queries; use zksync_types::{ @@ -7,6 +7,7 @@ use zksync_types::{ Transaction, H256, }; use zksync_utils::{be_words_to_bytes, h256_to_u256, u256_to_h256}; +use zksync_vm_interface::{pubdata::PubdataBuilder, InspectExecutionMode}; use crate::{ glue::GlueInto, @@ -21,7 +22,7 @@ use crate::{ vm_latest::{ bootloader_state::BootloaderState, old_vm::{events::merge_events, history_recorder::HistoryEnabled}, - tracers::dispatcher::TracerDispatcher, + tracers::{dispatcher::TracerDispatcher, PubdataTracer}, types::internals::{new_vm_state, VmSnapshot, ZkSyncVmState}, }, HistoryMode, @@ -38,6 +39,8 @@ pub(crate) enum MultiVMSubversion { SmallBootloaderMemory, /// The final correct version of v1.5.0 IncreasedBootloaderMemory, + /// VM for post-gateway versions. + Gateway, } impl MultiVMSubversion { @@ -55,6 +58,7 @@ impl TryFrom for MultiVMSubversion { match value { VmVersion::Vm1_5_0SmallBootloaderMemory => Ok(Self::SmallBootloaderMemory), VmVersion::Vm1_5_0IncreasedBootloaderMemory => Ok(Self::IncreasedBootloaderMemory), + VmVersion::VmGateway => Ok(Self::Gateway), _ => Err(VmVersionIsNotVm150Error), } } @@ -148,9 +152,9 @@ impl VmInterface for Vm { fn inspect( &mut self, tracer: &mut Self::TracerDispatcher, - execution_mode: VmExecutionMode, + execution_mode: InspectExecutionMode, ) -> VmExecutionResultAndLogs { - self.inspect_inner(tracer, execution_mode, None) + self.inspect_inner(tracer, execution_mode.into(), None) } fn start_new_l2_block(&mut self, l2_block_env: L2BlockEnv) { @@ -182,19 +186,30 @@ impl VmInterface for Vm { } } - fn finish_batch(&mut self) -> FinishedL1Batch { - let result = self.inspect(&mut TracerDispatcher::default(), VmExecutionMode::Batch); + fn finish_batch(&mut self, pubdata_builder: Rc) -> FinishedL1Batch { + let pubdata_tracer = Some(PubdataTracer::new( + self.batch_env.clone(), + VmExecutionMode::Batch, + self.subversion, + Some(pubdata_builder.clone()), + )); + + let result = self.inspect_inner( + &mut TracerDispatcher::default(), + VmExecutionMode::Batch, + pubdata_tracer, + ); let execution_state = self.get_current_execution_state(); - let bootloader_memory = self.bootloader_state.bootloader_memory(); + let bootloader_memory = self + .bootloader_state + .bootloader_memory(pubdata_builder.as_ref()); FinishedL1Batch { block_tip_execution_result: result, final_execution_state: execution_state, final_bootloader_memory: Some(bootloader_memory), pubdata_input: Some( self.bootloader_state - .get_pubdata_information() - .clone() - .build_pubdata(false), + .settlement_layer_pubdata(pubdata_builder.as_ref()), ), state_diffs: Some( self.bootloader_state diff --git a/core/lib/multivm/src/versions/vm_m5/vm.rs b/core/lib/multivm/src/versions/vm_m5/vm.rs index 3d57d1cd5439..55afeed17cd1 100644 --- a/core/lib/multivm/src/versions/vm_m5/vm.rs +++ b/core/lib/multivm/src/versions/vm_m5/vm.rs @@ -1,13 +1,15 @@ +use std::rc::Rc; + use zksync_types::{vm::VmVersion, Transaction}; use zksync_utils::h256_to_u256; +use zksync_vm_interface::{pubdata::PubdataBuilder, InspectExecutionMode}; use crate::{ glue::{history_mode::HistoryMode, GlueInto}, interface::{ storage::StoragePtr, BytecodeCompressionResult, FinishedL1Batch, L1BatchEnv, L2BlockEnv, - PushTransactionResult, SystemEnv, TxExecutionMode, VmExecutionMode, - VmExecutionResultAndLogs, VmFactory, VmInterface, VmInterfaceHistoryEnabled, - VmMemoryMetrics, + PushTransactionResult, SystemEnv, TxExecutionMode, VmExecutionResultAndLogs, VmFactory, + VmInterface, VmInterfaceHistoryEnabled, VmMemoryMetrics, }, vm_m5::{ storage::Storage, @@ -75,10 +77,10 @@ impl VmInterface for Vm { fn inspect( &mut self, _tracer: &mut Self::TracerDispatcher, - execution_mode: VmExecutionMode, + execution_mode: InspectExecutionMode, ) -> VmExecutionResultAndLogs { match execution_mode { - VmExecutionMode::OneTx => match self.system_env.execution_mode { + InspectExecutionMode::OneTx => match self.system_env.execution_mode { TxExecutionMode::VerifyExecute => self.vm.execute_next_tx().glue_into(), TxExecutionMode::EstimateFee | TxExecutionMode::EthCall => self .vm @@ -87,8 +89,7 @@ impl VmInterface for Vm { ) .glue_into(), }, - VmExecutionMode::Batch => self.finish_batch().block_tip_execution_result, - VmExecutionMode::Bootloader => self.vm.execute_block_tip().glue_into(), + InspectExecutionMode::Bootloader => self.vm.execute_block_tip().glue_into(), } } @@ -110,11 +111,11 @@ impl VmInterface for Vm { // Bytecode compression isn't supported ( Ok(vec![].into()), - self.inspect(&mut (), VmExecutionMode::OneTx), + self.inspect(&mut (), InspectExecutionMode::OneTx), ) } - fn finish_batch(&mut self) -> FinishedL1Batch { + fn finish_batch(&mut self, _pubdata_builder: Rc) -> FinishedL1Batch { self.vm .execute_till_block_end( crate::vm_m5::vm_with_bootloader::BootloaderJobType::BlockPostprocessing, diff --git a/core/lib/multivm/src/versions/vm_m6/vm.rs b/core/lib/multivm/src/versions/vm_m6/vm.rs index 1ee6aa618220..4c67a2184180 100644 --- a/core/lib/multivm/src/versions/vm_m6/vm.rs +++ b/core/lib/multivm/src/versions/vm_m6/vm.rs @@ -1,13 +1,14 @@ -use std::collections::HashSet; +use std::{collections::HashSet, rc::Rc}; use zksync_types::{vm::VmVersion, Transaction}; use zksync_utils::{bytecode::hash_bytecode, h256_to_u256}; +use zksync_vm_interface::{pubdata::PubdataBuilder, InspectExecutionMode}; use crate::{ glue::{history_mode::HistoryMode, GlueInto}, interface::{ storage::StoragePtr, BytecodeCompressionError, BytecodeCompressionResult, FinishedL1Batch, - L1BatchEnv, L2BlockEnv, PushTransactionResult, SystemEnv, TxExecutionMode, VmExecutionMode, + L1BatchEnv, L2BlockEnv, PushTransactionResult, SystemEnv, TxExecutionMode, VmExecutionResultAndLogs, VmFactory, VmInterface, VmInterfaceHistoryEnabled, VmMemoryMetrics, }, @@ -88,7 +89,7 @@ impl VmInterface for Vm { fn inspect( &mut self, tracer: &mut Self::TracerDispatcher, - execution_mode: VmExecutionMode, + execution_mode: InspectExecutionMode, ) -> VmExecutionResultAndLogs { if let Some(storage_invocations) = tracer.storage_invocations { self.vm @@ -97,7 +98,7 @@ impl VmInterface for Vm { } match execution_mode { - VmExecutionMode::OneTx => match self.system_env.execution_mode { + InspectExecutionMode::OneTx => match self.system_env.execution_mode { TxExecutionMode::VerifyExecute => { let enable_call_tracer = tracer.call_tracer.is_some(); let result = self.vm.execute_next_tx( @@ -116,8 +117,7 @@ impl VmInterface for Vm { ) .glue_into(), }, - VmExecutionMode::Batch => self.finish_batch().block_tip_execution_result, - VmExecutionMode::Bootloader => self.vm.execute_block_tip().glue_into(), + InspectExecutionMode::Bootloader => self.vm.execute_block_tip().glue_into(), } } @@ -207,7 +207,7 @@ impl VmInterface for Vm { } } - fn finish_batch(&mut self) -> FinishedL1Batch { + fn finish_batch(&mut self, _pubdata_builder: Rc) -> FinishedL1Batch { self.vm .execute_till_block_end( crate::vm_m6::vm_with_bootloader::BootloaderJobType::BlockPostprocessing, diff --git a/core/lib/multivm/src/versions/vm_refunds_enhancement/vm.rs b/core/lib/multivm/src/versions/vm_refunds_enhancement/vm.rs index 2bcd68bec044..81b0c52cce5e 100644 --- a/core/lib/multivm/src/versions/vm_refunds_enhancement/vm.rs +++ b/core/lib/multivm/src/versions/vm_refunds_enhancement/vm.rs @@ -1,5 +1,8 @@ +use std::rc::Rc; + use circuit_sequencer_api_1_3_3::sort_storage_access::sort_storage_access_queries; use zksync_types::{l2_to_l1_log::UserL2ToL1Log, Transaction}; +use zksync_vm_interface::{pubdata::PubdataBuilder, InspectExecutionMode}; use crate::{ glue::GlueInto, @@ -88,9 +91,9 @@ impl VmInterface for Vm { fn inspect( &mut self, dispatcher: &mut Self::TracerDispatcher, - execution_mode: VmExecutionMode, + execution_mode: InspectExecutionMode, ) -> VmExecutionResultAndLogs { - self.inspect_inner(dispatcher, execution_mode) + self.inspect_inner(dispatcher, execution_mode.into()) } fn start_new_l2_block(&mut self, l2_block_env: L2BlockEnv) { @@ -105,7 +108,7 @@ impl VmInterface for Vm { with_compression: bool, ) -> (BytecodeCompressionResult<'_>, VmExecutionResultAndLogs) { self.push_transaction_with_compression(tx, with_compression); - let result = self.inspect(dispatcher, VmExecutionMode::OneTx); + let result = self.inspect(dispatcher, InspectExecutionMode::OneTx); if self.has_unpublished_bytecodes() { ( Err(BytecodeCompressionError::BytecodeCompressionFailed), @@ -122,8 +125,8 @@ impl VmInterface for Vm { } } - fn finish_batch(&mut self) -> FinishedL1Batch { - let result = self.inspect(&mut TracerDispatcher::default(), VmExecutionMode::Batch); + fn finish_batch(&mut self, _pubdata_builder: Rc) -> FinishedL1Batch { + let result = self.inspect_inner(&mut TracerDispatcher::default(), VmExecutionMode::Batch); let execution_state = self.get_current_execution_state(); let bootloader_memory = self.bootloader_state.bootloader_memory(); FinishedL1Batch { diff --git a/core/lib/multivm/src/versions/vm_virtual_blocks/vm.rs b/core/lib/multivm/src/versions/vm_virtual_blocks/vm.rs index 497128c64bd9..a2d18e10de44 100644 --- a/core/lib/multivm/src/versions/vm_virtual_blocks/vm.rs +++ b/core/lib/multivm/src/versions/vm_virtual_blocks/vm.rs @@ -1,5 +1,8 @@ +use std::rc::Rc; + use circuit_sequencer_api_1_3_3::sort_storage_access::sort_storage_access_queries; use zksync_types::{l2_to_l1_log::UserL2ToL1Log, Transaction}; +use zksync_vm_interface::{pubdata::PubdataBuilder, InspectExecutionMode}; use crate::{ glue::GlueInto, @@ -88,9 +91,9 @@ impl VmInterface for Vm { fn inspect( &mut self, tracer: &mut TracerDispatcher, - execution_mode: VmExecutionMode, + execution_mode: InspectExecutionMode, ) -> VmExecutionResultAndLogs { - self.inspect_inner(tracer, execution_mode) + self.inspect_inner(tracer, execution_mode.into()) } fn start_new_l2_block(&mut self, l2_block_env: L2BlockEnv) { @@ -122,8 +125,8 @@ impl VmInterface for Vm { } } - fn finish_batch(&mut self) -> FinishedL1Batch { - let result = self.inspect(&mut TracerDispatcher::default(), VmExecutionMode::Batch); + fn finish_batch(&mut self, _pubdata_builder: Rc) -> FinishedL1Batch { + let result = self.inspect_inner(&mut TracerDispatcher::default(), VmExecutionMode::Batch); let execution_state = self.get_current_execution_state(); let bootloader_memory = self.bootloader_state.bootloader_memory(); FinishedL1Batch { diff --git a/core/lib/multivm/src/vm_instance.rs b/core/lib/multivm/src/vm_instance.rs index 43a6c48aa9c5..5ff27046377a 100644 --- a/core/lib/multivm/src/vm_instance.rs +++ b/core/lib/multivm/src/vm_instance.rs @@ -1,7 +1,8 @@ -use std::mem; +use std::{mem, rc::Rc}; use zksync_types::{vm::VmVersion, ProtocolVersionId, Transaction}; use zksync_vm2::interface::Tracer; +use zksync_vm_interface::{pubdata::PubdataBuilder, InspectExecutionMode}; use crate::{ glue::history_mode::HistoryMode, @@ -9,8 +10,8 @@ use crate::{ storage::{ImmutableStorageView, ReadStorage, StoragePtr, StorageView}, utils::ShadowVm, BytecodeCompressionResult, FinishedL1Batch, L1BatchEnv, L2BlockEnv, PushTransactionResult, - SystemEnv, VmExecutionMode, VmExecutionResultAndLogs, VmFactory, VmInterface, - VmInterfaceHistoryEnabled, VmMemoryMetrics, + SystemEnv, VmExecutionResultAndLogs, VmFactory, VmInterface, VmInterfaceHistoryEnabled, + VmMemoryMetrics, }, tracers::TracerDispatcher, vm_latest::HistoryEnabled, @@ -63,7 +64,7 @@ impl VmInterface for LegacyVmInstance { fn inspect( &mut self, dispatcher: &mut Self::TracerDispatcher, - execution_mode: VmExecutionMode, + execution_mode: InspectExecutionMode, ) -> VmExecutionResultAndLogs { dispatch_legacy_vm!(self.inspect(&mut mem::take(dispatcher).into(), execution_mode)) } @@ -87,8 +88,8 @@ impl VmInterface for LegacyVmInstance { } /// Return the results of execution of all batch - fn finish_batch(&mut self) -> FinishedL1Batch { - dispatch_legacy_vm!(self.finish_batch()) + fn finish_batch(&mut self, pubdata_builder: Rc) -> FinishedL1Batch { + dispatch_legacy_vm!(self.finish_batch(pubdata_builder)) } } @@ -206,6 +207,15 @@ impl LegacyVmInstance { ); Self::Vm1_5_0(vm) } + VmVersion::VmGateway => { + let vm = crate::vm_latest::Vm::new_with_subversion( + l1_batch_env, + system_env, + storage_view, + crate::vm_latest::MultiVMSubversion::Gateway, + ); + Self::Vm1_5_0(vm) + } } } @@ -253,7 +263,7 @@ impl VmInterface for FastVmInsta fn inspect( &mut self, tracer: &mut Self::TracerDispatcher, - execution_mode: VmExecutionMode, + execution_mode: InspectExecutionMode, ) -> VmExecutionResultAndLogs { match self { Self::Fast(vm) => vm.inspect(&mut tracer.1, execution_mode), @@ -283,8 +293,8 @@ impl VmInterface for FastVmInsta } } - fn finish_batch(&mut self) -> FinishedL1Batch { - dispatch_fast_vm!(self.finish_batch()) + fn finish_batch(&mut self, pubdata_builder: Rc) -> FinishedL1Batch { + dispatch_fast_vm!(self.finish_batch(pubdata_builder)) } } diff --git a/core/lib/protobuf_config/src/contracts.rs b/core/lib/protobuf_config/src/contracts.rs index 84c404367503..84f03c5afe3a 100644 --- a/core/lib/protobuf_config/src/contracts.rs +++ b/core/lib/protobuf_config/src/contracts.rs @@ -76,6 +76,12 @@ impl ProtoRepr for proto::Contracts { .map(|x| parse_h160(x)) .transpose() .context("l2_shared_bridge_addr")?, + l2_legacy_shared_bridge_addr: l2 + .legacy_shared_bridge_addr + .as_ref() + .map(|x| parse_h160(x)) + .transpose() + .context("l2_legacy_shared_bridge_addr")?, l1_weth_bridge_proxy_addr: weth_bridge .as_ref() .and_then(|bridge| bridge.l1_address.as_ref().map(|x| parse_h160(x))) @@ -107,6 +113,12 @@ impl ProtoRepr for proto::Contracts { .map(|x| parse_h160(x)) .transpose() .context("chain_admin_addr")?, + l2_da_validator_addr: l2 + .da_validator_addr + .as_ref() + .map(|x| parse_h160(x)) + .transpose() + .context("l2_da_validator_addr")?, }) } @@ -142,6 +154,10 @@ impl ProtoRepr for proto::Contracts { }), l2: Some(proto::L2 { testnet_paymaster_addr: this.l2_testnet_paymaster_addr.map(|a| format!("{:?}", a)), + da_validator_addr: this.l2_da_validator_addr.map(|a| format!("{:?}", a)), + legacy_shared_bridge_addr: this + .l2_legacy_shared_bridge_addr + .map(|a| format!("{:?}", a)), }), bridges: Some(proto::Bridges { shared: Some(proto::Bridge { diff --git a/core/lib/protobuf_config/src/proto/config/contracts.proto b/core/lib/protobuf_config/src/proto/config/contracts.proto index f4488c7901a1..6ab03e6aa11b 100644 --- a/core/lib/protobuf_config/src/proto/config/contracts.proto +++ b/core/lib/protobuf_config/src/proto/config/contracts.proto @@ -21,6 +21,8 @@ message L1 { message L2 { optional string testnet_paymaster_addr = 1; // optional; H160 + optional string da_validator_addr = 2; // optional; H160 + optional string legacy_shared_bridge_addr = 3; // optional; H160 } message Bridge { diff --git a/core/lib/prover_interface/src/inputs.rs b/core/lib/prover_interface/src/inputs.rs index 97de24f42dae..cfc1d4a0d552 100644 --- a/core/lib/prover_interface/src/inputs.rs +++ b/core/lib/prover_interface/src/inputs.rs @@ -5,7 +5,7 @@ use serde_with::{serde_as, Bytes}; use zksync_multivm::interface::{L1BatchEnv, SystemEnv}; use zksync_object_store::{_reexports::BoxedError, serialize_using_bincode, Bucket, StoredObject}; use zksync_types::{ - basic_fri_types::Eip4844Blobs, block::L2BlockExecutionData, + basic_fri_types::Eip4844Blobs, block::L2BlockExecutionData, commitment::PubdataParams, witness_block_state::WitnessStorageState, L1BatchNumber, ProtocolVersionId, H256, U256, }; @@ -269,6 +269,7 @@ pub struct V1TeeVerifierInput { pub l2_blocks_execution_data: Vec, pub l1_batch_env: L1BatchEnv, pub system_env: SystemEnv, + pub pubdata_params: PubdataParams, } impl V1TeeVerifierInput { @@ -278,6 +279,7 @@ impl V1TeeVerifierInput { l2_blocks_execution_data: Vec, l1_batch_env: L1BatchEnv, system_env: SystemEnv, + pubdata_params: PubdataParams, ) -> Self { V1TeeVerifierInput { vm_run_data, @@ -285,6 +287,7 @@ impl V1TeeVerifierInput { l2_blocks_execution_data, l1_batch_env, system_env, + pubdata_params, } } } diff --git a/core/lib/snapshots_applier/src/tests/utils.rs b/core/lib/snapshots_applier/src/tests/utils.rs index 2c9b1440af2a..cf68d2e181a6 100644 --- a/core/lib/snapshots_applier/src/tests/utils.rs +++ b/core/lib/snapshots_applier/src/tests/utils.rs @@ -182,6 +182,7 @@ pub(super) fn mock_l2_block_header(l2_block_number: L2BlockNumber) -> L2BlockHea virtual_blocks: 0, gas_limit: 0, logs_bloom: Default::default(), + pubdata_params: Default::default(), } } diff --git a/core/lib/state/src/test_utils.rs b/core/lib/state/src/test_utils.rs index decb2a0f403d..a12508f615f0 100644 --- a/core/lib/state/src/test_utils.rs +++ b/core/lib/state/src/test_utils.rs @@ -88,6 +88,7 @@ pub(crate) async fn create_l2_block( virtual_blocks: 0, gas_limit: 0, logs_bloom: Default::default(), + pubdata_params: Default::default(), }; conn.blocks_dal() diff --git a/core/lib/tee_verifier/src/lib.rs b/core/lib/tee_verifier/src/lib.rs index ffe3a548a02b..140085dbb9fe 100644 --- a/core/lib/tee_verifier/src/lib.rs +++ b/core/lib/tee_verifier/src/lib.rs @@ -15,6 +15,7 @@ use zksync_multivm::{ FinishedL1Batch, L2BlockEnv, VmFactory, VmInterface, VmInterfaceExt, VmInterfaceHistoryEnabled, }, + pubdata_builders::pubdata_params_to_builder, vm_latest::HistoryEnabled, LegacyVmInstance, }; @@ -22,7 +23,8 @@ use zksync_prover_interface::inputs::{ StorageLogMetadata, V1TeeVerifierInput, WitnessInputMerklePaths, }; use zksync_types::{ - block::L2BlockExecutionData, L1BatchNumber, StorageLog, StorageValue, Transaction, H256, + block::L2BlockExecutionData, commitment::PubdataParams, L1BatchNumber, StorageLog, + StorageValue, Transaction, H256, }; use zksync_utils::u256_to_h256; @@ -88,7 +90,7 @@ impl Verify for V1TeeVerifierInput { let storage_snapshot = StorageSnapshot::new(storage, factory_deps); let storage_view = StorageView::new(storage_snapshot).to_rc_ptr(); let vm = LegacyVmInstance::new(self.l1_batch_env, self.system_env, storage_view); - let vm_out = execute_vm(self.l2_blocks_execution_data, vm)?; + let vm_out = execute_vm(self.l2_blocks_execution_data, vm, self.pubdata_params)?; let block_output_with_proofs = get_bowp(self.merkle_paths)?; @@ -178,6 +180,7 @@ fn get_bowp(witness_input_merkle_paths: WitnessInputMerklePaths) -> Result( l2_blocks_execution_data: Vec, mut vm: LegacyVmInstance, + pubdata_params: PubdataParams, ) -> anyhow::Result { let next_l2_blocks_data = l2_blocks_execution_data.iter().skip(1); @@ -206,7 +209,7 @@ fn execute_vm( tracing::trace!("about to vm.finish_batch()"); - Ok(vm.finish_batch()) + Ok(vm.finish_batch(pubdata_params_to_builder(pubdata_params))) } /// Map `LogQuery` and `TreeLogEntry` to a `TreeInstruction` @@ -356,6 +359,7 @@ mod tests { default_validation_computational_gas_limit: 0, chain_id: Default::default(), }, + Default::default(), ); let tvi = TeeVerifierInput::new(tvi); let serialized = bincode::serialize(&tvi).expect("Failed to serialize TeeVerifierInput."); diff --git a/core/lib/types/src/api/en.rs b/core/lib/types/src/api/en.rs index 209ab7c24f98..daaa5651a032 100644 --- a/core/lib/types/src/api/en.rs +++ b/core/lib/types/src/api/en.rs @@ -1,7 +1,7 @@ //! API types related to the External Node specific methods. use serde::{Deserialize, Serialize}; -use zksync_basic_types::{Address, L1BatchNumber, L2BlockNumber, H256}; +use zksync_basic_types::{commitment::PubdataParams, Address, L1BatchNumber, L2BlockNumber, H256}; use zksync_contracts::BaseSystemContractsHashes; use crate::ProtocolVersionId; @@ -42,6 +42,8 @@ pub struct SyncBlock { pub hash: Option, /// Version of the protocol used for this block. pub protocol_version: ProtocolVersionId, + /// Pubdata params used for this batch + pub pubdata_params: Option, } /// Global configuration of the consensus served by the main node to the external nodes. diff --git a/core/lib/types/src/api/mod.rs b/core/lib/types/src/api/mod.rs index b8f8a2f05841..a4eb64605534 100644 --- a/core/lib/types/src/api/mod.rs +++ b/core/lib/types/src/api/mod.rs @@ -206,6 +206,7 @@ pub struct BridgeAddresses { pub l2_erc20_default_bridge: Option
, pub l1_weth_bridge: Option
, pub l2_weth_bridge: Option
, + pub l2_legacy_shared_bridge: Option
, } #[derive(Debug, Default, Clone, PartialEq, Serialize, Deserialize)] diff --git a/core/lib/types/src/block.rs b/core/lib/types/src/block.rs index 9211a6f1d8cf..310e3a73b8e8 100644 --- a/core/lib/types/src/block.rs +++ b/core/lib/types/src/block.rs @@ -1,7 +1,7 @@ use std::{fmt, ops}; use serde::{Deserialize, Serialize}; -use zksync_basic_types::{Address, Bloom, BloomInput, H256, U256}; +use zksync_basic_types::{commitment::PubdataParams, Address, Bloom, BloomInput, H256, U256}; use zksync_contracts::BaseSystemContractsHashes; use zksync_system_constants::SYSTEM_BLOCK_INFO_BLOCK_NUMBER_MULTIPLIER; use zksync_utils::concat_and_hash; @@ -113,6 +113,7 @@ pub struct L2BlockHeader { /// amount of gas can be spent on pubdata. pub gas_limit: u64, pub logs_bloom: Bloom, + pub pubdata_params: PubdataParams, } /// Structure that represents the data is returned by the storage oracle during batch execution. diff --git a/core/lib/types/src/commitment/mod.rs b/core/lib/types/src/commitment/mod.rs index 759ee8947ba9..40532a1e5899 100644 --- a/core/lib/types/src/commitment/mod.rs +++ b/core/lib/types/src/commitment/mod.rs @@ -9,11 +9,12 @@ use std::{collections::HashMap, convert::TryFrom}; use serde::{Deserialize, Serialize}; -pub use zksync_basic_types::commitment::L1BatchCommitmentMode; +pub use zksync_basic_types::commitment::{L1BatchCommitmentMode, PubdataParams}; use zksync_contracts::BaseSystemContractsHashes; +use zksync_crypto_primitives::hasher::{keccak::KeccakHasher, Hasher}; use zksync_mini_merkle_tree::MiniMerkleTree; use zksync_system_constants::{ - KNOWN_CODES_STORAGE_ADDRESS, L2_TO_L1_LOGS_TREE_ROOT_KEY, STATE_DIFF_HASH_KEY, + KNOWN_CODES_STORAGE_ADDRESS, L2_TO_L1_LOGS_TREE_ROOT_KEY, STATE_DIFF_HASH_KEY_PRE_GATEWAY, ZKPORTER_IS_AVAILABLE, }; use zksync_utils::u256_to_h256; @@ -22,8 +23,8 @@ use crate::{ blob::num_blobs_required, block::{L1BatchHeader, L1BatchTreeData}, l2_to_l1_log::{ - l2_to_l1_logs_tree_size, parse_system_logs_for_blob_hashes, L2ToL1Log, SystemL2ToL1Log, - UserL2ToL1Log, + l2_to_l1_logs_tree_size, parse_system_logs_for_blob_hashes_pre_gateway, L2ToL1Log, + SystemL2ToL1Log, UserL2ToL1Log, }, web3::keccak256, writes::{ @@ -92,6 +93,16 @@ pub struct L1BatchMetadata { /// commitment to the transactions in the batch. pub bootloader_initial_content_commitment: Option, pub state_diffs_compressed: Vec, + /// Hash of packed state diffs. It's present only for post-gateway batches. + pub state_diff_hash: Option, + /// Root hash of the local logs tree. Tree contains logs that were produced on this chain. + /// It's present only for post-gateway batches. + pub local_root: Option, + /// Root hash of the aggregated logs tree. Tree aggregates `local_root`s of chains that settle on this chain. + /// It's present only for post-gateway batches. + pub aggregation_root: Option, + /// Data Availability inclusion proof, that has to be verified on the settlement layer. + pub da_inclusion_data: Option>, } impl L1BatchMetadata { @@ -265,6 +276,13 @@ pub struct L1BatchAuxiliaryCommonOutput { protocol_version: ProtocolVersionId, } +#[derive(Debug, Default, Clone, Copy, Eq, PartialEq)] +#[cfg_attr(test, derive(Serialize, Deserialize))] +pub struct BlobHash { + pub commitment: H256, + pub linear_hash: H256, +} + /// Block Output produced by Virtual Machine #[derive(Debug, Clone, Eq, PartialEq)] #[cfg_attr(test, derive(Serialize, Deserialize))] @@ -283,8 +301,9 @@ pub enum L1BatchAuxiliaryOutput { state_diffs_compressed: Vec, state_diffs_hash: H256, aux_commitments: AuxCommitments, - blob_linear_hashes: Vec, - blob_commitments: Vec, + blob_hashes: Vec, + aggregation_root: H256, + local_root: H256, }, } @@ -333,17 +352,23 @@ impl L1BatchAuxiliaryOutput { system_logs, state_diffs, aux_commitments, - blob_commitments, + blob_hashes, + aggregation_root, } => { let l2_l1_logs_compressed = serialize_commitments(&common_input.l2_to_l1_logs); let merkle_tree_leaves = l2_l1_logs_compressed .chunks(UserL2ToL1Log::SERIALIZED_SIZE) .map(|chunk| <[u8; UserL2ToL1Log::SERIALIZED_SIZE]>::try_from(chunk).unwrap()); - let l2_l1_logs_merkle_root = MiniMerkleTree::new( + let local_root = MiniMerkleTree::new( merkle_tree_leaves, Some(l2_to_l1_logs_tree_size(common_input.protocol_version)), ) .merkle_root(); + let l2_l1_logs_merkle_root = if common_input.protocol_version.is_pre_gateway() { + local_root + } else { + KeccakHasher.compress(&local_root, &aggregation_root) + }; let common_output = L1BatchAuxiliaryCommonOutput { l2_l1_logs_merkle_root, @@ -357,22 +382,33 @@ impl L1BatchAuxiliaryOutput { let state_diffs_hash = H256::from(keccak256(&(state_diffs_packed))); let state_diffs_compressed = compress_state_diffs(state_diffs); - let blob_linear_hashes = - parse_system_logs_for_blob_hashes(&common_input.protocol_version, &system_logs); - // Sanity checks. System logs are empty for the genesis batch, so we can't do checks for it. if !system_logs.is_empty() { - let state_diff_hash_from_logs = system_logs - .iter() - .find_map(|log| { - (log.0.key == u256_to_h256(STATE_DIFF_HASH_KEY.into())) - .then_some(log.0.value) - }) - .expect("Failed to find state diff hash in system logs"); - assert_eq!( - state_diffs_hash, state_diff_hash_from_logs, - "State diff hash mismatch" - ); + if common_input.protocol_version.is_pre_gateway() { + let state_diff_hash_from_logs = system_logs + .iter() + .find_map(|log| { + (log.0.key == u256_to_h256(STATE_DIFF_HASH_KEY_PRE_GATEWAY.into())) + .then_some(log.0.value) + }) + .expect("Failed to find state diff hash in system logs"); + assert_eq!( + state_diffs_hash, state_diff_hash_from_logs, + "State diff hash mismatch" + ); + + let blob_linear_hashes_from_logs = + parse_system_logs_for_blob_hashes_pre_gateway( + &common_input.protocol_version, + &system_logs, + ); + let blob_linear_hashes: Vec<_> = + blob_hashes.iter().map(|b| b.linear_hash).collect(); + assert_eq!( + blob_linear_hashes, blob_linear_hashes_from_logs, + "Blob linear hashes mismatch" + ); + } let l2_to_l1_logs_tree_root_from_logs = system_logs .iter() @@ -387,25 +423,45 @@ impl L1BatchAuxiliaryOutput { ); } - assert_eq!( - blob_linear_hashes.len(), - blob_commitments.len(), - "Blob linear hashes and commitments have different lengths" - ); - Self::PostBoojum { common: common_output, system_logs_linear_hash, state_diffs_compressed, state_diffs_hash, aux_commitments, - blob_linear_hashes, - blob_commitments, + blob_hashes, + local_root, + aggregation_root, } } } } + pub fn local_root(&self) -> H256 { + match self { + Self::PreBoojum { common, .. } => common.l2_l1_logs_merkle_root, + Self::PostBoojum { local_root, .. } => *local_root, + } + } + + pub fn aggregation_root(&self) -> H256 { + match self { + Self::PreBoojum { .. } => H256::zero(), + Self::PostBoojum { + aggregation_root, .. + } => *aggregation_root, + } + } + + pub fn state_diff_hash(&self) -> H256 { + match self { + Self::PreBoojum { .. } => H256::zero(), + Self::PostBoojum { + state_diffs_hash, .. + } => *state_diffs_hash, + } + } + pub fn to_bytes(&self) -> Vec { let mut result = Vec::new(); @@ -426,8 +482,7 @@ impl L1BatchAuxiliaryOutput { system_logs_linear_hash, state_diffs_hash, aux_commitments, - blob_linear_hashes, - blob_commitments, + blob_hashes, .. } => { result.extend(system_logs_linear_hash.as_bytes()); @@ -439,9 +494,9 @@ impl L1BatchAuxiliaryOutput { ); result.extend(aux_commitments.events_queue_commitment.as_bytes()); - for i in 0..blob_commitments.len() { - result.extend(blob_linear_hashes[i].as_bytes()); - result.extend(blob_commitments[i].as_bytes()); + for b in blob_hashes { + result.extend(b.linear_hash.as_bytes()); + result.extend(b.commitment.as_bytes()); } } } @@ -637,6 +692,9 @@ impl L1BatchCommitment { aux_commitments: self.aux_commitments(), compressed_initial_writes, compressed_repeated_writes, + local_root: self.auxiliary_output.local_root(), + aggregation_root: self.auxiliary_output.aggregation_root(), + state_diff_hash: self.auxiliary_output.state_diff_hash(), } } } @@ -673,7 +731,8 @@ pub enum CommitmentInput { system_logs: Vec, state_diffs: Vec, aux_commitments: AuxCommitments, - blob_commitments: Vec, + blob_hashes: Vec, + aggregation_root: H256, }, } @@ -715,11 +774,11 @@ impl CommitmentInput { events_queue_commitment: H256::zero(), bootloader_initial_content_commitment: H256::zero(), }, - blob_commitments: { + blob_hashes: { let num_blobs = num_blobs_required(&protocol_version); - - vec![H256::zero(); num_blobs] + vec![Default::default(); num_blobs] }, + aggregation_root: H256::zero(), } } } @@ -734,4 +793,7 @@ pub struct L1BatchCommitmentArtifacts { pub compressed_repeated_writes: Option>, pub zkporter_is_available: bool, pub aux_commitments: Option, + pub aggregation_root: H256, + pub local_root: H256, + pub state_diff_hash: H256, } diff --git a/core/lib/types/src/commitment/tests/mod.rs b/core/lib/types/src/commitment/tests/mod.rs index 33fb0142b04d..a95318309a28 100644 --- a/core/lib/types/src/commitment/tests/mod.rs +++ b/core/lib/types/src/commitment/tests/mod.rs @@ -55,3 +55,8 @@ fn post_boojum_1_5_0() { fn post_boojum_1_5_0_with_evm() { run_test("post_boojum_1_5_0_test_with_evm"); } + +#[test] +fn post_gateway() { + run_test("post_gateway_test"); +} diff --git a/core/lib/types/src/commitment/tests/post_boojum_1_4_1_test.json b/core/lib/types/src/commitment/tests/post_boojum_1_4_1_test.json index c5eccbce038a..c854a6e77d8f 100644 --- a/core/lib/types/src/commitment/tests/post_boojum_1_4_1_test.json +++ b/core/lib/types/src/commitment/tests/post_boojum_1_4_1_test.json @@ -190,10 +190,17 @@ "events_queue_commitment": "0x6193a5098eb140796387bdf40700a3855eeb010474b5478f30bf917172c67883", "bootloader_initial_content_commitment": "0xf031b4491c37f20516c4ebf428f4765156409f67089e64772f4106fd2d9f3351" }, - "blob_commitments": [ - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000" - ] + "blob_hashes": [ + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000000", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000000", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + ], + "aggregation_root": "0x0000000000000000000000000000000000000000000000000000000000000000" } }, "pass_through_data": { @@ -248,14 +255,18 @@ "events_queue_commitment": "0x6193a5098eb140796387bdf40700a3855eeb010474b5478f30bf917172c67883", "bootloader_initial_content_commitment": "0xf031b4491c37f20516c4ebf428f4765156409f67089e64772f4106fd2d9f3351" }, - "blob_linear_hashes": [ - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000" + "blob_hashes": [ + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000000", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000000", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000000" + } ], - "blob_commitments": [ - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000" - ] + "aggregation_root": "0x0000000000000000000000000000000000000000000000000000000000000000", + "local_root": "0xe52d57bd64cabf6c588b30365512da2bf10912c106e7a06483b236d05ac4037e" } }, "hashes": { diff --git a/core/lib/types/src/commitment/tests/post_boojum_1_4_2_test.json b/core/lib/types/src/commitment/tests/post_boojum_1_4_2_test.json index 4983bbeca143..96aa8ab842ce 100644 --- a/core/lib/types/src/commitment/tests/post_boojum_1_4_2_test.json +++ b/core/lib/types/src/commitment/tests/post_boojum_1_4_2_test.json @@ -206,10 +206,17 @@ "events_queue_commitment": "0x6193a5098eb140796387bdf40700a3855eeb010474b5478f30bf917172c67883", "bootloader_initial_content_commitment": "0xf031b4491c37f20516c4ebf428f4765156409f67089e64772f4106fd2d9f3351" }, - "blob_commitments": [ - "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x0000000000000000000000000000000000000000000000000000000000000002" - ] + "blob_hashes": [ + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000001", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000003" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000002", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000004" + } + ], + "aggregation_root": "0x0000000000000000000000000000000000000000000000000000000000000000" } }, "pass_through_data": { @@ -264,14 +271,18 @@ "events_queue_commitment": "0x6193a5098eb140796387bdf40700a3855eeb010474b5478f30bf917172c67883", "bootloader_initial_content_commitment": "0xf031b4491c37f20516c4ebf428f4765156409f67089e64772f4106fd2d9f3351" }, - "blob_linear_hashes": [ - "0x0000000000000000000000000000000000000000000000000000000000000003", - "0x0000000000000000000000000000000000000000000000000000000000000004" + "blob_hashes": [ + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000001", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000003" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000002", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000004" + } ], - "blob_commitments": [ - "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x0000000000000000000000000000000000000000000000000000000000000002" - ] + "aggregation_root": "0x0000000000000000000000000000000000000000000000000000000000000000", + "local_root": "0x0b6e1ad4643cc2bee06b5e173184ec822d80826e5720f5715172898350433299" } }, "hashes": { diff --git a/core/lib/types/src/commitment/tests/post_boojum_1_5_0_test.json b/core/lib/types/src/commitment/tests/post_boojum_1_5_0_test.json index 59a24b7c90ce..ed61ea67cefc 100644 --- a/core/lib/types/src/commitment/tests/post_boojum_1_5_0_test.json +++ b/core/lib/types/src/commitment/tests/post_boojum_1_5_0_test.json @@ -238,24 +238,73 @@ "events_queue_commitment": "0x6193a5098eb140796387bdf40700a3855eeb010474b5478f30bf917172c67883", "bootloader_initial_content_commitment": "0xf031b4491c37f20516c4ebf428f4765156409f67089e64772f4106fd2d9f3351" }, - "blob_commitments": [ - "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x0000000000000000000000000000000000000000000000000000000000000002", - "0x0000000000000000000000000000000000000000000000000000000000000003", - "0x0000000000000000000000000000000000000000000000000000000000000004", - "0x0000000000000000000000000000000000000000000000000000000000000005", - "0x0000000000000000000000000000000000000000000000000000000000000006", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000" - ] + "blob_hashes": [ + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000001", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000003" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000002", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000004" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000003", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000005" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000004", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000006" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000005", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000007" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000006", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000008" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000000", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000000", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000000", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000000", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000000", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000000", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000000", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000000", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000000", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000000", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + ], + "aggregation_root": "0x0000000000000000000000000000000000000000000000000000000000000000" } }, "pass_through_data": { @@ -310,42 +359,74 @@ "events_queue_commitment": "0x6193a5098eb140796387bdf40700a3855eeb010474b5478f30bf917172c67883", "bootloader_initial_content_commitment": "0xf031b4491c37f20516c4ebf428f4765156409f67089e64772f4106fd2d9f3351" }, - "blob_linear_hashes": [ - "0x0000000000000000000000000000000000000000000000000000000000000003", - "0x0000000000000000000000000000000000000000000000000000000000000004", - "0x0000000000000000000000000000000000000000000000000000000000000005", - "0x0000000000000000000000000000000000000000000000000000000000000006", - "0x0000000000000000000000000000000000000000000000000000000000000007", - "0x0000000000000000000000000000000000000000000000000000000000000008", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000" + "blob_hashes": [ + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000001", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000003" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000002", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000004" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000003", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000005" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000004", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000006" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000005", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000007" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000006", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000008" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000000", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000000", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000000", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000000", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000000", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000000", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000000", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000000", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000000", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000000", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000000" + } ], - "blob_commitments": [ - "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x0000000000000000000000000000000000000000000000000000000000000002", - "0x0000000000000000000000000000000000000000000000000000000000000003", - "0x0000000000000000000000000000000000000000000000000000000000000004", - "0x0000000000000000000000000000000000000000000000000000000000000005", - "0x0000000000000000000000000000000000000000000000000000000000000006", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000" - ] + "aggregation_root": "0x0000000000000000000000000000000000000000000000000000000000000000", + "local_root": "0x30ba728b1aac22b122de4f32589dd2711da264412cb90e35bf7b1f735dd357ff" } }, "hashes": { diff --git a/core/lib/types/src/commitment/tests/post_boojum_1_5_0_test_with_evm.json b/core/lib/types/src/commitment/tests/post_boojum_1_5_0_test_with_evm.json index 4e8c0e0814a0..a41aa33c04a1 100644 --- a/core/lib/types/src/commitment/tests/post_boojum_1_5_0_test_with_evm.json +++ b/core/lib/types/src/commitment/tests/post_boojum_1_5_0_test_with_evm.json @@ -239,24 +239,73 @@ "events_queue_commitment": "0x6193a5098eb140796387bdf40700a3855eeb010474b5478f30bf917172c67883", "bootloader_initial_content_commitment": "0xf031b4491c37f20516c4ebf428f4765156409f67089e64772f4106fd2d9f3351" }, - "blob_commitments": [ - "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x0000000000000000000000000000000000000000000000000000000000000002", - "0x0000000000000000000000000000000000000000000000000000000000000003", - "0x0000000000000000000000000000000000000000000000000000000000000004", - "0x0000000000000000000000000000000000000000000000000000000000000005", - "0x0000000000000000000000000000000000000000000000000000000000000006", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000" - ] + "blob_hashes": [ + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000001", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000003" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000002", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000004" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000003", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000005" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000004", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000006" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000005", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000007" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000006", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000008" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000000", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000000", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000000", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000000", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000000", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000000", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000000", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000000", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000000", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000000", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + ], + "aggregation_root": "0x0000000000000000000000000000000000000000000000000000000000000000" } }, "pass_through_data": { @@ -312,42 +361,74 @@ "events_queue_commitment": "0x6193a5098eb140796387bdf40700a3855eeb010474b5478f30bf917172c67883", "bootloader_initial_content_commitment": "0xf031b4491c37f20516c4ebf428f4765156409f67089e64772f4106fd2d9f3351" }, - "blob_linear_hashes": [ - "0x0000000000000000000000000000000000000000000000000000000000000003", - "0x0000000000000000000000000000000000000000000000000000000000000004", - "0x0000000000000000000000000000000000000000000000000000000000000005", - "0x0000000000000000000000000000000000000000000000000000000000000006", - "0x0000000000000000000000000000000000000000000000000000000000000007", - "0x0000000000000000000000000000000000000000000000000000000000000008", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000" + "blob_hashes": [ + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000001", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000003" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000002", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000004" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000003", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000005" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000004", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000006" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000005", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000007" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000006", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000008" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000000", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000000", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000000", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000000", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000000", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000000", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000000", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000000", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000000", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000000", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000000" + } ], - "blob_commitments": [ - "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x0000000000000000000000000000000000000000000000000000000000000002", - "0x0000000000000000000000000000000000000000000000000000000000000003", - "0x0000000000000000000000000000000000000000000000000000000000000004", - "0x0000000000000000000000000000000000000000000000000000000000000005", - "0x0000000000000000000000000000000000000000000000000000000000000006", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000" - ] + "aggregation_root": "0x0000000000000000000000000000000000000000000000000000000000000000", + "local_root": "0x30ba728b1aac22b122de4f32589dd2711da264412cb90e35bf7b1f735dd357ff" } }, "hashes": { diff --git a/core/lib/types/src/commitment/tests/post_gateway_test.json b/core/lib/types/src/commitment/tests/post_gateway_test.json new file mode 100644 index 000000000000..4b598ff59f4f --- /dev/null +++ b/core/lib/types/src/commitment/tests/post_gateway_test.json @@ -0,0 +1,1977 @@ +{ + "hashes": { + "pass_through_data": "0x756c1660f611302295f6a56a8f4b9d68f2ebf51f8278f225d6b7e64bb9364be0", + "aux_output": "0xcccf1ef8192054cb1b5fb668868ce4e069a695a1394b9486ebd3031cec12fe12", + "meta_parameters": "0xdb298fa55c75b134333cee0b39f77aea956553a1eb861a5777dc7a66ad7a55b9", + "commitment": "0xd6615c5447c817a320c69c6a5af12c472fd4d5bc2ef4de7806d40afe384ddc27" + }, + "auxiliary_output": { + "PostBoojum": { + "common": { + "l2_l1_logs_merkle_root": "0x38eaeef3afe69b6f6b2fa22c92da8137f1e405a1e1861b7de7cfa30c7d7462dd", + "protocol_version": "Version27" + }, + "system_logs_linear_hash": "0xe8460ce1ed47b77cfee3cadf803aa089c144c506ea2bdd358a6a38ff2c7bc8e3", + "state_diffs_compressed": [ + 1,0,27,89,4,0,148,112,120,89,162,183,230,11,175,17,100,223,232,175,83,47,195,198,157,29,129,145,197,186,61,127,17,109,250,141,181,206,45,0,1,0,1,67,6,51,197,115,134,143,51,94,49,6,252,85,139,173,197,6,118,46,184,24,78,249,206,120,93,239,110,206,130,208,215,121,46,249,196,126,160,123,216,26,86,45,8,246,35,74,8,171,141,141,223,145,137,150,142,180,236,158,154,37,0,1,0,14,207,174,184,55,189,9,139,207,155,222,111,194,204,216,232,169,53,90,27,112,230,1,172,24,205,8,158,179,8,246,11,47,22,184,171,230,29,125,57,179,213,44,191,157,128,184,167,253,5,55,217,60,33,8,75,147,188,5,4,171,60,0,1,0,0,195,40,243,40,221,130,10,29,214,152,4,122,127,125,73,135,77,130,89,25,110,39,53,23,67,10,248,244,128,203,204,98,199,195,136,172,152,215,47,208,131,209,215,32,206,186,255,203,162,198,108,114,94,200,185,197,197,240,116,111,138,0,1,0,0,91,142,88,121,116,4,61,89,191,251,246,50,208,32,231,100,149,154,190,98,228,194,56,216,223,46,98,178,181,235,143,74,199,189,78,241,151,159,154,102,86,114,178,92,208,123,30,61,99,122,89,162,199,107,26,34,232,91,117,146,65,0,1,0,1,67,6,51,197,115,134,143,51,94,49,6,252,85,139,173,197,6,118,46,184,24,78,249,206,120,93,239,110,206,66,202,106,148,168,163,117,186,10,227,150,70,185,29,164,88,23,175,73,33,116,119,174,107,73,193,3,53,191,78,11,115,0,1,0,1,179,126,95,140,175,172,146,75,62,102,55,121,225,44,128,218,206,138,2,177,210,115,174,112,143,39,90,214,42,71,164,52,102,233,54,181,135,193,191,158,16,243,13,105,123,17,66,228,89,233,6,51,219,18,27,114,127,245,180,121,43,0,1,0,0,103,85,79,83,198,102,14,83,189,151,41,240,10,238,1,137,1,13,254,184,104,250,60,189,72,18,50,72,12,95,233,138,250,154,14,193,124,34,99,2,123,232,159,70,229,238,83,58,30,33,169,31,255,76,177,68,204,74,239,33,188,0,1,0,5,181,151,235,2,5,139,35,12,238,106,156,223,71,5,65,13,21,26,209,234,106,211,226,222,119,132,26,207,194,142,107,134,4,159,177,116,20,22,26,103,250,177,44,27,34,144,68,85,154,16,112,202,176,23,66,216,18,18,139,156,190,0,1,0,0,103,85,79,83,198,102,14,83,189,151,41,240,10,238,1,137,1,13,254,184,104,250,60,189,72,18,50,72,12,140,78,248,13,214,150,89,51,34,40,248,136,164,249,180,131,12,12,50,27,140,170,45,67,53,35,250,200,97,150,181,207,0,1,0,4,139,241,177,101,244,200,80,208,30,184,30,92,4,15,112,234,1,220,160,25,231,128,168,127,128,236,120,151,195,235,96,109,232,32,223,19,108,89,177,255,121,225,223,146,96,66,108,164,143,175,146,74,70,53,36,33,31,183,195,161,165,0,1,0,2,1,233,35,243,228,122,223,167,196,240,246,30,168,221,66,86,246,109,16,153,151,11,205,49,72,146,134,73,23,95,127,60,252,81,90,137,254,204,8,97,6,46,254,57,252,48,104,36,27,116,128,26,163,170,147,245,100,172,98,242,54,0,1,0,6,29,196,13,11,194,203,129,144,94,107,193,66,30,189,75,216,183,154,172,184,218,79,157,113,69,178,136,103,79,207,14,96,187,125,119,111,198,230,184,241,1,19,161,190,119,25,192,44,34,151,163,108,216,124,11,59,35,121,140,74,95,0,1,0,7,15,28,212,226,131,6,7,175,48,25,39,67,145,15,223,171,241,221,0,74,128,115,148,66,117,129,157,29,254,53,89,195,90,167,22,152,246,194,202,70,67,239,232,80,69,169,73,79,38,45,119,238,103,193,61,215,52,230,38,48,90,0,1,0,1,67,6,51,197,115,134,143,51,94,49,6,252,85,139,173,197,6,118,46,184,24,78,249,206,120,93,239,110,206,186,93,97,46,65,80,43,253,205,126,211,179,176,210,212,177,245,200,248,185,15,209,21,42,187,224,222,192,14,162,61,7,0,1,0,4,139,241,177,101,244,200,80,208,30,184,30,92,4,15,112,234,1,220,160,25,231,128,168,127,128,236,120,151,195,44,61,141,160,220,54,28,84,148,218,146,175,212,98,94,116,25,190,241,121,131,189,209,145,214,33,89,62,212,173,57,47,0,1,0,3,35,183,38,99,20,185,211,236,56,125,91,205,149,144,165,11,224,14,120,136,55,202,90,136,13,151,227,238,131,48,100,113,86,255,138,164,229,100,8,99,14,34,251,194,115,119,250,250,242,7,188,204,248,210,254,18,115,9,165,229,233,0,1,0,2,21,205,111,48,109,117,125,93,47,219,180,96,198,15,41,133,132,23,158,236,192,113,150,199,174,142,79,141,100,200,51,40,178,38,74,180,112,167,221,220,163,38,200,255,61,159,78,76,252,60,226,78,168,221,216,201,180,12,20,188,185,0,1,0,2,1,233,35,243,228,122,223,167,196,240,246,30,168,221,66,86,246,109,16,153,151,11,205,49,72,146,134,73,23,229,176,77,5,169,51,88,54,33,49,122,209,137,227,159,45,116,33,7,146,238,29,46,153,91,171,175,162,128,71,14,27,0,1,0,1,83,6,251,15,11,95,222,33,153,150,85,28,128,114,198,113,27,186,83,0,178,102,154,235,15,14,76,116,69,250,253,202,115,87,157,171,40,23,48,73,193,157,78,81,69,162,232,29,120,68,42,125,135,121,254,156,149,143,198,173,119,0,1,0,0,53,186,49,237,22,194,17,96,120,10,192,151,99,191,213,147,177,116,143,105,230,131,169,251,16,146,26,164,157,188,67,139,78,87,51,241,113,6,164,3,59,144,48,243,76,127,49,1,147,79,102,218,253,36,37,149,91,92,247,35,64,0,1,0,0,237,48,107,41,18,142,6,90,253,206,115,235,200,224,236,208,140,217,24,253,192,247,76,3,246,77,81,94,72,6,115,118,133,155,130,106,66,115,187,68,69,230,28,222,77,91,95,90,23,4,86,255,161,95,247,195,108,233,152,241,190,0,1,0,1,63,74,44,150,76,113,212,159,45,136,118,161,30,238,75,244,232,209,146,49,101,47,199,117,178,202,228,58,33,129,4,114,76,225,212,61,128,125,223,69,48,213,107,167,249,183,181,194,21,67,99,215,247,166,215,108,189,158,61,249,130,0,1,0,0,103,33,171,145,26,65,216,181,37,2,234,76,223,66,236,153,229,229,41,190,106,62,102,243,173,178,20,60,90,51,232,118,240,225,158,242,19,13,216,95,254,79,35,196,212,101,148,164,24,219,221,10,181,111,253,164,76,93,72,246,206,0,1,0,5,187,116,113,160,1,107,28,51,15,118,122,94,115,173,12,51,9,52,105,76,173,0,124,90,163,249,38,190,101,25,143,99,94,50,239,35,14,215,12,184,219,25,32,81,51,246,142,27,126,246,157,133,33,13,119,172,197,111,163,43,234,0,1,0,5,21,101,126,190,1,77,145,81,72,7,18,222,122,16,141,155,14,26,122,121,141,61,162,148,91,165,60,209,3,90,251,120,52,143,255,91,253,53,60,239,129,160,65,213,230,214,195,241,114,123,145,145,220,232,75,132,91,7,118,101,237,0,1,0,6,49,18,87,196,3,187,186,126,42,239,10,162,8,34,98,124,130,236,116,132,252,179,27,135,221,140,88,42,169,240,163,222,200,2,37,101,9,35,172,42,74,77,142,96,167,8,137,208,171,61,234,142,107,218,41,37,203,138,127,216,252,137,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,174,229,34,198,20,187,1,37,21,66,226,45,128,16,30,45,151,85,103,77,143,214,69,38,254,154,44,77,223,171,97,143,137,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,159,186,133,75,226,253,235,173,50,111,19,111,136,219,244,177,114,214,77,28,237,51,180,171,99,164,148,28,226,73,151,137,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,201,172,113,10,243,67,127,194,244,249,48,131,50,164,72,10,88,81,76,45,149,28,73,119,114,174,142,141,132,8,175,27,137,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,182,81,125,81,147,30,201,86,98,178,2,213,133,189,82,214,234,207,27,118,113,82,28,46,150,32,45,104,62,223,226,99,137,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,28,170,140,159,117,250,84,163,177,210,240,18,225,217,234,99,118,79,112,157,28,25,151,121,72,28,143,77,92,237,107,62,9,1,45,86,211,71,72,250,222,240,196,161,223,115,65,15,173,85,177,255,211,89,90,168,146,255,238,205,12,128,137,196,203,27,9,1,12,138,2,247,115,213,230,144,244,253,93,195,182,20,84,243,71,244,71,24,244,103,128,231,65,233,198,173,128,126,246,169,9,1,185,67,192,97,81,170,106,240,157,23,26,106,216,228,65,120,68,165,135,110,2,31,216,158,187,67,79,105,151,157,234,15,9,1,12,91,247,177,168,165,63,93,186,29,121,106,121,167,27,50,198,22,230,125,252,159,77,132,92,155,115,251,100,87,112,147,9,1,127,216,219,101,110,162,74,65,114,24,131,123,143,204,15,44,36,72,8,136,170,255,39,231,108,143,128,71,65,95,117,4,9,1,4,27,221,133,245,254,194,84,195,88,19,141,109,233,58,225,116,116,251,225,170,44,159,23,28,181,85,238,6,151,63,144,9,1,130,114,163,11,234,79,36,77,175,198,107,147,58,183,234,134,122,178,61,205,225,34,184,146,138,50,221,70,198,19,2,191,9,1,41,151,245,131,127,195,211,240,254,148,60,106,169,97,173,173,118,116,195,243,213,115,169,17,155,83,25,181,108,68,48,51,9,1,236,254,112,114,24,207,172,186,132,163,119,198,20,66,226,51,51,142,39,212,88,198,68,118,92,136,138,204,26,155,11,165,9,1,215,116,3,65,140,246,136,209,81,15,184,214,188,49,94,63,81,57,12,135,108,143,41,137,113,88,11,84,15,30,158,184,9,1,50,203,140,60,152,140,103,117,103,130,42,29,70,236,110,49,211,18,247,40,117,35,54,107,171,190,233,18,117,69,68,43,9,1,95,50,92,228,81,22,16,190,182,42,66,158,131,165,204,25,25,20,143,210,29,170,143,129,94,111,129,132,227,28,102,180,9,1,96,153,155,64,152,142,147,161,102,88,190,194,238,147,14,243,71,26,33,184,193,50,249,29,88,2,52,157,179,7,69,77,9,1,212,255,51,143,196,70,53,156,98,221,171,235,82,21,252,198,242,28,2,246,195,67,6,91,2,240,95,173,200,49,66,89,9,1,58,212,15,123,117,242,193,79,217,63,177,112,56,232,153,140,93,188,111,168,108,138,82,113,212,107,209,150,246,205,191,157,9,1,204,180,39,152,129,136,139,125,156,240,127,28,205,2,65,12,140,132,177,76,5,4,95,204,205,9,179,77,57,148,6,231,9,1,249,145,142,225,129,214,86,160,12,71,51,28,109,238,246,115,57,184,6,234,138,46,107,81,103,128,201,242,101,51,179,68,9,1,17,109,102,169,143,117,42,93,149,160,20,188,122,34,0,140,248,73,206,232,146,65,183,250,61,35,40,54,167,63,173,215,9,1,58,197,183,31,149,121,187,250,193,140,202,222,69,149,235,105,78,113,59,213,78,241,15,40,62,137,46,19,193,78,85,31,9,1,209,81,122,212,165,252,102,254,115,58,127,209,26,21,188,113,69,3,30,255,154,72,181,219,97,7,227,96,209,19,138,181,9,1,151,245,134,14,100,30,161,175,227,142,158,71,197,157,213,103,198,28,241,51,173,107,242,84,76,53,176,101,132,26,29,60,9,1,72,239,59,253,40,148,227,213,236,98,100,14,198,212,71,148,180,209,64,152,228,196,11,209,109,231,183,97,135,156,172,241,9,1,205,107,120,198,53,118,206,64,8,204,37,15,58,43,95,189,38,38,203,212,73,105,50,160,21,160,38,124,10,233,46,22,17,1,14,204,0,103,138,56,182,245,161,43,137,56,202,232,138,228,30,242,80,214,237,253,8,17,251,148,203,85,106,127,162,114,20,161,98,175,120,161,168,109,95,168,170,123,117,238,24,132,211,108,163,195,25,58,89,16,198,41,13,94,89,2,119,169,28,80,179,104,66,21,38,252,16,146,163,159,122,68,234,161,165,150,251,139,57,4,0,82,244,49,170,53,221,128,152,46,60,102,97,65,18,80,60,162,198,227,68,116,95,74,43,207,201,189,126,9,199,85,132,67,87,214,19,120,116,147,47,78,236,178,95,23,23,1,171,197,181,63,197,52,162,224,221,93,223,35,243,248,138,100,215,25,1,0,2,94,249,142,243,210,28,27,218,191,10,139,245,66,107,2,111,153,125,18,238,76,249,208,69,34,173,165,21,177,18,82,239,17,1,14,217,248,73,34,237,151,158,186,178,226,225,234,58,186,218,7,175,174,60,185,248,248,25,28,51,154,61,168,213,77,242,169,0,82,244,49,170,53,221,128,152,46,60,102,97,65,18,80,60,162,198,227,68,116,95,74,43,207,201,189,126,9,199,85,132,194,179,227,24,162,84,191,59,100,89,207,244,98,199,135,44,91,35,210,22,182,249,66,219,89,32,250,61,112,54,16,141,161,98,175,120,161,168,109,95,168,170,123,117,238,24,132,211,108,163,195,25,58,60,170,232,127,53,17,58,173,142,247,89,247,207,149,119,134,64,14,158,82,18,231,188,179,163,89,11,174,81,43,46,153,9,9,132,119,216,135,171,185,255,65,210,32,46,77,152,229,32,71,244,141,39,140,188,245,22,25,184,28,198,202,132,222,174,160,25,1,0,2,119,228,107,44,53,217,61,182,86,125,189,169,81,109,32,249,139,212,234,72,144,24,135,118,89,121,216,219,24,207,66,168,17,1,14,213,5,71,76,80,42,16,77,105,27,101,50,79,76,38,232,167,55,134,79,128,251,113,33,35,116,77,254,28,6,176,0,0,82,244,49,170,53,221,128,152,46,60,102,97,65,18,80,60,162,198,227,68,116,95,74,43,207,201,189,126,9,199,85,132,110,177,116,132,158,116,7,177,77,240,138,82,212,212,241,43,54,8,1,75,42,104,243,5,241,73,226,60,72,169,2,41,25,1,0,3,73,127,150,33,212,30,131,171,90,28,221,170,53,22,176,210,81,154,146,160,81,67,188,184,7,13,240,169,97,51,230,181,9,100,71,111,167,179,223,229,107,45,223,184,100,207,103,16,106,234,217,25,120,51,156,12,142,28,186,4,134,110,182,28,191,11,9,9,62,169,255,238,205,94,99,210,162,31,213,85,158,233,223,231,174,18,241,77,26,133,255,75,40,190,65,163,26,48,53,196,25,1,0,2,232,83,248,233,232,89,11,170,74,117,125,224,222,189,198,137,244,49,205,228,155,200,97,42,160,89,8,63,109,25,91,168,9,9,255,134,239,235,78,5,0,110,98,20,109,14,192,231,250,72,49,145,191,114,177,51,38,242,67,121,217,71,114,50,124,171,9,9,209,167,69,145,2,139,203,92,187,46,4,30,218,0,85,77,176,3,253,201,73,229,148,92,229,57,32,59,244,12,109,96,9,9,113,233,23,33,249,145,133,118,215,96,240,47,3,202,196,124,111,64,3,49,96,49,132,142,60,29,153,230,232,58,71,67,65,14,41,230,74,233,195,128,0,49,87,111,239,58,195,179,2,237,163,15,66,168,74,199,52,200,236,175,1,55,3,126,248,127,239,193,246,133,27,151,79,57,134,3,21,27,16,164,160,185,211,150,83,253,116,26,253,56,22,83,204,70,30,122,203,221,134,84,251,39,141,138,17,246,159,212,31,236,239,75,201,65,5,60,24,80,250,182,152,192,250,91,168,183,69,6,78,180,185,147,215,10,134,34,96,243,26,77,158,213,121,211,188,200,73,204,177,205,8,52,178,106,57,74,136,235,186,254,43,32,141,97,126,192,90,203,191,95,226,69,41,166,75,35,133,169,106,173,67,240,155,225,173,169,44,112,64,49,220,193,72,27,65,8,29,65,249,24,254,23,128,162,84,32,193,217,215,5,53,140,19,76,198,1,217,209,132,203,77,253,222,126,28,172,43,195,212,211,139,249,236,68,230,33,5,245,225,0,18,59,175,197,134,247,119,100,72,140,210,76,106,119,84,110,90,15,232,189,251,79,162,3,207,175,252,54,204,228,221,91,137,1,0,0,0,0,0,0,0,0,0,0,0,0,102,252,2,65,142,125,208,106,197,183,59,71,59,230,188,90,81,3,15,76,116,55,101,124,183,178,155,243,118,197,100,184,209,103,90,94,137,2,0,0,0,0,0,0,0,0,0,0,0,0,102,252,2,66,75,168,78,31,55,208,65,188,110,85,186,57,104,38,204,73,78,132,212,129,91,109,181,38,144,66,46,234,115,134,49,79,0,232,231,118,38,88,111,115,185,85,54,76,123,75,191,11,183,247,104,94,189,64,232,82,177,100,99,58,74,203,211,36,76,61,226,32,44,203,98,106,211,135,215,7,34,230,79,190,68,86,46,47,35,26,41,12,8,83,43,141,106,186,64,47,245,0,242,170,235,6,192,229,86,67,74,201,60,35,47,55,221,139,224,167,191,159,67,15,118,235,86,77,249,252,183,112,196,95,121,9,53,136,208,232,71,239,167,58,16,206,32,228,121,159,177,228,102,66,214,86,23,199,229,33,63,160,73,137,217,45,137,2,0,0,0,0,0,0,0,0,0,0,0,0,102,252,2,66,135,222,210,71,225,102,15,130,112,113,199,241,55,25,52,88,151,81,8,83,132,252,159,68,98,193,241,137,124,92,62,239,137,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,134,36,129,147,235,77,210,168,206,129,95,135,108,18,77,72,53,149,34,240,133,77,149,216,7,46,175,240,211,125,85,189,17,3,32,62,137,13,108,44,59,173,166,238,204,150,3,169,156,28,98,89,237,90,100,2,241,199,108,193,139,86,140,58,239,186,15,17,34,169,145,29,210,173,116,63,242,55,212,17,100,138,15,227,44,109,116,238,192,96,113,106,42,116,53,47,107,28,67,91,93,103,0,249,3,11,120,197,191,90,201,151,167,105,98,170,50,201,10,109,142,142,188,233,131,140,142,235,56,141,115,225,247,101,154,214,116,246,54,163,90,111,26,81,86,78,195,55,27,156,77,163,18,109,90,208,186,227,80,207,199,250,234,199,99,99,184,9,255,104,98,246,102,108,85,7,252,51,21,214,132,35,158,2,38,112,107,69,195,65,114,145,245,183,172,194,211,57,80,82,17,161,138,214,89,21,244,44,6,173,6,242,62,51,254,238,79,87,6,12,210,73,180,68,244,119,54,206,136,162,78,107,80,251,5,29,192,174,93,179,175,68,217,8,246,220,217,160,21,208,74,126,225,227,25,1,0,3,59,172,224,22,174,10,65,231,169,237,9,168,91,33,85,109,38,187,242,242,75,76,32,165,75,187,165,27,95,83,162,158,25,1,0,5,237,36,132,158,202,168,131,171,106,32,214,79,172,224,148,150,15,71,73,102,217,162,19,183,2,117,192,112,196,76,181,34,161,61,185,77,114,162,95,100,135,66,67,175,119,110,6,244,73,213,91,169,221,83,157,81,206,111,89,151,62,178,167,63,16,226,11,189,169,125,149,14,110,8,62,221,87,116,233,142,217,139,253,153,16,9,1,186,154,222,88,248,170,108,168,43,242,42,43,72,15,245,221,236,232,166,232,99,81,164,123,16,213,143,51,128,251,219,183,9,1,103,185,128,156,225,233,200,126,96,129,32,179,163,131,84,200,153,155,236,34,245,43,19,243,165,109,226,10,22,113,50,131,9,1,203,224,11,159,230,121,179,34,119,46,123,13,250,7,202,214,183,18,124,144,172,158,237,255,172,53,228,144,236,81,142,168,161,44,60,95,185,9,118,123,106,246,85,186,215,47,93,102,56,245,245,208,160,183,144,135,107,116,64,90,68,61,138,52,178,244,96,20,237,96,5,52,90,158,129,172,204,39,175,55,18,74,73,29,222,9,255,36,49,6,86,93,12,79,206,248,151,94,121,177,178,35,12,1,159,78,58,178,122,63,78,124,169,48,107,159,98,153,132,161,138,214,89,21,244,44,6,173,6,242,62,51,254,238,79,87,6,12,210,73,208,111,9,167,39,114,89,78,179,210,171,35,115,181,211,197,236,176,132,184,74,77,237,45,48,18,241,69,222,221,138,25,161,93,224,137,41,163,192,131,82,50,167,205,32,29,51,131,23,202,171,216,115,199,117,193,115,55,85,171,245,34,173,219,214,151,226,215,10,91,97,70,75,209,104,27,41,137,81,196,246,13,142,199,12,25,1,0,4,113,24,36,136,41,22,138,100,28,59,149,105,31,231,215,27,33,193,211,238,215,254,44,202,236,107,125,180,46,38,146,200,25,1,0,2,38,182,122,48,1,162,205,218,95,52,172,146,222,81,199,193,42,178,228,105,133,88,214,83,137,237,66,230,119,250,5,85,9,255,253,39,5,238,88,207,60,229,238,92,28,224,63,70,109,126,152,54,188,71,18,186,162,153,21,61,132,71,202,121,113,207,161,138,214,89,21,244,44,6,173,6,242,62,51,254,238,79,87,6,12,210,73,191,14,175,103,174,227,73,235,177,89,118,163,111,237,172,26,74,6,101,80,58,211,113,127,243,254,106,224,120,179,101,156,161,76,72,189,176,20,90,137,189,135,248,136,79,63,168,193,228,45,88,94,117,184,2,226,247,10,56,240,40,136,100,146,139,246,198,195,194,209,164,217,45,202,10,147,86,175,254,198,249,92,64,121,164,0,1,0,0,253,83,6,143,195,92,106,35,254,224,103,188,253,63,192,216,128,186,79,121,216,182,90,175,191,240,47,48,93,168,74,2,141,105,206,208,33,164,189,140,91,38,36,168,242,80,217,18,184,248,245,157,129,85,249,94,94,229,138,101,38,9,1,47,241,202,110,153,206,246,252,92,214,119,95,159,94,245,61,243,40,240,8,26,143,180,81,247,55,255,244,73,12,229,83,9,1,95,192,113,95,216,242,21,235,124,16,227,245,80,217,178,9,241,140,170,135,64,175,84,27,211,70,239,73,100,139,20,245,9,1,201,169,20,123,206,251,168,141,33,64,175,106,246,185,19,185,53,101,125,53,5,87,5,184,7,21,91,61,208,130,42,131,9,1,183,44,52,109,222,204,99,77,172,182,15,29,40,214,131,168,39,33,227,213,36,163,61,162,168,47,3,62,136,241,101,126,9,1,133,79,165,174,6,191,41,30,209,5,109,104,28,93,197,246,247,13,23,242,234,3,204,110,233,229,198,255,131,62,203,105,0,9,36,146,140,19,119,166,207,36,195,156,45,70,248,235,157,242,62,129,27,38,220,53,39,229,72,57,111,212,225,115,177,211,102,235,93,180,24,37,200,29,129,191,72,73,93,114,116,50,181,244,253,225,248,223,46,101,251,180,223,113,77,242,139,0,70,112,11,77,64,172,92,53,175,44,34,221,162,120,122,145,235,86,123,6,201,36,168,251,138,233,160,91,32,192,140,33,228,96,52,194,207,181,181,131,126,57,95,233,204,152,190,4,82,34,235,53,200,202,40,109,252,73,189,213,239,94,126,130,9,1,27,8,240,147,212,200,27,37,231,124,191,110,45,189,91,214,149,171,253,138,221,47,115,230,14,214,92,143,87,109,114,128,17,1,249,248,63,134,138,17,62,7,250,227,100,52,50,139,214,30,153,110,204,16,117,222,9,119,59,220,202,187,15,30,237,162,217,9,1,207,50,50,89,38,214,97,46,146,127,167,239,70,37,230,216,37,111,63,130,63,184,65,242,102,240,65,120,90,218,241,226,9,1,247,124,190,104,95,142,126,239,68,219,69,165,161,237,129,135,165,5,236,239,227,84,140,240,18,4,129,67,95,125,116,254,0,70,112,11,77,64,172,92,53,175,44,34,221,162,120,122,145,235,86,123,6,201,36,168,251,138,233,160,91,32,192,140,33,64,31,45,164,25,35,131,214,111,103,185,66,123,36,77,209,130,54,238,77,124,250,76,42,126,68,137,156,53,223,112,84,9,1,172,109,18,138,162,172,98,227,191,233,228,200,186,6,38,31,205,90,238,83,85,200,140,40,95,174,70,100,236,184,92,217,161,244,45,89,208,100,220,62,250,92,105,132,16,63,83,84,164,87,143,157,56,238,206,71,73,61,115,66,84,21,49,226,43,98,209,124,67,230,245,74,241,47,105,36,12,239,120,5,217,170,54,156,84,161,240,229,12,107,226,171,19,248,82,37,157,153,49,126,15,161,81,30,210,115,133,159,227,100,212,172,149,230,75,232,210,108,56,145,60,23,37,166,185,84,193,191,193,253,113,198,103,19,58,1,211,88,161,138,214,89,21,244,44,6,173,6,242,62,51,254,238,79,87,6,12,210,73,244,204,176,178,59,175,3,143,139,2,242,240,21,87,122,194,191,65,151,96,89,50,229,228,174,155,172,240,102,252,221,88,161,54,97,92,243,73,215,246,52,72,145,177,231,202,124,114,136,63,93,192,73,97,131,206,41,240,31,150,151,163,154,135,110,104,89,178,252,214,86,245,40,217,82,157,194,186,14,137,246,116,87,3,221,0,88,209,228,65,175,80,39,254,110,76,107,116,157,222,72,114,28,239,59,179,26,8,211,214,75,156,110,156,114,90,188,114,36,198,234,1,57,238,186,239,33,185,70,78,68,110,74,247,188,177,180,151,164,216,15,115,133,254,13,247,190,87,17,67,0,232,148,145,23,177,217,122,193,138,141,18,36,190,30,64,69,198,123,105,131,146,212,237,192,61,179,237,70,185,233,70,115,24,243,123,134,88,68,215,142,127,133,2,149,85,85,176,160,214,111,3,112,143,142,78,137,211,79,138,29,6,66,209,69,161,250,30,45,145,12,250,62,92,70,95,125,127,105,194,36,213,66,224,165,152,168,81,60,218,234,227,67,148,118,29,59,147,53,55,78,40,8,227,39,217,122,18,110,222,78,162,140,204,238,55,6,95,41,25,0,0,0,0,144,32,12,17,126,234,225,99,200,138,138,108,231,51,212,1,171,8,94,147,139,188,115,131,162,159,107,192,34,19,171,180,161,151,178,33,144,104,181,16,79,208,222,10,42,70,102,179,246,243,151,172,167,86,83,107,175,210,186,181,198,128,36,151,56,29,81,196,245,31,168,78,1,68,190,24,94,31,195,247,20,122,219,85,214,0,172,224,132,217,231,157,205,174,1,20,9,234,148,84,215,130,24,9,46,11,24,156,214,165,23,59,68,102,116,0,213,17,230,13,150,23,44,152,198,242,109,118,74,176,93,184,102,158,85,104,138,31,78,160,214,75,29,223,239,114,74,97,156,59,161,94,69,18,60,117,174,107,34,34,42,46,244,10,252,240,128,232,79,90,245,105,207,185,63,169,21,50,218,22,157,164,50,155,208,136,29,218,73,246,12,13,209,254,95,239,141,35,221,253,207,221,212,9,1,248,135,166,243,99,75,238,65,244,69,142,255,92,110,93,81,203,0,116,149,135,131,96,149,14,49,60,161,204,107,128,214,10,1,164,102,179,128,123,95,250,209,85,215,47,223,202,234,9,179,137,135,46,66,252,162,20,55,210,106,243,173,46,40,178,89,161,54,97,92,243,73,215,246,52,72,145,177,231,202,124,114,136,63,93,192,73,156,179,78,101,253,32,134,94,34,150,203,47,196,201,136,120,12,142,64,149,165,101,204,29,186,80,109,39,8,84,79,232,161,128,2,205,152,207,181,99,73,42,111,179,231,200,36,59,123,154,212,204,146,140,190,129,206,40,197,26,241,53,110,14,80,134,5,37,204,178,45,166,159,129,221,136,86,105,96,102,217,243,16,89,249,161,104,60,252,156,182,35,11,128,137,157,188,182,24,21,145,214,144,137,216,164,177,52,180,226,24,99,117,67,64,64,241,12,41,231,167,74,209,204,218,129,255,34,102,39,251,93,142,41,145,92,203,50,161,138,214,89,21,244,44,6,173,6,242,62,51,254,238,79,87,6,12,210,73,164,143,172,103,50,238,187,229,211,197,117,198,212,234,78,82,14,197,48,46,66,117,89,74,193,245,113,83,209,177,183,217,161,81,125,159,102,197,100,210,237,244,60,182,87,66,79,114,241,194,13,59,255,230,154,81,238,249,118,81,47,67,167,51,81,39,137,145,76,187,230,155,155,70,102,153,242,27,165,84,224,218,253,106,44,9,255,60,175,19,171,24,127,90,244,102,215,109,52,163,108,87,248,78,75,87,18,254,157,225,108,251,34,166,46,135,226,155,114,9,1,137,66,124,98,185,206,118,62,215,166,225,249,150,252,161,203,0,217,115,193,56,251,207,17,2,102,50,45,221,187,226,50,177,93,224,137,41,163,192,131,82,50,167,205,32,29,51,131,23,202,171,216,115,0,2,86,146,226,162,251,7,31,172,102,81,196,200,22,126,55,247,235,106,113,202,76,139,128,246,85,114,151,178,101,95,159,191,161,51,139,210,222,212,86,156,86,143,33,218,23,74,206,199,11,130,110,85,12,238,250,55,221,42,57,86,177,201,103,75,239,3,21,25,161,11,112,13,117,46,113,1,71,100,17,102,72,32,125,98,78,0,1,0,0,253,83,6,143,195,92,106,35,254,224,103,188,253,63,192,216,128,186,79,121,216,182,90,175,191,240,47,48,93,22,155,114,188,54,101,62,87,11,121,52,68,25,197,106,219,1,155,20,238,224,223,45,229,125,209,123,117,113,166,132,12,161,220,14,214,252,191,229,28,159,132,166,98,230,79,209,52,119,54,170,116,134,81,122,205,57,136,220,234,247,156,218,204,189,130,97,114,48,48,160,227,48,48,64,28,58,212,244,195,137,255,228,64,41,161,128,2,205,152,207,181,99,73,42,111,179,231,200,36,59,123,154,212,204,146,237,236,215,194,80,85,137,94,24,27,243,41,116,140,187,70,33,135,209,48,214,17,9,198,53,117,79,21,244,235,240,208,9,255,219,215,135,89,179,97,218,60,174,210,247,236,175,60,97,114,55,143,26,104,199,6,53,175,153,170,254,4,26,49,33,168,161,54,97,92,243,73,215,246,52,72,145,177,231,202,124,114,136,63,93,192,73,131,75,158,95,145,124,241,215,162,81,17,8,190,214,110,90,15,123,1,214,244,31,200,40,196,119,19,72,17,44,27,219,161,44,60,95,185,9,118,123,106,246,85,186,215,47,93,102,56,245,245,208,160,62,110,21,209,63,190,73,44,77,121,157,143,198,176,46,157,199,11,251,128,18,248,171,99,94,148,201,218,67,21,70,232,9,255,16,46,124,130,188,155,165,96,66,61,124,176,157,94,180,222,164,199,68,147,148,121,54,59,60,181,162,4,74,28,114,103,9,1,0,0,0,60,9,235 + ], + "state_diffs_hash": "0xc83cac9cd98a4216cbc0d0830e63c4956e4a1c45c122ebbc88af7ea3b496c406", + "aux_commitments": { + "events_queue_commitment": "0xec82208c87a937d88768a0067b2a80f0525eca8288dad2cf96cf8bbe6a1aa565", + "bootloader_initial_content_commitment": "0x97df88dcecbcd29b49773c042cdee7a44c57a741e64913fff5aa1b3484232f28" + }, + "blob_hashes": [ + { + "commitment": "0xf840cf3f6b7dc92729b2b9ef3b399e7b896d553b746362fe81c4eb911013570d", + "linear_hash": "0xff4feb4bef9401731ab9db3626c2e015baa6880d7b1c4382d03b30da3a0fd75e" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000000", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000000", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000000", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000000", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000000", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000000", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000000", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000000", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000000", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000000", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000000", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000000", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000000", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000000", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000000", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + ], + "aggregation_root": "0x0924928c1377a6cf24c39c2d46f8eb9df23e811b26dc3527e548396fd4e173b1", + "local_root": "0xd4790efa9052ea67dcb473de870e3522e2fc340374e6293ad4646fde312c8c76" + } + }, + "meta_parameters": { + "zkporter_is_available": false, + "bootloader_code_hash": "0x010008c753336bc8d1ddca235602b9f31d346412b2d463cd342899f7bfb73baf", + "default_aa_code_hash": "0x0100055d760f11a3d737e7fd1816e600a4cd874a9f17f7a225d1f1c537c51a1e", + "protocol_version": "Version27" + }, + "pass_through_data": { + "shared_states": [ + { + "last_leaf_index": 212, + "root_hash": "0x0332d2acc43785a44b2b84fc010372c8f3e4ff4d0ca5f312de142ffe74189500" + }, + { + "last_leaf_index": 0, + "root_hash": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + ] + }, + "input": { + "PostBoojum": { + "common": { + "l2_to_l1_logs": [ + { + "shard_id": 0, + "is_service": true, + "tx_number_in_block": 0, + "sender": "0x0000000000000000000000000000000000008001", + "key": "0x91ac392a7af99b6df974efe2d6b40e35dc79156fa3b75ea257df4976da0c26e8", + "value": "0x0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "shard_id": 0, + "is_service": true, + "tx_number_in_block": 1, + "sender": "0x0000000000000000000000000000000000008001", + "key": "0xa088c0c1710f2244aad45e356742e7ac7773a153cf23db6cec4ded7e8da05d69", + "value": "0x0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "shard_id": 0, + "is_service": true, + "tx_number_in_block": 2, + "sender": "0x0000000000000000000000000000000000008001", + "key": "0xccdf8bf8f4bf596f8fbb7ed18d67ef6208919707de498d0cae4d2c01c50e2305", + "value": "0x0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "shard_id": 0, + "is_service": true, + "tx_number_in_block": 3, + "sender": "0x0000000000000000000000000000000000008001", + "key": "0xe43e076103a2a867921c20b43365e7729003f1a00558c3dc51b31b25c90b2b2a", + "value": "0x0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "shard_id": 0, + "is_service": true, + "tx_number_in_block": 4, + "sender": "0x0000000000000000000000000000000000008001", + "key": "0x3eba0d3506eba94a8b328b82b3a32623c2ef77e253bfbb82d2667b163c8714c7", + "value": "0x0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "shard_id": 0, + "is_service": true, + "tx_number_in_block": 5, + "sender": "0x0000000000000000000000000000000000008001", + "key": "0xdaf8935b934fe9513d112e3ca61a728dbfae2fdb5ea1edf8e6f56b8283aa4cd8", + "value": "0x0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "shard_id": 0, + "is_service": true, + "tx_number_in_block": 6, + "sender": "0x0000000000000000000000000000000000008001", + "key": "0x5527767da575eb332ed996603486300af0f55116f2a177b0c05ed31518a23d77", + "value": "0x0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "shard_id": 0, + "is_service": true, + "tx_number_in_block": 7, + "sender": "0x0000000000000000000000000000000000008001", + "key": "0x15f4d69332763eaaf4d80e05e88b04d45d38d0854381f58e4c01688496e03f63", + "value": "0x0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "shard_id": 0, + "is_service": true, + "tx_number_in_block": 8, + "sender": "0x0000000000000000000000000000000000008001", + "key": "0x96a04ccc56dc1cea06a00fe97af3231766aee89c948c86f0c16eeebcdddc0aa3", + "value": "0x0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "shard_id": 0, + "is_service": true, + "tx_number_in_block": 9, + "sender": "0x0000000000000000000000000000000000008001", + "key": "0x886292e17714665013e6c7fc19b12b15a69676394ec88ceb5d1698a0b198a7dd", + "value": "0x0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "shard_id": 0, + "is_service": true, + "tx_number_in_block": 10, + "sender": "0x0000000000000000000000000000000000008001", + "key": "0x9e84bba4d8497ea90d8c5513063912bdbd9cc85ac68185ee1715a7b15ca01f17", + "value": "0x0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "shard_id": 0, + "is_service": true, + "tx_number_in_block": 11, + "sender": "0x0000000000000000000000000000000000008001", + "key": "0x3795b197a06415b6b00d2bde238a25741ecc9791269d899c97ff983d88dcd5e6", + "value": "0x0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "shard_id": 0, + "is_service": true, + "tx_number_in_block": 12, + "sender": "0x0000000000000000000000000000000000008001", + "key": "0x0e5be5348f9a9fd4e936c4fad6793e0e4395f5642d1b5f9a08e1a3703226f8ef", + "value": "0x0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "shard_id": 0, + "is_service": true, + "tx_number_in_block": 13, + "sender": "0x0000000000000000000000000000000000008001", + "key": "0xec3e691650319cdf9fbc5410f388ea24f2c9325b0d7b4ce37db2a1c5957bd86b", + "value": "0x0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "shard_id": 0, + "is_service": true, + "tx_number_in_block": 14, + "sender": "0x0000000000000000000000000000000000008001", + "key": "0xfa448e8ac5560693b992b70fae5e08f3e9cae510c8e1fa69d2c212dd1811bf05", + "value": "0x0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "shard_id": 0, + "is_service": true, + "tx_number_in_block": 15, + "sender": "0x0000000000000000000000000000000000008001", + "key": "0x6c5a74345d321eb4edebdf43f42a11bc409613a9b92cbfe96730498217b12d43", + "value": "0x0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "shard_id": 0, + "is_service": true, + "tx_number_in_block": 16, + "sender": "0x0000000000000000000000000000000000008001", + "key": "0x7912d592b280f7f7a5d04c68eaddae09b518816a0a6d97bc89b143ae3109e78f", + "value": "0x0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "shard_id": 0, + "is_service": true, + "tx_number_in_block": 17, + "sender": "0x0000000000000000000000000000000000008001", + "key": "0x3c1fad3b48be6cb9503048860557f3ef99dccdf1f51dfbf26570f630469b1a98", + "value": "0x0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "shard_id": 0, + "is_service": true, + "tx_number_in_block": 18, + "sender": "0x0000000000000000000000000000000000008001", + "key": "0xb7e755892fbe6870e93cbd3c0945d772e141b94ee50aa75a2d7bb7219fb53266", + "value": "0x0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "shard_id": 0, + "is_service": true, + "tx_number_in_block": 19, + "sender": "0x0000000000000000000000000000000000008001", + "key": "0xb81f1f0fbe80e956956132771d1a99c35bd52856adbf932cc061d3980a79c124", + "value": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "shard_id": 0, + "is_service": true, + "tx_number_in_block": 20, + "sender": "0x0000000000000000000000000000000000008001", + "key": "0x8f5a7c0d48c9b82137c446c9db31ce5ef4e1a30166dd3ae09580c33595bbe2b7", + "value": "0x0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "shard_id": 0, + "is_service": true, + "tx_number_in_block": 21, + "sender": "0x0000000000000000000000000000000000008001", + "key": "0x2f6516d033cfa362a407a7d2d2279c62fa185eaae6742bc6f51fdcb51606094e", + "value": "0x0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "shard_id": 0, + "is_service": true, + "tx_number_in_block": 22, + "sender": "0x0000000000000000000000000000000000008001", + "key": "0x82eb8a4152ff724ef814c3ddacea2a65e6e6d09a00d72e57fff9e12b7857461d", + "value": "0x0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "shard_id": 0, + "is_service": true, + "tx_number_in_block": 23, + "sender": "0x0000000000000000000000000000000000008001", + "key": "0x08a95d3f4505e0e3fb90a2002a81750c0bae658a5d4a290acaeacdfc2691560a", + "value": "0x0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "shard_id": 0, + "is_service": true, + "tx_number_in_block": 24, + "sender": "0x0000000000000000000000000000000000008001", + "key": "0xb8c38e08db553411378fc77ca81f20da7d5b1be77fb316393e33bfe0c08565dd", + "value": "0x0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "shard_id": 0, + "is_service": true, + "tx_number_in_block": 25, + "sender": "0x0000000000000000000000000000000000008001", + "key": "0xd54d7593c4d133e4903becb318f109246537ddab2646148ac51ac7c94e25ef8c", + "value": "0x0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "shard_id": 0, + "is_service": true, + "tx_number_in_block": 26, + "sender": "0x0000000000000000000000000000000000008001", + "key": "0x3e86b6ddb211d47e057c4e246810e2dbb10061c2679e52ae7e4b647c9c98bf08", + "value": "0x0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "shard_id": 0, + "is_service": true, + "tx_number_in_block": 27, + "sender": "0x0000000000000000000000000000000000008001", + "key": "0xe1cee6c0528143fa82ff667c9655d2d775dccdb4204791956096a6225059c9b8", + "value": "0x0000000000000000000000000000000000000000000000000000000000000001" + } + ], + "rollup_last_leaf_index": 212, + "rollup_root_hash": "0x0332d2acc43785a44b2b84fc010372c8f3e4ff4d0ca5f312de142ffe74189500", + "bootloader_code_hash": "0x010008c753336bc8d1ddca235602b9f31d346412b2d463cd342899f7bfb73baf", + "default_aa_code_hash": "0x0100055d760f11a3d737e7fd1816e600a4cd874a9f17f7a225d1f1c537c51a1e", + "protocol_version": "Version27" + }, + "system_logs": [ + { + "shard_id": 0, + "is_service": false, + "tx_number_in_block": 0, + "sender": "0x000000000000000000000000000000000000800b", + "key": "0x0000000000000000000000000000000000000000000000000000000000000002", + "value": "0xf9030b78c5bf5ac997a76962aa32c90a6d8e8ebce9838c8eeb388d73e1f7659a" + }, + { + "shard_id": 0, + "is_service": true, + "tx_number_in_block": 0, + "sender": "0x0000000000000000000000000000000000008001", + "key": "0x0000000000000000000000000000000000000000000000000000000000000007", + "value": "0x91ac392a7af99b6df974efe2d6b40e35dc79156fa3b75ea257df4976da0c26e8" + }, + { + "shard_id": 0, + "is_service": false, + "tx_number_in_block": 28, + "sender": "0x000000000000000000000000000000000000800b", + "key": "0x0000000000000000000000000000000000000000000000000000000000000001", + "value": "0x00000000000000000000000066fc024100000000000000000000000066fc0242" + }, + { + "shard_id": 0, + "is_service": true, + "tx_number_in_block": 28, + "sender": "0x0000000000000000000000000000000000008001", + "key": "0x0000000000000000000000000000000000000000000000000000000000000003", + "value": "0x190bda1fde651ac21cf771cb9f125f486678abbab229cce182a7c9a07361afbe" + }, + { + "shard_id": 0, + "is_service": true, + "tx_number_in_block": 28, + "sender": "0x0000000000000000000000000000000000008001", + "key": "0x0000000000000000000000000000000000000000000000000000000000000004", + "value": "0x000000000000000000000000000000000000000000000000000000000000001b" + }, + { + "shard_id": 0, + "is_service": true, + "tx_number_in_block": 28, + "sender": "0x0000000000000000000000000000000000008008", + "key": "0x0000000000000000000000000000000000000000000000000000000000000000", + "value": "0x38eaeef3afe69b6f6b2fa22c92da8137f1e405a1e1861b7de7cfa30c7d7462dd" + }, + { + "shard_id": 0, + "is_service": true, + "tx_number_in_block": 28, + "sender": "0x0000000000000000000000000000000000008008", + "key": "0x0000000000000000000000000000000000000000000000000000000000000006", + "value": "0x000000000000000000000000cc4b013229ffd6cb5eae5876251874172cafed0a" + }, + { + "shard_id": 0, + "is_service": true, + "tx_number_in_block": 28, + "sender": "0x0000000000000000000000000000000000008008", + "key": "0x0000000000000000000000000000000000000000000000000000000000000005", + "value": "0x335f4f11c3e55bb502bcbdedfd8e63b8e5c84bea465c984a5c664a8eca7d4a7a" + } + ], + "state_diffs": [ + { + "address": "0x0000000000000000000000000000000000008002", + "key": "0x3e013dc3eb10bbd48a8f9c94758f04d081563b6", + "derived_key": [ + 112,120,89,162,183,230,11,175,17,100,223,232,175,83,47,195,198,157,29,129,145,197,186,61,127,17,109,250,141,181,206,45 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x10001430633c573868f335e3106fc558badc506762eb8184ef9ce785def6ece" + }, + { + "address": "0x0000000000000000000000000000000000008002", + "key": "0x868a8819e738818dabe8bfb671ae8e027372dd7", + "derived_key": [ + 130,208,215,121,46,249,196,126,160,123,216,26,86,45,8,246,35,74,8,171,141,141,223,145,137,150,142,180,236,158,154,37 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x1000ecfaeb837bd098bcf9bde6fc2ccd8e8a9355a1b70e601ac18cd089eb308" + }, + { + "address": "0x0000000000000000000000000000000000008002", + "key": "0x9af32a0f1b0914742c84d68795a9be9abd6bbd5", + "derived_key": [ + 246,11,47,22,184,171,230,29,125,57,179,213,44,191,157,128,184,167,253,5,55,217,60,33,8,75,147,188,5,4,171,60 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x10000c328f328dd820a1dd698047a7f7d49874d8259196e273517430af8f480" + }, + { + "address": "0x0000000000000000000000000000000000008002", + "key": "0x22acca3c358a523c1ecbf1491d131a597aada298", + "derived_key": [ + 203,204,98,199,195,136,172,152,215,47,208,131,209,215,32,206,186,255,203,162,198,108,114,94,200,185,197,197,240,116,111,138 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x100005b8e587974043d59bffbf632d020e764959abe62e4c238d8df2e62b2b5" + }, + { + "address": "0x0000000000000000000000000000000000008002", + "key": "0x2c3c5fb909767b6af655bad72f5d6638f5f5d0a0", + "derived_key": [ + 235,143,74,199,189,78,241,151,159,154,102,86,114,178,92,208,123,30,61,99,122,89,162,199,107,26,34,232,91,117,146,65 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x10001430633c573868f335e3106fc558badc506762eb8184ef9ce785def6ece" + }, + { + "address": "0x0000000000000000000000000000000000008002", + "key": "0x30439cdc8796fb3cecb53f4bf5b133f581b5b40f", + "derived_key": [ + 66,202,106,148,168,163,117,186,10,227,150,70,185,29,164,88,23,175,73,33,116,119,174,107,73,193,3,53,191,78,11,115 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x10001b37e5f8cafac924b3e663779e12c80dace8a02b1d273ae708f275ad62a" + }, + { + "address": "0x0000000000000000000000000000000000008002", + "key": "0x338bd2ded4569c568f21da174acec70b826e550c", + "derived_key": [ + 71,164,52,102,233,54,181,135,193,191,158,16,243,13,105,123,17,66,228,89,233,6,51,219,18,27,114,127,245,180,121,43 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x1000067554f53c6660e53bd9729f00aee0189010dfeb868fa3cbd481232480c" + }, + { + "address": "0x0000000000000000000000000000000000008002", + "key": "0x48a6f6788413af58f1bdf8c963cb67a4346f5fd8", + "derived_key": [ + 95,233,138,250,154,14,193,124,34,99,2,123,232,159,70,229,238,83,58,30,33,169,31,255,76,177,68,204,74,239,33,188 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x10005b597eb02058b230cee6a9cdf4705410d151ad1ea6ad3e2de77841acfc2" + }, + { + "address": "0x0000000000000000000000000000000000008002", + "key": "0x4c48bdb0145a89bd87f8884f3fa8c1e42d585e75", + "derived_key": [ + 142,107,134,4,159,177,116,20,22,26,103,250,177,44,27,34,144,68,85,154,16,112,202,176,23,66,216,18,18,139,156,190 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x1000067554f53c6660e53bd9729f00aee0189010dfeb868fa3cbd481232480c" + }, + { + "address": "0x0000000000000000000000000000000000008002", + "key": "0x517d9f66c564d2edf43cb657424f72f1c20d3bff", + "derived_key": [ + 140,78,248,13,214,150,89,51,34,40,248,136,164,249,180,131,12,12,50,27,140,170,45,67,53,35,250,200,97,150,181,207 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x100048bf1b165f4c850d01eb81e5c040f70ea01dca019e780a87f80ec7897c3" + }, + { + "address": "0x0000000000000000000000000000000000008002", + "key": "0x55f6f01d04a21e76cbd2de9d4a9ff6ee9f8893a6", + "derived_key": [ + 235,96,109,232,32,223,19,108,89,177,255,121,225,223,146,96,66,108,164,143,175,146,74,70,53,36,33,31,183,195,161,165 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x1000201e923f3e47adfa7c4f0f61ea8dd4256f66d1099970bcd314892864917" + }, + { + "address": "0x0000000000000000000000000000000000008002", + "key": "0x5caf5f2b06ca757c7cebacdcd6f163af45a6bb83", + "derived_key": [ + 95,127,60,252,81,90,137,254,204,8,97,6,46,254,57,252,48,104,36,27,116,128,26,163,170,147,245,100,172,98,242,54 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x100061dc40d0bc2cb81905e6bc1421ebd4bd8b79aacb8da4f9d7145b288674f" + }, + { + "address": "0x0000000000000000000000000000000000008002", + "key": "0x5e45123c75ae6b22222a2ef40afcf080e84f5af5", + "derived_key": [ + 207,14,96,187,125,119,111,198,230,184,241,1,19,161,190,119,25,192,44,34,151,163,108,216,124,11,59,35,121,140,74,95 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x100070f1cd4e2830607af30192743910fdfabf1dd004a8073944275819d1dfe" + }, + { + "address": "0x0000000000000000000000000000000000008002", + "key": "0x62af78a1a86d5fa8aa7b75ee1884d36ca3c3193a", + "derived_key": [ + 53,89,195,90,167,22,152,246,194,202,70,67,239,232,80,69,169,73,79,38,45,119,238,103,193,61,215,52,230,38,48,90 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x10001430633c573868f335e3106fc558badc506762eb8184ef9ce785def6ece" + }, + { + "address": "0x0000000000000000000000000000000000008002", + "key": "0x683cfc9cb6230b80899dbcb6181591d69089d8a4", + "derived_key": [ + 186,93,97,46,65,80,43,253,205,126,211,179,176,210,212,177,245,200,248,185,15,209,21,42,187,224,222,192,14,162,61,7 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x100048bf1b165f4c850d01eb81e5c040f70ea01dca019e780a87f80ec7897c3" + }, + { + "address": "0x0000000000000000000000000000000000008002", + "key": "0x7cf7e4a85a7a677f6a5b2fe169e6d5eef29219c5", + "derived_key": [ + 44,61,141,160,220,54,28,84,148,218,146,175,212,98,94,116,25,190,241,121,131,189,209,145,214,33,89,62,212,173,57,47 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x1000323b7266314b9d3ec387d5bcd9590a50be00e788837ca5a880d97e3ee83" + }, + { + "address": "0x0000000000000000000000000000000000008002", + "key": "0x97b2219068b5104fd0de0a2a4666b3f6f397aca7", + "derived_key": [ + 48,100,113,86,255,138,164,229,100,8,99,14,34,251,194,115,119,250,250,242,7,188,204,248,210,254,18,115,9,165,229,233 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x1000215cd6f306d757d5d2fdbb460c60f298584179eecc07196c7ae8e4f8d64" + }, + { + "address": "0x0000000000000000000000000000000000008002", + "key": "0x9961618bfad393730ea065a18399303330f1395f", + "derived_key": [ + 200,51,40,178,38,74,180,112,167,221,220,163,38,200,255,61,159,78,76,252,60,226,78,168,221,216,201,180,12,20,188,185 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x1000201e923f3e47adfa7c4f0f61ea8dd4256f66d1099970bcd314892864917" + }, + { + "address": "0x0000000000000000000000000000000000008002", + "key": "0xcc4b013229ffd6cb5eae5876251874172cafed0a", + "derived_key": [ + 229,176,77,5,169,51,88,54,33,49,122,209,137,227,159,45,116,33,7,146,238,29,46,153,91,171,175,162,128,71,14,27 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x100015306fb0f0b5fde219996551c8072c6711bba5300b2669aeb0f0e4c7445" + }, + { + "address": "0x0000000000000000000000000000000000008002", + "key": "0xcc8e14c05825cde94522515a0303e4c2e07ca6f9", + "derived_key": [ + 250,253,202,115,87,157,171,40,23,48,73,193,157,78,81,69,162,232,29,120,68,42,125,135,121,254,156,149,143,198,173,119 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x1000035ba31ed16c21160780ac09763bfd593b1748f69e683a9fb10921aa49d" + }, + { + "address": "0x0000000000000000000000000000000000008002", + "key": "0xdb5b25a5c3ff135d39df0dd3417a6b26724d2b24", + "derived_key": [ + 188,67,139,78,87,51,241,113,6,164,3,59,144,48,243,76,127,49,1,147,79,102,218,253,36,37,149,91,92,247,35,64 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x10000ed306b29128e065afdce73ebc8e0ecd08cd918fdc0f74c03f64d515e48" + }, + { + "address": "0x0000000000000000000000000000000000008002", + "key": "0xdc0ed6fcbfe51c9f84a662e64fd1347736aa7486", + "derived_key": [ + 6,115,118,133,155,130,106,66,115,187,68,69,230,28,222,77,91,95,90,23,4,86,255,161,95,247,195,108,233,152,241,190 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x100013f4a2c964c71d49f2d8876a11eee4bf4e8d19231652fc775b2cae43a21" + }, + { + "address": "0x0000000000000000000000000000000000008002", + "key": "0xe024f9e4e8fa2f08f768c1cb56bc4a6e3cbd8834", + "derived_key": [ + 129,4,114,76,225,212,61,128,125,223,69,48,213,107,167,249,183,181,194,21,67,99,215,247,166,215,108,189,158,61,249,130 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x100006721ab911a41d8b52502ea4cdf42ec99e5e529be6a3e66f3adb2143c5a" + }, + { + "address": "0x0000000000000000000000000000000000008002", + "key": "0xe300eb4b0834a551cac3e93f30380643ce153408", + "derived_key": [ + 51,232,118,240,225,158,242,19,13,216,95,254,79,35,196,212,101,148,164,24,219,221,10,181,111,253,164,76,93,72,246,206 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x10005bb7471a0016b1c330f767a5e73ad0c330934694cad007c5aa3f926be65" + }, + { + "address": "0x0000000000000000000000000000000000008002", + "key": "0xf0e50c6be2ab13f852259d99317e0fa1511ed273", + "derived_key": [ + 25,143,99,94,50,239,35,14,215,12,184,219,25,32,81,51,246,142,27,126,246,157,133,33,13,119,172,197,111,163,43,234 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x1000515657ebe014d9151480712de7a108d9b0e1a7a798d3da2945ba53cd103" + }, + { + "address": "0x0000000000000000000000000000000000008002", + "key": "0xfa1e2d910cfa3e5c465f7d7f69c224d542e0a598", + "derived_key": [ + 90,251,120,52,143,255,91,253,53,60,239,129,160,65,213,230,214,195,241,114,123,145,145,220,232,75,132,91,7,118,101,237 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x10006311257c403bbba7e2aef0aa20822627c82ec7484fcb31b87dd8c582aa9" + }, + { + "address": "0x0000000000000000000000000000000000008003", + "key": "0x64534fbb7489d8b2e0974a2a70dee20ad40795d90f17c1a6d62ba36ea19e007", + "derived_key": [ + 240,163,222,200,2,37,101,9,35,172,42,74,77,142,96,167,8,137,208,171,61,234,142,107,218,41,37,203,138,127,216,252 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x200000000000000000000000000000000" + }, + { + "address": "0x0000000000000000000000000000000000008003", + "key": "0x1b458e5ab877fea2e4abf98d12b31ec3f7c93fd4856e807f684322e8cf11fdf7", + "derived_key": [ + 174,229,34,198,20,187,1,37,21,66,226,45,128,16,30,45,151,85,103,77,143,214,69,38,254,154,44,77,223,171,97,143 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x100000000000000000000000000000000" + }, + { + "address": "0x0000000000000000000000000000000000008003", + "key": "0x810ca1ae825b138452fb743e9948f909b6286cbfadd5a899190fcb21a75443ab", + "derived_key": [ + 0,159,186,133,75,226,253,235,173,50,111,19,111,136,219,244,177,114,214,77,28,237,51,180,171,99,164,148,28,226,73,151 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x700000000000000000000000000000000" + }, + { + "address": "0x0000000000000000000000000000000000008003", + "key": "0xe6d904d46c5d8b2934bf40eee45740c707124a9797010ceae3f79534391b6de5", + "derived_key": [ + 201,172,113,10,243,67,127,194,244,249,48,131,50,164,72,10,88,81,76,45,149,28,73,119,114,174,142,141,132,8,175,27 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x200000000000000000000000000000000" + }, + { + "address": "0x0000000000000000000000000000000000008003", + "key": "0xeaa2b2fbf0b42c559059e5e9510edc15755f1c1883f0e41d5ba5f9aea4ac201a", + "derived_key": [ + 182,81,125,81,147,30,201,86,98,178,2,213,133,189,82,214,234,207,27,118,113,82,28,46,150,32,45,104,62,223,226,99 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0xe00000000000000000000000000000000" + }, + { + "address": "0x0000000000000000000000000000000000008004", + "key": "0x1000035ba31ed16c21160780ac09763bfd593b1748f69e683a9fb10921aa49d", + "derived_key": [ + 28,170,140,159,117,250,84,163,177,210,240,18,225,217,234,99,118,79,112,157,28,25,151,121,72,28,143,77,92,237,107,62 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x1" + }, + { + "address": "0x0000000000000000000000000000000000008004", + "key": "0x100005b8e587974043d59bffbf632d020e764959abe62e4c238d8df2e62b2b5", + "derived_key": [ + 45,86,211,71,72,250,222,240,196,161,223,115,65,15,173,85,177,255,211,89,90,168,146,255,238,205,12,128,137,196,203,27 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x1" + }, + { + "address": "0x0000000000000000000000000000000000008004", + "key": "0x100006721ab911a41d8b52502ea4cdf42ec99e5e529be6a3e66f3adb2143c5a", + "derived_key": [ + 12,138,2,247,115,213,230,144,244,253,93,195,182,20,84,243,71,244,71,24,244,103,128,231,65,233,198,173,128,126,246,169 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x1" + }, + { + "address": "0x0000000000000000000000000000000000008004", + "key": "0x1000067554f53c6660e53bd9729f00aee0189010dfeb868fa3cbd481232480c", + "derived_key": [ + 185,67,192,97,81,170,106,240,157,23,26,106,216,228,65,120,68,165,135,110,2,31,216,158,187,67,79,105,151,157,234,15 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x1" + }, + { + "address": "0x0000000000000000000000000000000000008004", + "key": "0x10000c328f328dd820a1dd698047a7f7d49874d8259196e273517430af8f480", + "derived_key": [ + 12,91,247,177,168,165,63,93,186,29,121,106,121,167,27,50,198,22,230,125,252,159,77,132,92,155,115,251,100,87,112,147 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x1" + }, + { + "address": "0x0000000000000000000000000000000000008004", + "key": "0x10000ed306b29128e065afdce73ebc8e0ecd08cd918fdc0f74c03f64d515e48", + "derived_key": [ + 127,216,219,101,110,162,74,65,114,24,131,123,143,204,15,44,36,72,8,136,170,255,39,231,108,143,128,71,65,95,117,4 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x1" + }, + { + "address": "0x0000000000000000000000000000000000008004", + "key": "0x10000fd53068fc35c6a23fee067bcfd3fc0d880ba4f79d8b65aafbff02f305d", + "derived_key": [ + 4,27,221,133,245,254,194,84,195,88,19,141,109,233,58,225,116,116,251,225,170,44,159,23,28,181,85,238,6,151,63,144 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x1" + }, + { + "address": "0x0000000000000000000000000000000000008004", + "key": "0x100013f4a2c964c71d49f2d8876a11eee4bf4e8d19231652fc775b2cae43a21", + "derived_key": [ + 130,114,163,11,234,79,36,77,175,198,107,147,58,183,234,134,122,178,61,205,225,34,184,146,138,50,221,70,198,19,2,191 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x1" + }, + { + "address": "0x0000000000000000000000000000000000008004", + "key": "0x10001430633c573868f335e3106fc558badc506762eb8184ef9ce785def6ece", + "derived_key": [ + 41,151,245,131,127,195,211,240,254,148,60,106,169,97,173,173,118,116,195,243,213,115,169,17,155,83,25,181,108,68,48,51 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x1" + }, + { + "address": "0x0000000000000000000000000000000000008004", + "key": "0x100015306fb0f0b5fde219996551c8072c6711bba5300b2669aeb0f0e4c7445", + "derived_key": [ + 236,254,112,114,24,207,172,186,132,163,119,198,20,66,226,51,51,142,39,212,88,198,68,118,92,136,138,204,26,155,11,165 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x1" + }, + { + "address": "0x0000000000000000000000000000000000008004", + "key": "0x10001b37e5f8cafac924b3e663779e12c80dace8a02b1d273ae708f275ad62a", + "derived_key": [ + 215,116,3,65,140,246,136,209,81,15,184,214,188,49,94,63,81,57,12,135,108,143,41,137,113,88,11,84,15,30,158,184 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x1" + }, + { + "address": "0x0000000000000000000000000000000000008004", + "key": "0x1000201e923f3e47adfa7c4f0f61ea8dd4256f66d1099970bcd314892864917", + "derived_key": [ + 50,203,140,60,152,140,103,117,103,130,42,29,70,236,110,49,211,18,247,40,117,35,54,107,171,190,233,18,117,69,68,43 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x1" + }, + { + "address": "0x0000000000000000000000000000000000008004", + "key": "0x1000215cd6f306d757d5d2fdbb460c60f298584179eecc07196c7ae8e4f8d64", + "derived_key": [ + 95,50,92,228,81,22,16,190,182,42,66,158,131,165,204,25,25,20,143,210,29,170,143,129,94,111,129,132,227,28,102,180 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x1" + }, + { + "address": "0x0000000000000000000000000000000000008004", + "key": "0x100023dc5e29b1af44a05d231db67a62a8bfd0c06217caa29b061daa7f2913f", + "derived_key": [ + 96,153,155,64,152,142,147,161,102,88,190,194,238,147,14,243,71,26,33,184,193,50,249,29,88,2,52,157,179,7,69,77 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x1" + }, + { + "address": "0x0000000000000000000000000000000000008004", + "key": "0x1000323b7266314b9d3ec387d5bcd9590a50be00e788837ca5a880d97e3ee83", + "derived_key": [ + 212,255,51,143,196,70,53,156,98,221,171,235,82,21,252,198,242,28,2,246,195,67,6,91,2,240,95,173,200,49,66,89 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x1" + }, + { + "address": "0x0000000000000000000000000000000000008004", + "key": "0x100048bf1b165f4c850d01eb81e5c040f70ea01dca019e780a87f80ec7897c3", + "derived_key": [ + 58,212,15,123,117,242,193,79,217,63,177,112,56,232,153,140,93,188,111,168,108,138,82,113,212,107,209,150,246,205,191,157 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x1" + }, + { + "address": "0x0000000000000000000000000000000000008004", + "key": "0x1000515657ebe014d9151480712de7a108d9b0e1a7a798d3da2945ba53cd103", + "derived_key": [ + 204,180,39,152,129,136,139,125,156,240,127,28,205,2,65,12,140,132,177,76,5,4,95,204,205,9,179,77,57,148,6,231 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x1" + }, + { + "address": "0x0000000000000000000000000000000000008004", + "key": "0x10005b597eb02058b230cee6a9cdf4705410d151ad1ea6ad3e2de77841acfc2", + "derived_key": [ + 249,145,142,225,129,214,86,160,12,71,51,28,109,238,246,115,57,184,6,234,138,46,107,81,103,128,201,242,101,51,179,68 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x1" + }, + { + "address": "0x0000000000000000000000000000000000008004", + "key": "0x10005bb7471a0016b1c330f767a5e73ad0c330934694cad007c5aa3f926be65", + "derived_key": [ + 17,109,102,169,143,117,42,93,149,160,20,188,122,34,0,140,248,73,206,232,146,65,183,250,61,35,40,54,167,63,173,215 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x1" + }, + { + "address": "0x0000000000000000000000000000000000008004", + "key": "0x100061dc40d0bc2cb81905e6bc1421ebd4bd8b79aacb8da4f9d7145b288674f", + "derived_key": [ + 58,197,183,31,149,121,187,250,193,140,202,222,69,149,235,105,78,113,59,213,78,241,15,40,62,137,46,19,193,78,85,31 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x1" + }, + { + "address": "0x0000000000000000000000000000000000008004", + "key": "0x10006311257c403bbba7e2aef0aa20822627c82ec7484fcb31b87dd8c582aa9", + "derived_key": [ + 209,81,122,212,165,252,102,254,115,58,127,209,26,21,188,113,69,3,30,255,154,72,181,219,97,7,227,96,209,19,138,181 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x1" + }, + { + "address": "0x0000000000000000000000000000000000008004", + "key": "0x100070f1cd4e2830607af30192743910fdfabf1dd004a8073944275819d1dfe", + "derived_key": [ + 151,245,134,14,100,30,161,175,227,142,158,71,197,157,213,103,198,28,241,51,173,107,242,84,76,53,176,101,132,26,29,60 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x1" + }, + { + "address": "0x0000000000000000000000000000000000008004", + "key": "0x1000ecfaeb837bd098bcf9bde6fc2ccd8e8a9355a1b70e601ac18cd089eb308", + "derived_key": [ + 72,239,59,253,40,148,227,213,236,98,100,14,198,212,71,148,180,209,64,152,228,196,11,209,109,231,183,97,135,156,172,241 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x1" + }, + { + "address": "0x0000000000000000000000000000000000008005", + "key": "0xe778a21bcfe90796edfc6e5dba276e58537d4ff192bc30765e18d9ef2aa9a55", + "derived_key": [ + 205,107,120,198,53,118,206,64,8,204,37,15,58,43,95,189,38,38,203,212,73,105,50,160,21,160,38,124,10,233,46,22 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x10e" + }, + { + "address": "0x0000000000000000000000000000000000008005", + "key": "0x201f2e5549e69135c92587d30523c730fd01553abf72828402fad9b12c172e10", + "derived_key": [ + 204,0,103,138,56,182,245,161,43,137,56,202,232,138,228,30,242,80,214,237,253,8,17,251,148,203,85,106,127,162,114,20 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x62af78a1a86d5fa8aa7b75ee1884d36ca3c3193a" + }, + { + "address": "0x0000000000000000000000000000000000008005", + "key": "0x35dc0a033f8f3476b52059199e9babf078fddd76cb3c290e05ae42462bfc33eb", + "derived_key": [ + 89,16,198,41,13,94,89,2,119,169,28,80,179,104,66,21,38,252,16,146,163,159,122,68,234,161,165,150,251,139,57,4 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x52f431aa35dd80982e3c66614112503ca2c6e344745f4a2bcfc9bd7e09c75584" + }, + { + "address": "0x0000000000000000000000000000000000008005", + "key": "0x3859fd065954dbed7c74a1359d0e5bc38403ea4cdf0274ae615ce0e3e2afec6b", + "derived_key": [ + 67,87,214,19,120,116,147,47,78,236,178,95,23,23,1,171,197,181,63,197,52,162,224,221,93,223,35,243,248,138,100,215 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x10002" + }, + { + "address": "0x0000000000000000000000000000000000008005", + "key": "0x41c023ccaa2a67013d253ba3488447c2db3843b3f988653fdf8d7c7268862ca9", + "derived_key": [ + 94,249,142,243,210,28,27,218,191,10,139,245,66,107,2,111,153,125,18,238,76,249,208,69,34,173,165,21,177,18,82,239 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x10e" + }, + { + "address": "0x0000000000000000000000000000000000008005", + "key": "0x4792eb7ea10cfac9f83a8d12d965c903854b51c5cb0783e082741ecf0c20dcfe", + "derived_key": [ + 217,248,73,34,237,151,158,186,178,226,225,234,58,186,218,7,175,174,60,185,248,248,25,28,51,154,61,168,213,77,242,169 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x52f431aa35dd80982e3c66614112503ca2c6e344745f4a2bcfc9bd7e09c75584" + }, + { + "address": "0x0000000000000000000000000000000000008005", + "key": "0x5bad0400c1a2cec7acfd85c5c5c25108540c42f405d3ae6ea01209dfbcc63c29", + "derived_key": [ + 194,179,227,24,162,84,191,59,100,89,207,244,98,199,135,44,91,35,210,22,182,249,66,219,89,32,250,61,112,54,16,141 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x62af78a1a86d5fa8aa7b75ee1884d36ca3c3193a" + }, + { + "address": "0x0000000000000000000000000000000000008005", + "key": "0x71d2d9399f0017d99e02441b51c782e6f5613748934c615622bc6f2327b79b8d", + "derived_key": [ + 60,170,232,127,53,17,58,173,142,247,89,247,207,149,119,134,64,14,158,82,18,231,188,179,163,89,11,174,81,43,46,153 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x9" + }, + { + "address": "0x0000000000000000000000000000000000008005", + "key": "0x75579ad6152f71bd465c7f980c773c6df73f53d82aebf8b69c1173f678af2d81", + "derived_key": [ + 132,119,216,135,171,185,255,65,210,32,46,77,152,229,32,71,244,141,39,140,188,245,22,25,184,28,198,202,132,222,174,160 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x10002" + }, + { + "address": "0x0000000000000000000000000000000000008005", + "key": "0x87c06ae8fd6d2ee9919bb86c39ee03f70b0d87028d77b914408152f07043c769", + "derived_key": [ + 119,228,107,44,53,217,61,182,86,125,189,169,81,109,32,249,139,212,234,72,144,24,135,118,89,121,216,219,24,207,66,168 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x10e" + }, + { + "address": "0x0000000000000000000000000000000000008005", + "key": "0x962d8512b88c87f0272660761794a46a130b867d7d15b38fc1adc33433e4fce8", + "derived_key": [ + 213,5,71,76,80,42,16,77,105,27,101,50,79,76,38,232,167,55,134,79,128,251,113,33,35,116,77,254,28,6,176,0 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x52f431aa35dd80982e3c66614112503ca2c6e344745f4a2bcfc9bd7e09c75584" + }, + { + "address": "0x0000000000000000000000000000000000008005", + "key": "0x9f4693a69c182083198dd36e2803bc42bbe3f851aa03cb0f0de7687a2171336b", + "derived_key": [ + 110,177,116,132,158,116,7,177,77,240,138,82,212,212,241,43,54,8,1,75,42,104,243,5,241,73,226,60,72,169,2,41 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x10003" + }, + { + "address": "0x0000000000000000000000000000000000008005", + "key": "0xb35ae26426d210bd3178c283cdcb50ce0cdbff27177eb0786fc3fe0f45083b1d", + "derived_key": [ + 73,127,150,33,212,30,131,171,90,28,221,170,53,22,176,210,81,154,146,160,81,67,188,184,7,13,240,169,97,51,230,181 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x64" + }, + { + "address": "0x0000000000000000000000000000000000008005", + "key": "0xb62ada1fb8084bc5425b2aea59d59080ac3d0a10a1cc368978230741dca77a19", + "derived_key": [ + 71,111,167,179,223,229,107,45,223,184,100,207,103,16,106,234,217,25,120,51,156,12,142,28,186,4,134,110,182,28,191,11 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x9" + }, + { + "address": "0x0000000000000000000000000000000000008005", + "key": "0xcb5ca2f778293159761b941dc7b8f7fd374e3632c39b35a0fd4b1aa20ed4a091", + "derived_key": [ + 62,169,255,238,205,94,99,210,162,31,213,85,158,233,223,231,174,18,241,77,26,133,255,75,40,190,65,163,26,48,53,196 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x10002" + }, + { + "address": "0x0000000000000000000000000000000000008005", + "key": "0xd8fc94fc3444dd0233f4f4f74b08d69d0079035017309fa37c5b30a7cabb729b", + "derived_key": [ + 232,83,248,233,232,89,11,170,74,117,125,224,222,189,198,137,244,49,205,228,155,200,97,42,160,89,8,63,109,25,91,168 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x9" + }, + { + "address": "0x0000000000000000000000000000000000008005", + "key": "0xd9ba5de301f3948ee34a04905cc32b778b54dac455410e096889003b0770d47c", + "derived_key": [ + 255,134,239,235,78,5,0,110,98,20,109,14,192,231,250,72,49,145,191,114,177,51,38,242,67,121,217,71,114,50,124,171 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x9" + }, + { + "address": "0x0000000000000000000000000000000000008005", + "key": "0xf7fa34f014959c990f8cabd865f6012c5ad2ae9390bd21dc8ab2c3ee9c340257", + "derived_key": [ + 209,167,69,145,2,139,203,92,187,46,4,30,218,0,85,77,176,3,253,201,73,229,148,92,229,57,32,59,244,12,109,96 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x9" + }, + { + "address": "0x000000000000000000000000000000000000800a", + "key": "0x1", + "derived_key": [ + 113,233,23,33,249,145,133,118,215,96,240,47,3,202,196,124,111,64,3,49,96,49,132,142,60,29,153,230,232,58,71,67 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0xe29e64ae9c38000" + }, + { + "address": "0x000000000000000000000000000000000000800a", + "key": "0x1b458e5ab877fea2e4abf98d12b31ec3f7c93fd4856e807f684322e8cf11fdf7", + "derived_key": [ + 49,87,111,239,58,195,179,2,237,163,15,66,168,74,199,52,200,236,175,1,55,3,126,248,127,239,193,246,133,27,151,79 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x8603151b10a4a0" + }, + { + "address": "0x000000000000000000000000000000000000800a", + "key": "0x810ca1ae825b138452fb743e9948f909b6286cbfadd5a899190fcb21a75443ab", + "derived_key": [ + 185,211,150,83,253,116,26,253,56,22,83,204,70,30,122,203,221,134,84,251,39,141,138,17,246,159,212,31,236,239,75,201 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x53c1850fab698c0" + }, + { + "address": "0x000000000000000000000000000000000000800a", + "key": "0xafe379b9510a75924647deef7e3d3d3ebf948699c9f84eda83c07c71414098b8", + "derived_key": [ + 250,91,168,183,69,6,78,180,185,147,215,10,134,34,96,243,26,77,158,213,121,211,188,200,73,204,177,205,8,52,178,106 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x4a88ebbafe2b20" + }, + { + "address": "0x000000000000000000000000000000000000800a", + "key": "0xeaa2b2fbf0b42c559059e5e9510edc15755f1c1883f0e41d5ba5f9aea4ac201a", + "derived_key": [ + 141,97,126,192,90,203,191,95,226,69,41,166,75,35,133,169,106,173,67,240,155,225,173,169,44,112,64,49,220,193,72,27 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x81d41f918fe1780" + }, + { + "address": "0x000000000000000000000000000000000000800b", + "key": "0x0", + "derived_key": [ + 150,46,36,83,88,148,64,235,173,169,107,3,33,223,255,240,191,103,10,254,52,186,74,130,141,51,66,227,241,78,210,217 + ], + "enumeration_index": 60, + "initial_value": "0x10e", + "final_value": "0x1f9" + }, + { + "address": "0x000000000000000000000000000000000000800b", + "key": "0x6", + "derived_key": [ + 162,84,32,193,217,215,5,53,140,19,76,198,1,217,209,132,203,77,253,222,126,28,172,43,195,212,211,139,249,236,68,230 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x5f5e100" + }, + { + "address": "0x000000000000000000000000000000000000800b", + "key": "0x7", + "derived_key": [ + 18,59,175,197,134,247,119,100,72,140,210,76,106,119,84,110,90,15,232,189,251,79,162,3,207,175,252,54,204,228,221,91 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x100000000000000000000000066fc0241" + }, + { + "address": "0x000000000000000000000000000000000000800b", + "key": "0x9", + "derived_key": [ + 142,125,208,106,197,183,59,71,59,230,188,90,81,3,15,76,116,55,101,124,183,178,155,243,118,197,100,184,209,103,90,94 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x200000000000000000000000066fc0242" + }, + { + "address": "0x000000000000000000000000000000000000800b", + "key": "0xb", + "derived_key": [ + 75,168,78,31,55,208,65,188,110,85,186,57,104,38,204,73,78,132,212,129,91,109,181,38,144,66,46,234,115,134,49,79 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0xe8e77626586f73b955364c7b4bbf0bb7f7685ebd40e852b164633a4acbd3244c" + }, + { + "address": "0x000000000000000000000000000000000000800b", + "key": "0xc", + "derived_key": [ + 61,226,32,44,203,98,106,211,135,215,7,34,230,79,190,68,86,46,47,35,26,41,12,8,83,43,141,106,186,64,47,245 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0xf2aaeb06c0e556434ac93c232f37dd8be0a7bf9f430f76eb564df9fcb770c45f" + }, + { + "address": "0x000000000000000000000000000000000000800b", + "key": "0x10c", + "derived_key": [ + 121,9,53,136,208,232,71,239,167,58,16,206,32,228,121,159,177,228,102,66,214,86,23,199,229,33,63,160,73,137,217,45 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x200000000000000000000000066fc0242" + }, + { + "address": "0x000000000000000000000000000000000000800b", + "key": "0x10d", + "derived_key": [ + 135,222,210,71,225,102,15,130,112,113,199,241,55,25,52,88,151,81,8,83,132,252,159,68,98,193,241,137,124,92,62,239 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x100000000000000000000000000000001" + }, + { + "address": "0x000000000000000000000000000000000000800b", + "key": "0x10f", + "derived_key": [ + 134,36,129,147,235,77,210,168,206,129,95,135,108,18,77,72,53,149,34,240,133,77,149,216,7,46,175,240,211,125,85,189 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x320" + }, + { + "address": "0x000000000000000000000000000000000000800b", + "key": "0x110", + "derived_key": [ + 62,137,13,108,44,59,173,166,238,204,150,3,169,156,28,98,89,237,90,100,2,241,199,108,193,139,86,140,58,239,186,15 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x22a9" + }, + { + "address": "0x000000000000000000000000000000000000800b", + "key": "0x5eff886ea0ce6ca488a3d6e336d6c0f75f46d19b42c06ce5ee98e42c96d256c7", + "derived_key": [ + 145,29,210,173,116,63,242,55,212,17,100,138,15,227,44,109,116,238,192,96,113,106,42,116,53,47,107,28,67,91,93,103 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0xf9030b78c5bf5ac997a76962aa32c90a6d8e8ebce9838c8eeb388d73e1f7659a" + }, + { + "address": "0x0000000000000000000000000000000000010002", + "key": "0x0", + "derived_key": [ + 214,116,246,54,163,90,111,26,81,86,78,195,55,27,156,77,163,18,109,90,208,186,227,80,207,199,250,234,199,99,99,184 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0xff" + }, + { + "address": "0x0000000000000000000000000000000000010002", + "key": "0x33", + "derived_key": [ + 104,98,246,102,108,85,7,252,51,21,214,132,35,158,2,38,112,107,69,195,65,114,145,245,183,172,194,211,57,80,82,17 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x8ad65915f42c06ad06f23e33feee4f57060cd249" + }, + { + "address": "0x0000000000000000000000000000000000010002", + "key": "0xc9", + "derived_key": [ + 180,68,244,119,54,206,136,162,78,107,80,251,5,29,192,174,93,179,175,68,217,8,246,220,217,160,21,208,74,126,225,227 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x10003" + }, + { + "address": "0x0000000000000000000000000000000000010002", + "key": "0xd3", + "derived_key": [ + 59,172,224,22,174,10,65,231,169,237,9,168,91,33,85,109,38,187,242,242,75,76,32,165,75,187,165,27,95,83,162,158 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x10005" + }, + { + "address": "0x0000000000000000000000000000000000010002", + "key": "0xd5", + "derived_key": [ + 237,36,132,158,202,168,131,171,106,32,214,79,172,224,148,150,15,71,73,102,217,162,19,183,2,117,192,112,196,76,181,34 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x3db94d72a25f64874243af776e06f449d55ba9dd" + }, + { + "address": "0x0000000000000000000000000000000000010002", + "key": "0x4d7101ab951ded1d6f6a567c6e539f8f6a2a675fe1d5eba86fefe5192175b131", + "derived_key": [ + 83,157,81,206,111,89,151,62,178,167,63,16,226,11,189,169,125,149,14,110,8,62,221,87,116,233,142,217,139,253,153,16 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x1" + }, + { + "address": "0x0000000000000000000000000000000000010002", + "key": "0x8e94fed44239eb2314ab7a406345e6c5a8f0ccedf3b600de3d004e672c33abf4", + "derived_key": [ + 186,154,222,88,248,170,108,168,43,242,42,43,72,15,245,221,236,232,166,232,99,81,164,123,16,213,143,51,128,251,219,183 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x1" + }, + { + "address": "0x0000000000000000000000000000000000010002", + "key": "0x99d6a8ff20aa8acdd49c8fb0cc74f2b2b57e0fa371d5aadb8e266a8cf9157ef5", + "derived_key": [ + 103,185,128,156,225,233,200,126,96,129,32,179,163,131,84,200,153,155,236,34,245,43,19,243,165,109,226,10,22,113,50,131 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x1" + }, + { + "address": "0x0000000000000000000000000000000000010002", + "key": "0xca59cc8f90e9fd91e0bc61c0c980b4b130ad1217252dd3bc209e6dfa57a05f63", + "derived_key": [ + 203,224,11,159,230,121,179,34,119,46,123,13,250,7,202,214,183,18,124,144,172,158,237,255,172,53,228,144,236,81,142,168 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x2c3c5fb909767b6af655bad72f5d6638f5f5d0a0" + }, + { + "address": "0x0000000000000000000000000000000000010003", + "key": "0x0", + "derived_key": [ + 183,144,135,107,116,64,90,68,61,138,52,178,244,96,20,237,96,5,52,90,158,129,172,204,39,175,55,18,74,73,29,222 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0xff" + }, + { + "address": "0x0000000000000000000000000000000000010003", + "key": "0x33", + "derived_key": [ + 36,49,6,86,93,12,79,206,248,151,94,121,177,178,35,12,1,159,78,58,178,122,63,78,124,169,48,107,159,98,153,132 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x8ad65915f42c06ad06f23e33feee4f57060cd249" + }, + { + "address": "0x0000000000000000000000000000000000010003", + "key": "0xfa", + "derived_key": [ + 208,111,9,167,39,114,89,78,179,210,171,35,115,181,211,197,236,176,132,184,74,77,237,45,48,18,241,69,222,221,138,25 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x5de08929a3c0835232a7cd201d338317caabd873" + }, + { + "address": "0x0000000000000000000000000000000000010003", + "key": "0x56ca7d7fc0d180f3d83f99276f19310b5c00992edd8618fb359971a7ecb99ab3", + "derived_key": [ + 199,117,193,115,55,85,171,245,34,173,219,214,151,226,215,10,91,97,70,75,209,104,27,41,137,81,196,246,13,142,199,12 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x10004" + }, + { + "address": "0x0000000000000000000000000000000000010003", + "key": "0x635799b36cb7719b903c111d5790821f9e51e29061bc47a57c7988be806aff32", + "derived_key": [ + 113,24,36,136,41,22,138,100,28,59,149,105,31,231,215,27,33,193,211,238,215,254,44,202,236,107,125,180,46,38,146,200 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x10002" + }, + { + "address": "0x0000000000000000000000000000000000010004", + "key": "0x0", + "derived_key": [ + 38,182,122,48,1,162,205,218,95,52,172,146,222,81,199,193,42,178,228,105,133,88,214,83,137,237,66,230,119,250,5,85 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0xff" + }, + { + "address": "0x0000000000000000000000000000000000010004", + "key": "0x33", + "derived_key": [ + 253,39,5,238,88,207,60,229,238,92,28,224,63,70,109,126,152,54,188,71,18,186,162,153,21,61,132,71,202,121,113,207 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x8ad65915f42c06ad06f23e33feee4f57060cd249" + }, + { + "address": "0x0000000000000000000000000000000000010004", + "key": "0xc9", + "derived_key": [ + 191,14,175,103,174,227,73,235,177,89,118,163,111,237,172,26,74,6,101,80,58,211,113,127,243,254,106,224,120,179,101,156 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x4c48bdb0145a89bd87f8884f3fa8c1e42d585e75" + }, + { + "address": "0x0000000000000000000000000000000000010004", + "key": "0xfb", + "derived_key": [ + 184,2,226,247,10,56,240,40,136,100,146,139,246,198,195,194,209,164,217,45,202,10,147,86,175,254,198,249,92,64,121,164 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x10000fd53068fc35c6a23fee067bcfd3fc0d880ba4f79d8b65aafbff02f305d" + }, + { + "address": "0x0000000000000000000000000000000000010005", + "key": "0x0", + "derived_key": [ + 168,74,2,141,105,206,208,33,164,189,140,91,38,36,168,242,80,217,18,184,248,245,157,129,85,249,94,94,229,138,101,38 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x1" + }, + { + "address": "0x0000000000000000000000000000000000010005", + "key": "0x4", + "derived_key": [ + 47,241,202,110,153,206,246,252,92,214,119,95,159,94,245,61,243,40,240,8,26,143,180,81,247,55,255,244,73,12,229,83 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x1" + }, + { + "address": "0x0000000000000000000000000000000000010005", + "key": "0x5", + "derived_key": [ + 95,192,113,95,216,242,21,235,124,16,227,245,80,217,178,9,241,140,170,135,64,175,84,27,211,70,239,73,100,139,20,245 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x1" + }, + { + "address": "0x0000000000000000000000000000000000010005", + "key": "0x6", + "derived_key": [ + 201,169,20,123,206,251,168,141,33,64,175,106,246,185,19,185,53,101,125,53,5,87,5,184,7,21,91,61,208,130,42,131 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x1" + }, + { + "address": "0x0000000000000000000000000000000000010005", + "key": "0x36b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0", + "derived_key": [ + 183,44,52,109,222,204,99,77,172,182,15,29,40,214,131,168,39,33,227,213,36,163,61,162,168,47,3,62,136,241,101,126 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x1" + }, + { + "address": "0x0000000000000000000000000000000000010005", + "key": "0x16db2e4b9f8dc120de98f8491964203ba76de27b27b29c2d25f85a325cd37477", + "derived_key": [ + 133,79,165,174,6,191,41,30,209,5,109,104,28,93,197,246,247,13,23,242,234,3,204,110,233,229,198,255,131,62,203,105 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x924928c1377a6cf24c39c2d46f8eb9df23e811b26dc3527e548396fd4e173b1" + }, + { + "address": "0x0000000000000000000000000000000000010005", + "key": "0x7bbeda1ca523343d5e888708327d45f8c743f6cb29e139a7e03dc5068543e6c4", + "derived_key": [ + 211,102,235,93,180,24,37,200,29,129,191,72,73,93,114,116,50,181,244,253,225,248,223,46,101,251,180,223,113,77,242,139 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x46700b4d40ac5c35af2c22dda2787a91eb567b06c924a8fb8ae9a05b20c08c21" + }, + { + "address": "0x0000000000000000000000000000000000010005", + "key": "0x8e94fed44239eb2314ab7a406345e6c5a8f0ccedf3b600de3d004e672c33abf4", + "derived_key": [ + 228,96,52,194,207,181,181,131,126,57,95,233,204,152,190,4,82,34,235,53,200,202,40,109,252,73,189,213,239,94,126,130 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x1" + }, + { + "address": "0x0000000000000000000000000000000000010005", + "key": "0xac33ff75c19e70fe83507db0d683fd3465c996598dc972688b7ace676c89077b", + "derived_key": [ + 27,8,240,147,212,200,27,37,231,124,191,110,45,189,91,214,149,171,253,138,221,47,115,230,14,214,92,143,87,109,114,128 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x1f9" + }, + { + "address": "0x0000000000000000000000000000000000010005", + "key": "0xe14c171e271191dbbbddd568a762a4325466b12116e776c3243375f110708d73", + "derived_key": [ + 248,63,134,138,17,62,7,250,227,100,52,50,139,214,30,153,110,204,16,117,222,9,119,59,220,202,187,15,30,237,162,217 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x1" + }, + { + "address": "0x0000000000000000000000000000000000010005", + "key": "0xe14c171e271191dbbbddd568a762a4325466b12116e776c3243375f110708d74", + "derived_key": [ + 207,50,50,89,38,214,97,46,146,127,167,239,70,37,230,216,37,111,63,130,63,184,65,242,102,240,65,120,90,218,241,226 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x1" + }, + { + "address": "0x0000000000000000000000000000000000010005", + "key": "0xf652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f", + "derived_key": [ + 247,124,190,104,95,142,126,239,68,219,69,165,161,237,129,135,165,5,236,239,227,84,140,240,18,4,129,67,95,125,116,254 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x46700b4d40ac5c35af2c22dda2787a91eb567b06c924a8fb8ae9a05b20c08c21" + }, + { + "address": "0x03e013dc3eb10bbd48a8f9c94758f04d081563b6", + "key": "0x0", + "derived_key": [ + 64,31,45,164,25,35,131,214,111,103,185,66,123,36,77,209,130,54,238,77,124,250,76,42,126,68,137,156,53,223,112,84 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x1" + }, + { + "address": "0x03e013dc3eb10bbd48a8f9c94758f04d081563b6", + "key": "0x33", + "derived_key": [ + 172,109,18,138,162,172,98,227,191,233,228,200,186,6,38,31,205,90,238,83,85,200,140,40,95,174,70,100,236,184,92,217 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0xf42d59d064dc3efa5c6984103f5354a4578f9d38" + }, + { + "address": "0x03e013dc3eb10bbd48a8f9c94758f04d081563b6", + "key": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc", + "derived_key": [ + 238,206,71,73,61,115,66,84,21,49,226,43,98,209,124,67,230,245,74,241,47,105,36,12,239,120,5,217,170,54,156,84 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0xf0e50c6be2ab13f852259d99317e0fa1511ed273" + }, + { + "address": "0x03e013dc3eb10bbd48a8f9c94758f04d081563b6", + "key": "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103", + "derived_key": [ + 133,159,227,100,212,172,149,230,75,232,210,108,56,145,60,23,37,166,185,84,193,191,193,253,113,198,103,19,58,1,211,88 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x8ad65915f42c06ad06f23e33feee4f57060cd249" + }, + { + "address": "0x2c3c5fb909767b6af655bad72f5d6638f5f5d0a0", + "key": "0x33", + "derived_key": [ + 244,204,176,178,59,175,3,143,139,2,242,240,21,87,122,194,191,65,151,96,89,50,229,228,174,155,172,240,102,252,221,88 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x36615cf349d7f6344891b1e7ca7c72883f5dc049" + }, + { + "address": "0x2c3c5fb909767b6af655bad72f5d6638f5f5d0a0", + "key": "0x9a", + "derived_key": [ + 97,131,206,41,240,31,150,151,163,154,135,110,104,89,178,252,214,86,245,40,217,82,157,194,186,14,137,246,116,87,3,221 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x58d1e441af5027fe6e4c6b749dde48721cef3bb31a08d3d64b9c6e9c725abc72" + }, + { + "address": "0x2c3c5fb909767b6af655bad72f5d6638f5f5d0a0", + "key": "0x9b", + "derived_key": [ + 36,198,234,1,57,238,186,239,33,185,70,78,68,110,74,247,188,177,180,151,164,216,15,115,133,254,13,247,190,87,17,67 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0xe8949117b1d97ac18a8d1224be1e4045c67b698392d4edc03db3ed46b9e94673" + }, + { + "address": "0x2c3c5fb909767b6af655bad72f5d6638f5f5d0a0", + "key": "0x9c", + "derived_key": [ + 24,243,123,134,88,68,215,142,127,133,2,149,85,85,176,160,214,111,3,112,143,142,78,137,211,79,138,29,6,66,209,69 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0xfa1e2d910cfa3e5c465f7d7f69c224d542e0a598" + }, + { + "address": "0x2c3c5fb909767b6af655bad72f5d6638f5f5d0a0", + "key": "0x9d", + "derived_key": [ + 168,81,60,218,234,227,67,148,118,29,59,147,53,55,78,40,8,227,39,217,122,18,110,222,78,162,140,204,238,55,6,95 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x1900000000" + }, + { + "address": "0x2c3c5fb909767b6af655bad72f5d6638f5f5d0a0", + "key": "0x9f", + "derived_key": [ + 144,32,12,17,126,234,225,99,200,138,138,108,231,51,212,1,171,8,94,147,139,188,115,131,162,159,107,192,34,19,171,180 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x97b2219068b5104fd0de0a2a4666b3f6f397aca7" + }, + { + "address": "0x2c3c5fb909767b6af655bad72f5d6638f5f5d0a0", + "key": "0xa3", + "derived_key": [ + 86,83,107,175,210,186,181,198,128,36,151,56,29,81,196,245,31,168,78,1,68,190,24,94,31,195,247,20,122,219,85,214 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0xace084d9e79dcdae011409ea9454d78218092e0b189cd6a5173b44667400d511" + }, + { + "address": "0x2c3c5fb909767b6af655bad72f5d6638f5f5d0a0", + "key": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc", + "derived_key": [ + 230,13,150,23,44,152,198,242,109,118,74,176,93,184,102,158,85,104,138,31,78,160,214,75,29,223,239,114,74,97,156,59 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x5e45123c75ae6b22222a2ef40afcf080e84f5af5" + }, + { + "address": "0x2c3c5fb909767b6af655bad72f5d6638f5f5d0a0", + "key": "0x8e94fed44239eb2314ab7a406345e6c5a8f0ccedf3b600de3d004e672c33abf4", + "derived_key": [ + 105,207,185,63,169,21,50,218,22,157,164,50,155,208,136,29,218,73,246,12,13,209,254,95,239,141,35,221,253,207,221,212 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x1" + }, + { + "address": "0x2c3c5fb909767b6af655bad72f5d6638f5f5d0a0", + "key": "0xa2493ae5fceab9e59e3829df3da317d9a236c9b8b11dc1da94cb0e047a357cad", + "derived_key": [ + 248,135,166,243,99,75,238,65,244,69,142,255,92,110,93,81,203,0,116,149,135,131,96,149,14,49,60,161,204,107,128,214 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + }, + { + "address": "0x2c3c5fb909767b6af655bad72f5d6638f5f5d0a0", + "key": "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103", + "derived_key": [ + 164,102,179,128,123,95,250,209,85,215,47,223,202,234,9,179,137,135,46,66,252,162,20,55,210,106,243,173,46,40,178,89 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x36615cf349d7f6344891b1e7ca7c72883f5dc049" + }, + { + "address": "0x338bd2ded4569c568f21da174acec70b826e550c", + "key": "0x0", + "derived_key": [ + 156,179,78,101,253,32,134,94,34,150,203,47,196,201,136,120,12,142,64,149,165,101,204,29,186,80,109,39,8,84,79,232 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x8002cd98cfb563492a6fb3e7c8243b7b9ad4cc92" + }, + { + "address": "0x338bd2ded4569c568f21da174acec70b826e550c", + "key": "0x1", + "derived_key": [ + 140,190,129,206,40,197,26,241,53,110,14,80,134,5,37,204,178,45,166,159,129,221,136,86,105,96,102,217,243,16,89,249 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x683cfc9cb6230b80899dbcb6181591d69089d8a4" + }, + { + "address": "0x4c48bdb0145a89bd87f8884f3fa8c1e42d585e75", + "key": "0x0", + "derived_key": [ + 177,52,180,226,24,99,117,67,64,64,241,12,41,231,167,74,209,204,218,129,255,34,102,39,251,93,142,41,145,92,203,50 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x8ad65915f42c06ad06f23e33feee4f57060cd249" + }, + { + "address": "0x4c48bdb0145a89bd87f8884f3fa8c1e42d585e75", + "key": "0x1", + "derived_key": [ + 164,143,172,103,50,238,187,229,211,197,117,198,212,234,78,82,14,197,48,46,66,117,89,74,193,245,113,83,209,177,183,217 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x517d9f66c564d2edf43cb657424f72f1c20d3bff" + }, + { + "address": "0x517d9f66c564d2edf43cb657424f72f1c20d3bff", + "key": "0x0", + "derived_key": [ + 230,154,81,238,249,118,81,47,67,167,51,81,39,137,145,76,187,230,155,155,70,102,153,242,27,165,84,224,218,253,106,44 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0xff" + }, + { + "address": "0x5e45123c75ae6b22222a2ef40afcf080e84f5af5", + "key": "0x8e94fed44239eb2314ab7a406345e6c5a8f0ccedf3b600de3d004e672c33abf4", + "derived_key": [ + 60,175,19,171,24,127,90,244,102,215,109,52,163,108,87,248,78,75,87,18,254,157,225,108,251,34,166,46,135,226,155,114 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x1" + }, + { + "address": "0x62af78a1a86d5fa8aa7b75ee1884d36ca3c3193a", + "key": "0x0", + "derived_key": [ + 137,66,124,98,185,206,118,62,215,166,225,249,150,252,161,203,0,217,115,193,56,251,207,17,2,102,50,45,221,187,226,50 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x5de08929a3c0835232a7cd201d338317caabd8730002" + }, + { + "address": "0x62af78a1a86d5fa8aa7b75ee1884d36ca3c3193a", + "key": "0x1", + "derived_key": [ + 86,146,226,162,251,7,31,172,102,81,196,200,22,126,55,247,235,106,113,202,76,139,128,246,85,114,151,178,101,95,159,191 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x338bd2ded4569c568f21da174acec70b826e550c" + }, + { + "address": "0x62af78a1a86d5fa8aa7b75ee1884d36ca3c3193a", + "key": "0x2", + "derived_key": [ + 238,250,55,221,42,57,86,177,201,103,75,239,3,21,25,161,11,112,13,117,46,113,1,71,100,17,102,72,32,125,98,78 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x10000fd53068fc35c6a23fee067bcfd3fc0d880ba4f79d8b65aafbff02f305d" + }, + { + "address": "0x62af78a1a86d5fa8aa7b75ee1884d36ca3c3193a", + "key": "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc", + "derived_key": [ + 22,155,114,188,54,101,62,87,11,121,52,68,25,197,106,219,1,155,20,238,224,223,45,229,125,209,123,117,113,166,132,12 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0xdc0ed6fcbfe51c9f84a662e64fd1347736aa7486" + }, + { + "address": "0x62af78a1a86d5fa8aa7b75ee1884d36ca3c3193a", + "key": "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103", + "derived_key": [ + 81,122,205,57,136,220,234,247,156,218,204,189,130,97,114,48,48,160,227,48,48,64,28,58,212,244,195,137,255,228,64,41 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x8002cd98cfb563492a6fb3e7c8243b7b9ad4cc92" + }, + { + "address": "0x683cfc9cb6230b80899dbcb6181591d69089d8a4", + "key": "0x0", + "derived_key": [ + 237,236,215,194,80,85,137,94,24,27,243,41,116,140,187,70,33,135,209,48,214,17,9,198,53,117,79,21,244,235,240,208 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0xff" + }, + { + "address": "0x97b2219068b5104fd0de0a2a4666b3f6f397aca7", + "key": "0x0", + "derived_key": [ + 219,215,135,89,179,97,218,60,174,210,247,236,175,60,97,114,55,143,26,104,199,6,53,175,153,170,254,4,26,49,33,168 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x36615cf349d7f6344891b1e7ca7c72883f5dc049" + }, + { + "address": "0x97b2219068b5104fd0de0a2a4666b3f6f397aca7", + "key": "0x2", + "derived_key": [ + 131,75,158,95,145,124,241,215,162,81,17,8,190,214,110,90,15,123,1,214,244,31,200,40,196,119,19,72,17,44,27,219 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x2c3c5fb909767b6af655bad72f5d6638f5f5d0a0" + }, + { + "address": "0xdc0ed6fcbfe51c9f84a662e64fd1347736aa7486", + "key": "0x0", + "derived_key": [ + 62,110,21,209,63,190,73,44,77,121,157,143,198,176,46,157,199,11,251,128,18,248,171,99,94,148,201,218,67,21,70,232 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0xff" + }, + { + "address": "0xe024f9e4e8fa2f08f768c1cb56bc4a6e3cbd8834", + "key": "0x8e94fed44239eb2314ab7a406345e6c5a8f0ccedf3b600de3d004e672c33abf4", + "derived_key": [ + 16,46,124,130,188,155,165,96,66,61,124,176,157,94,180,222,164,199,68,147,148,121,54,59,60,181,162,4,74,28,114,103 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x1" + } + ], + "aux_commitments": { + "events_queue_commitment": "0xec82208c87a937d88768a0067b2a80f0525eca8288dad2cf96cf8bbe6a1aa565", + "bootloader_initial_content_commitment": "0x97df88dcecbcd29b49773c042cdee7a44c57a741e64913fff5aa1b3484232f28" + }, + "blob_hashes": [ + { + "commitment": "0xf840cf3f6b7dc92729b2b9ef3b399e7b896d553b746362fe81c4eb911013570d", + "linear_hash": "0xff4feb4bef9401731ab9db3626c2e015baa6880d7b1c4382d03b30da3a0fd75e" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000000", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000000", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000000", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000000", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000000", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000000", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000000", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000000", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000000", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000000", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000000", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000000", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000000", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000000", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "commitment": "0x0000000000000000000000000000000000000000000000000000000000000000", + "linear_hash": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + ], + "aggregation_root": "0x0924928c1377a6cf24c39c2d46f8eb9df23e811b26dc3527e548396fd4e173b1" + } + } +} diff --git a/core/lib/types/src/l2_to_l1_log.rs b/core/lib/types/src/l2_to_l1_log.rs index 59ade8873cd1..957cfa9a1a6a 100644 --- a/core/lib/types/src/l2_to_l1_log.rs +++ b/core/lib/types/src/l2_to_l1_log.rs @@ -1,5 +1,5 @@ use serde::{Deserialize, Serialize}; -use zksync_system_constants::{BLOB1_LINEAR_HASH_KEY, PUBDATA_CHUNK_PUBLISHER_ADDRESS}; +use zksync_system_constants::{BLOB1_LINEAR_HASH_KEY_PRE_GATEWAY, PUBDATA_CHUNK_PUBLISHER_ADDRESS}; use crate::{ blob::{num_blobs_created, num_blobs_required}, @@ -80,10 +80,15 @@ pub fn l2_to_l1_logs_tree_size(protocol_version: ProtocolVersionId) -> usize { } /// Returns the blob hashes parsed out from the system logs -pub fn parse_system_logs_for_blob_hashes( +pub fn parse_system_logs_for_blob_hashes_pre_gateway( protocol_version: &ProtocolVersionId, system_logs: &[SystemL2ToL1Log], ) -> Vec { + assert!( + protocol_version.is_pre_gateway(), + "Cannot parse blob linear hashes from system logs for post gateway" + ); + let num_required_blobs = num_blobs_required(protocol_version) as u32; let num_created_blobs = num_blobs_created(protocol_version) as u32; @@ -95,9 +100,11 @@ pub fn parse_system_logs_for_blob_hashes( .iter() .filter(|log| { log.0.sender == PUBDATA_CHUNK_PUBLISHER_ADDRESS - && log.0.key >= H256::from_low_u64_be(BLOB1_LINEAR_HASH_KEY as u64) + && log.0.key >= H256::from_low_u64_be(BLOB1_LINEAR_HASH_KEY_PRE_GATEWAY as u64) && log.0.key - < H256::from_low_u64_be((BLOB1_LINEAR_HASH_KEY + num_created_blobs) as u64) + < H256::from_low_u64_be( + (BLOB1_LINEAR_HASH_KEY_PRE_GATEWAY + num_created_blobs) as u64, + ) }) .map(|log| (log.0.key, log.0.value)) .collect::>(); diff --git a/core/lib/vm_executor/src/batch/factory.rs b/core/lib/vm_executor/src/batch/factory.rs index bc19086c9692..f974d17f4a75 100644 --- a/core/lib/vm_executor/src/batch/factory.rs +++ b/core/lib/vm_executor/src/batch/factory.rs @@ -6,6 +6,7 @@ use tokio::sync::mpsc; use zksync_multivm::{ interface::{ executor::{BatchExecutor, BatchExecutorFactory}, + pubdata::PubdataBuilder, storage::{ReadStorage, StoragePtr, StorageView, StorageViewStats}, utils::DivergenceHandler, BatchTransactionExecutionResult, BytecodeCompressionError, CompressedBytecodeInfo, @@ -13,12 +14,13 @@ use zksync_multivm::{ VmInterface, VmInterfaceHistoryEnabled, }, is_supported_by_fast_vm, + pubdata_builders::pubdata_params_to_builder, tracers::CallTracer, vm_fast, vm_latest::HistoryEnabled, FastVmInstance, LegacyVmInstance, MultiVMTracer, }; -use zksync_types::{vm::FastVmMode, Transaction}; +use zksync_types::{commitment::PubdataParams, vm::FastVmMode, Transaction}; use super::{ executor::{Command, MainBatchExecutor}, @@ -116,6 +118,7 @@ impl BatchExecutorFactory storage: S, l1_batch_params: L1BatchEnv, system_env: SystemEnv, + pubdata_params: PubdataParams, ) -> Box> { // Since we process `BatchExecutor` commands one-by-one (the next command is never enqueued // until a previous command is processed), capacity 1 is enough for the commands channel. @@ -130,8 +133,14 @@ impl BatchExecutorFactory _tracer: PhantomData::, }; - let handle = - tokio::task::spawn_blocking(move || executor.run(storage, l1_batch_params, system_env)); + let handle = tokio::task::spawn_blocking(move || { + executor.run( + storage, + l1_batch_params, + system_env, + pubdata_params_to_builder(pubdata_params), + ) + }); Box::new(MainBatchExecutor::new(handle, commands_sender)) } } @@ -183,8 +192,8 @@ impl BatchVm { dispatch_batch_vm!(self.start_new_l2_block(l2_block)); } - fn finish_batch(&mut self) -> FinishedL1Batch { - dispatch_batch_vm!(self.finish_batch()) + fn finish_batch(&mut self, pubdata_builder: Rc) -> FinishedL1Batch { + dispatch_batch_vm!(self.finish_batch(pubdata_builder)) } fn make_snapshot(&mut self) { @@ -260,6 +269,7 @@ impl CommandReceiver { storage: S, l1_batch_params: L1BatchEnv, system_env: SystemEnv, + pubdata_builder: Rc, ) -> anyhow::Result> { tracing::info!("Starting executing L1 batch #{}", &l1_batch_params.number); @@ -310,7 +320,7 @@ impl CommandReceiver { } } Command::FinishBatch(resp) => { - let vm_block_result = self.finish_batch(&mut vm)?; + let vm_block_result = self.finish_batch(&mut vm, pubdata_builder)?; if resp.send(vm_block_result).is_err() { break; } @@ -365,10 +375,14 @@ impl CommandReceiver { latency.observe(); } - fn finish_batch(&self, vm: &mut BatchVm) -> anyhow::Result { + fn finish_batch( + &self, + vm: &mut BatchVm, + pubdata_builder: Rc, + ) -> anyhow::Result { // The vm execution was paused right after the last transaction was executed. // There is some post-processing work that the VM needs to do before the block is fully processed. - let result = vm.finish_batch(); + let result = vm.finish_batch(pubdata_builder); anyhow::ensure!( !result.block_tip_execution_result.result.is_failed(), "VM must not fail when finalizing block: {:#?}", diff --git a/core/lib/vm_executor/src/oneshot/block.rs b/core/lib/vm_executor/src/oneshot/block.rs index cc759c032fc1..d6118f15b98e 100644 --- a/core/lib/vm_executor/src/oneshot/block.rs +++ b/core/lib/vm_executor/src/oneshot/block.rs @@ -203,6 +203,7 @@ impl OneshotEnvParameters { enforced_base_fee, ) .await?; + Ok(OneshotEnv { system, l1_batch, diff --git a/core/lib/vm_executor/src/oneshot/contracts.rs b/core/lib/vm_executor/src/oneshot/contracts.rs index dc9ef0c0e8df..d4e0a94f9178 100644 --- a/core/lib/vm_executor/src/oneshot/contracts.rs +++ b/core/lib/vm_executor/src/oneshot/contracts.rs @@ -67,6 +67,8 @@ pub struct MultiVMBaseSystemContracts { vm_1_5_0_increased_memory: BaseSystemContracts, /// Contracts to be used after the protocol defense upgrade vm_protocol_defense: BaseSystemContracts, + /// Contracts to be used after the gateway upgrade + gateway: BaseSystemContracts, // We use `fn() -> C` marker so that the `MultiVMBaseSystemContracts` unconditionally implements `Send + Sync`. _contracts_kind: PhantomData C>, } @@ -105,6 +107,7 @@ impl MultiVMBaseSystemContracts { ProtocolVersionId::Version25 | ProtocolVersionId::Version26 => { &self.vm_protocol_defense } + ProtocolVersionId::Version27 => &self.gateway, }; let base = base.clone(); @@ -133,6 +136,7 @@ impl MultiVMBaseSystemContracts { vm_1_5_0_increased_memory: BaseSystemContracts::estimate_gas_post_1_5_0_increased_memory(), vm_protocol_defense: BaseSystemContracts::estimate_gas_post_protocol_defense(), + gateway: BaseSystemContracts::estimate_gas_gateway(), _contracts_kind: PhantomData, } } @@ -154,6 +158,7 @@ impl MultiVMBaseSystemContracts { vm_1_5_0_increased_memory: BaseSystemContracts::playground_post_1_5_0_increased_memory( ), vm_protocol_defense: BaseSystemContracts::playground_post_protocol_defense(), + gateway: BaseSystemContracts::playground_gateway(), _contracts_kind: PhantomData, } } diff --git a/core/lib/vm_executor/src/oneshot/mod.rs b/core/lib/vm_executor/src/oneshot/mod.rs index 018e5abded6f..5f9e4dd3c6f4 100644 --- a/core/lib/vm_executor/src/oneshot/mod.rs +++ b/core/lib/vm_executor/src/oneshot/mod.rs @@ -19,8 +19,9 @@ use zksync_multivm::{ executor::{OneshotExecutor, TransactionValidator}, storage::{ReadStorage, StoragePtr, StorageView, WriteStorage}, tracer::{ValidationError, ValidationParams}, - ExecutionResult, OneshotEnv, OneshotTracingParams, OneshotTransactionExecutionResult, - StoredL2BlockEnv, TxExecutionArgs, TxExecutionMode, VmExecutionMode, VmInterface, + ExecutionResult, InspectExecutionMode, OneshotEnv, OneshotTracingParams, + OneshotTransactionExecutionResult, StoredL2BlockEnv, TxExecutionArgs, TxExecutionMode, + VmInterface, }, tracers::{CallTracer, StorageInvocations, ValidationTracer}, utils::adjust_pubdata_price_for_tx, @@ -169,7 +170,7 @@ where ); let exec_result = executor.apply(|vm, transaction| { vm.push_transaction(transaction); - vm.inspect(&mut tracers.into(), VmExecutionMode::OneTx) + vm.inspect(&mut tracers.into(), InspectExecutionMode::OneTx) }); let validation_result = Arc::make_mut(&mut validation_result) .take() diff --git a/core/lib/vm_executor/src/storage.rs b/core/lib/vm_executor/src/storage.rs index fa0e530c1909..e5a2d404233b 100644 --- a/core/lib/vm_executor/src/storage.rs +++ b/core/lib/vm_executor/src/storage.rs @@ -7,8 +7,9 @@ use zksync_contracts::BaseSystemContracts; use zksync_dal::{Connection, Core, CoreDal, DalError}; use zksync_multivm::interface::{L1BatchEnv, L2BlockEnv, SystemEnv, TxExecutionMode}; use zksync_types::{ - block::L2BlockHeader, fee_model::BatchFeeInput, snapshots::SnapshotRecoveryStatus, Address, - L1BatchNumber, L2BlockNumber, L2ChainId, ProtocolVersionId, H256, ZKPORTER_IS_AVAILABLE, + block::L2BlockHeader, commitment::PubdataParams, fee_model::BatchFeeInput, + snapshots::SnapshotRecoveryStatus, Address, L1BatchNumber, L2BlockNumber, L2ChainId, + ProtocolVersionId, H256, ZKPORTER_IS_AVAILABLE, }; const BATCH_COMPUTATIONAL_GAS_LIMIT: u32 = u32::MAX; @@ -263,7 +264,7 @@ impl L1BatchParamsProvider { first_l2_block_in_batch: &FirstL2BlockInBatch, validation_computational_gas_limit: u32, chain_id: L2ChainId, - ) -> anyhow::Result<(SystemEnv, L1BatchEnv)> { + ) -> anyhow::Result<(SystemEnv, L1BatchEnv, PubdataParams)> { anyhow::ensure!( first_l2_block_in_batch.l1_batch_number > L1BatchNumber(0), "Loading params for genesis L1 batch not supported" @@ -317,7 +318,7 @@ impl L1BatchParamsProvider { .await .context("failed getting base system contracts")?; - Ok(l1_batch_params( + let (system_env, l1_batch_env) = l1_batch_params( first_l2_block_in_batch.l1_batch_number, first_l2_block_in_batch.header.fee_account_address, l1_batch_timestamp, @@ -333,6 +334,12 @@ impl L1BatchParamsProvider { .context("`protocol_version` must be set for L2 block")?, first_l2_block_in_batch.header.virtual_blocks, chain_id, + ); + + Ok(( + system_env, + l1_batch_env, + first_l2_block_in_batch.header.pubdata_params, )) } @@ -346,7 +353,7 @@ impl L1BatchParamsProvider { number: L1BatchNumber, validation_computational_gas_limit: u32, chain_id: L2ChainId, - ) -> anyhow::Result> { + ) -> anyhow::Result> { let first_l2_block = self .load_first_l2_block_in_batch(storage, number) .await diff --git a/core/lib/vm_interface/src/executor.rs b/core/lib/vm_interface/src/executor.rs index 119f975fecd5..60522ba338a2 100644 --- a/core/lib/vm_interface/src/executor.rs +++ b/core/lib/vm_interface/src/executor.rs @@ -3,7 +3,7 @@ use std::fmt; use async_trait::async_trait; -use zksync_types::{l2::L2Tx, Transaction}; +use zksync_types::{commitment::PubdataParams, l2::L2Tx, Transaction}; use crate::{ storage::{ReadStorage, StorageView}, @@ -20,6 +20,7 @@ pub trait BatchExecutorFactory: 'static + Send + fmt::Debug { storage: S, l1_batch_params: L1BatchEnv, system_env: SystemEnv, + pubdata_params: PubdataParams, ) -> Box>; } diff --git a/core/lib/vm_interface/src/lib.rs b/core/lib/vm_interface/src/lib.rs index e0287483067a..39f949e5d8a9 100644 --- a/core/lib/vm_interface/src/lib.rs +++ b/core/lib/vm_interface/src/lib.rs @@ -24,8 +24,8 @@ pub use crate::{ VmRevertReason, VmRevertReasonParsingError, }, inputs::{ - L1BatchEnv, L2BlockEnv, OneshotEnv, OneshotTracingParams, StoredL2BlockEnv, SystemEnv, - TxExecutionArgs, TxExecutionMode, VmExecutionMode, + InspectExecutionMode, L1BatchEnv, L2BlockEnv, OneshotEnv, OneshotTracingParams, + StoredL2BlockEnv, SystemEnv, TxExecutionArgs, TxExecutionMode, VmExecutionMode, }, outputs::{ BatchTransactionExecutionResult, BootloaderMemory, Call, CallType, CircuitStatistic, @@ -41,6 +41,7 @@ pub use crate::{ }; pub mod executor; +pub mod pubdata; pub mod storage; mod types; pub mod utils; diff --git a/core/lib/vm_interface/src/pubdata/mod.rs b/core/lib/vm_interface/src/pubdata/mod.rs new file mode 100644 index 000000000000..f901687b5fa6 --- /dev/null +++ b/core/lib/vm_interface/src/pubdata/mod.rs @@ -0,0 +1,90 @@ +use zksync_types::{ + l2_to_l1_log::L2ToL1Log, writes::StateDiffRecord, Address, ProtocolVersionId, H256, U256, +}; + +/// Corresponds to the following solidity event: +/// ```solidity +/// struct L2ToL1Log { +/// uint8 l2ShardId; +/// bool isService; +/// uint16 txNumberInBlock; +/// address sender; +/// bytes32 key; +/// bytes32 value; +/// } +/// ``` +#[derive(Debug, Default, Clone, PartialEq)] +pub struct L1MessengerL2ToL1Log { + pub l2_shard_id: u8, + pub is_service: bool, + pub tx_number_in_block: u16, + pub sender: Address, + pub key: U256, + pub value: U256, +} + +impl L1MessengerL2ToL1Log { + pub fn packed_encoding(&self) -> Vec { + /// Converts `U256` value into bytes array + fn u256_to_bytes_be(value: &U256) -> Vec { + let mut bytes = vec![0u8; 32]; + value.to_big_endian(bytes.as_mut_slice()); + bytes + } + + let mut res: Vec = vec![]; + res.push(self.l2_shard_id); + res.push(self.is_service as u8); + res.extend_from_slice(&self.tx_number_in_block.to_be_bytes()); + res.extend_from_slice(self.sender.as_bytes()); + res.extend(u256_to_bytes_be(&self.key)); + res.extend(u256_to_bytes_be(&self.value)); + res + } +} + +impl From for L2ToL1Log { + fn from(log: L1MessengerL2ToL1Log) -> Self { + fn u256_to_h256(num: U256) -> H256 { + let mut bytes = [0u8; 32]; + num.to_big_endian(&mut bytes); + H256::from_slice(&bytes) + } + + L2ToL1Log { + shard_id: log.l2_shard_id, + is_service: log.is_service, + tx_number_in_block: log.tx_number_in_block, + sender: log.sender, + key: u256_to_h256(log.key), + value: u256_to_h256(log.value), + } + } +} + +/// Struct based on which the pubdata blob is formed +#[derive(Debug, Clone, Default)] +pub struct PubdataInput { + pub user_logs: Vec, + pub l2_to_l1_messages: Vec>, + pub published_bytecodes: Vec>, + pub state_diffs: Vec, +} + +/// Trait that encapsulates pubdata building logic. It is implemented for rollup and validium cases. +/// If chains needs custom pubdata format then another implementation should be added. +pub trait PubdataBuilder: std::fmt::Debug { + fn l2_da_validator(&self) -> Address; + + fn l1_messenger_operator_input( + &self, + input: &PubdataInput, + protocol_version: ProtocolVersionId, + ) -> Vec; + + fn settlement_layer_pubdata( + &self, + input: &PubdataInput, + protocol_version: ProtocolVersionId, + ) -> Vec; +} diff --git a/core/lib/vm_interface/src/types/inputs/execution_mode.rs b/core/lib/vm_interface/src/types/inputs/execution_mode.rs index 41492af6edc5..f091a259d30d 100644 --- a/core/lib/vm_interface/src/types/inputs/execution_mode.rs +++ b/core/lib/vm_interface/src/types/inputs/execution_mode.rs @@ -13,3 +13,22 @@ pub enum VmExecutionMode { /// Stop after executing the entire bootloader. But before you exit the bootloader. Bootloader, } + +/// Subset of `VmExecutionMode` variants that do not require any additional input +/// and can be invoked with `inspect` method. +#[derive(Debug, Copy, Clone)] +pub enum InspectExecutionMode { + /// Stop after executing the next transaction. + OneTx, + /// Stop after executing the entire bootloader. But before you exit the bootloader. + Bootloader, +} + +impl From for VmExecutionMode { + fn from(mode: InspectExecutionMode) -> Self { + match mode { + InspectExecutionMode::Bootloader => Self::Bootloader, + InspectExecutionMode::OneTx => Self::OneTx, + } + } +} diff --git a/core/lib/vm_interface/src/types/inputs/mod.rs b/core/lib/vm_interface/src/types/inputs/mod.rs index 24f58ae72f16..cb80ba7c1386 100644 --- a/core/lib/vm_interface/src/types/inputs/mod.rs +++ b/core/lib/vm_interface/src/types/inputs/mod.rs @@ -3,7 +3,7 @@ use zksync_types::{ }; pub use self::{ - execution_mode::VmExecutionMode, + execution_mode::{InspectExecutionMode, VmExecutionMode}, l1_batch_env::L1BatchEnv, l2_block::{L2BlockEnv, StoredL2BlockEnv}, system_env::{SystemEnv, TxExecutionMode}, diff --git a/core/lib/vm_interface/src/utils/dump.rs b/core/lib/vm_interface/src/utils/dump.rs index 4076aa72270b..f23d6f307b89 100644 --- a/core/lib/vm_interface/src/utils/dump.rs +++ b/core/lib/vm_interface/src/utils/dump.rs @@ -1,13 +1,14 @@ -use std::collections::HashMap; +use std::{collections::HashMap, rc::Rc}; use serde::{Deserialize, Serialize}; use zksync_types::{block::L2BlockExecutionData, L1BatchNumber, L2BlockNumber, Transaction, H256}; use crate::{ + pubdata::PubdataBuilder, storage::{ReadStorage, StoragePtr, StorageSnapshot, StorageView}, - BytecodeCompressionResult, FinishedL1Batch, L1BatchEnv, L2BlockEnv, PushTransactionResult, - SystemEnv, VmExecutionMode, VmExecutionResultAndLogs, VmFactory, VmInterface, VmInterfaceExt, - VmInterfaceHistoryEnabled, VmTrackingContracts, + BytecodeCompressionResult, FinishedL1Batch, InspectExecutionMode, L1BatchEnv, L2BlockEnv, + PushTransactionResult, SystemEnv, VmExecutionResultAndLogs, VmFactory, VmInterface, + VmInterfaceExt, VmInterfaceHistoryEnabled, VmTrackingContracts, }; fn create_storage_snapshot( @@ -48,6 +49,7 @@ fn create_storage_snapshot( } /// VM dump allowing to re-run the VM on the same inputs. Can be (de)serialized. +/// Note, dump is not capable of finishing batch in terms of VM execution. #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] pub struct VmDump { pub l1_batch_env: L1BatchEnv, @@ -98,7 +100,6 @@ impl VmDump { } } } - vm.finish_batch(); vm } } @@ -162,7 +163,7 @@ impl VmInterface for DumpingVm { fn inspect( &mut self, dispatcher: &mut Self::TracerDispatcher, - execution_mode: VmExecutionMode, + execution_mode: InspectExecutionMode, ) -> VmExecutionResultAndLogs { self.inner.inspect(dispatcher, execution_mode) } @@ -189,8 +190,8 @@ impl VmInterface for DumpingVm { .inspect_transaction_with_bytecode_compression(tracer, tx, with_compression) } - fn finish_batch(&mut self) -> FinishedL1Batch { - self.inner.finish_batch() + fn finish_batch(&mut self, pubdata_builder: Rc) -> FinishedL1Batch { + self.inner.finish_batch(pubdata_builder) } } diff --git a/core/lib/vm_interface/src/utils/shadow.rs b/core/lib/vm_interface/src/utils/shadow.rs index e8ef87c3c7f8..d12d85fa2e3a 100644 --- a/core/lib/vm_interface/src/utils/shadow.rs +++ b/core/lib/vm_interface/src/utils/shadow.rs @@ -3,6 +3,7 @@ use std::{ cell::RefCell, collections::{BTreeMap, BTreeSet}, fmt, + rc::Rc, sync::Arc, }; @@ -10,9 +11,10 @@ use zksync_types::{StorageKey, StorageLog, StorageLogWithPreviousValue, Transact use super::dump::{DumpingVm, VmDump}; use crate::{ + pubdata::PubdataBuilder, storage::{ReadStorage, StoragePtr, StorageView}, - BytecodeCompressionResult, CurrentExecutionState, FinishedL1Batch, L1BatchEnv, L2BlockEnv, - PushTransactionResult, SystemEnv, VmExecutionMode, VmExecutionResultAndLogs, VmFactory, + BytecodeCompressionResult, CurrentExecutionState, FinishedL1Batch, InspectExecutionMode, + L1BatchEnv, L2BlockEnv, PushTransactionResult, SystemEnv, VmExecutionResultAndLogs, VmFactory, VmInterface, VmInterfaceHistoryEnabled, VmTrackingContracts, }; @@ -332,7 +334,7 @@ where where Shadow: VmFactory, { - let main = DumpingVm::new(batch_env.clone(), system_env.clone(), storage.clone()); + let main = DumpingVm::new(batch_env.clone(), system_env.clone(), storage); let shadow = Shadow::new(batch_env.clone(), system_env.clone(), shadow_storage); let shadow = VmWithReporting { vm: shadow, @@ -400,7 +402,7 @@ where fn inspect( &mut self, (main_tracer, shadow_tracer): &mut Self::TracerDispatcher, - execution_mode: VmExecutionMode, + execution_mode: InspectExecutionMode, ) -> VmExecutionResultAndLogs { let main_result = self.main.inspect(main_tracer, execution_mode); if let Some(shadow) = self.shadow.get_mut() { @@ -457,10 +459,10 @@ where (main_bytecodes_result, main_tx_result) } - fn finish_batch(&mut self) -> FinishedL1Batch { - let main_batch = self.main.finish_batch(); + fn finish_batch(&mut self, pubdata_builder: Rc) -> FinishedL1Batch { + let main_batch = self.main.finish_batch(pubdata_builder.clone()); if let Some(shadow) = self.shadow.get_mut() { - let shadow_batch = shadow.vm.finish_batch(); + let shadow_batch = shadow.vm.finish_batch(pubdata_builder); let errors = main_batch.check_divergence(&shadow_batch); if let Err(err) = errors.into_result() { self.report(err); diff --git a/core/lib/vm_interface/src/vm.rs b/core/lib/vm_interface/src/vm.rs index 3a06d7f80cbe..2c25d729e318 100644 --- a/core/lib/vm_interface/src/vm.rs +++ b/core/lib/vm_interface/src/vm.rs @@ -11,11 +11,14 @@ //! Generally speaking, in most cases, the tracer dispatcher is a wrapper around `Vec>`, //! where `VmTracer` is a trait implemented for a specific VM version. +use std::rc::Rc; + use zksync_types::{Transaction, H256}; use crate::{ - storage::StoragePtr, BytecodeCompressionResult, FinishedL1Batch, L1BatchEnv, L2BlockEnv, - PushTransactionResult, SystemEnv, VmExecutionMode, VmExecutionResultAndLogs, + pubdata::PubdataBuilder, storage::StoragePtr, BytecodeCompressionResult, FinishedL1Batch, + InspectExecutionMode, L1BatchEnv, L2BlockEnv, PushTransactionResult, SystemEnv, + VmExecutionResultAndLogs, }; pub trait VmInterface { @@ -35,7 +38,7 @@ pub trait VmInterface { fn inspect( &mut self, dispatcher: &mut Self::TracerDispatcher, - execution_mode: VmExecutionMode, + execution_mode: InspectExecutionMode, ) -> VmExecutionResultAndLogs; /// Start a new L2 block. @@ -51,13 +54,13 @@ pub trait VmInterface { /// Execute batch till the end and return the result, with final execution state /// and bootloader memory. - fn finish_batch(&mut self) -> FinishedL1Batch; + fn finish_batch(&mut self, pubdata_builder: Rc) -> FinishedL1Batch; } /// Extension trait for [`VmInterface`] that provides some additional methods. pub trait VmInterfaceExt: VmInterface { /// Executes the next VM step (either next transaction or bootloader or the whole batch). - fn execute(&mut self, execution_mode: VmExecutionMode) -> VmExecutionResultAndLogs { + fn execute(&mut self, execution_mode: InspectExecutionMode) -> VmExecutionResultAndLogs { self.inspect(&mut ::default(), execution_mode) } diff --git a/core/node/api_server/src/web3/state.rs b/core/node/api_server/src/web3/state.rs index 18c206eaf584..a2aee8c7420a 100644 --- a/core/node/api_server/src/web3/state.rs +++ b/core/node/api_server/src/web3/state.rs @@ -146,6 +146,7 @@ impl InternalApiConfig { .l1_weth_bridge_proxy_addr .unwrap_or_default(), ), + l2_legacy_shared_bridge: contracts_config.l2_legacy_shared_bridge_addr, }, bridgehub_proxy_addr: contracts_config .ecosystem_contracts diff --git a/core/node/block_reverter/src/tests.rs b/core/node/block_reverter/src/tests.rs index 85d894b7fd57..b2c4ee6465f6 100644 --- a/core/node/block_reverter/src/tests.rs +++ b/core/node/block_reverter/src/tests.rs @@ -67,6 +67,7 @@ async fn setup_storage(storage: &mut Connection<'_, Core>, storage_logs: &[Stora virtual_blocks: 1, gas_limit: 0, logs_bloom: Default::default(), + pubdata_params: Default::default(), }; storage .blocks_dal() diff --git a/core/node/commitment_generator/Cargo.toml b/core/node/commitment_generator/Cargo.toml index 5ec8410124fc..1f4645414cbd 100644 --- a/core/node/commitment_generator/Cargo.toml +++ b/core/node/commitment_generator/Cargo.toml @@ -20,6 +20,7 @@ zksync_utils.workspace = true zksync_eth_client.workspace = true zksync_contracts.workspace = true zksync_multivm.workspace = true +zksync_system_constants.workspace = true circuit_sequencer_api_1_4_0.workspace = true circuit_sequencer_api_1_4_1.workspace = true circuit_sequencer_api_1_5_0.workspace = true diff --git a/core/node/commitment_generator/src/lib.rs b/core/node/commitment_generator/src/lib.rs index cf6971b041c6..9a33d4766f6e 100644 --- a/core/node/commitment_generator/src/lib.rs +++ b/core/node/commitment_generator/src/lib.rs @@ -9,7 +9,7 @@ use zksync_l1_contract_interface::i_executor::commit::kzg::pubdata_to_blob_commi use zksync_types::{ blob::num_blobs_required, commitment::{ - AuxCommitments, CommitmentCommonInput, CommitmentInput, L1BatchAuxiliaryOutput, + AuxCommitments, BlobHash, CommitmentCommonInput, CommitmentInput, L1BatchAuxiliaryOutput, L1BatchCommitment, L1BatchCommitmentArtifacts, L1BatchCommitmentMode, }, writes::{InitialStorageWrite, RepeatedStorageWrite, StateDiffRecord}, @@ -19,7 +19,10 @@ use zksync_utils::h256_to_u256; use crate::{ metrics::{CommitmentStage, METRICS}, - utils::{convert_vm_events_to_log_queries, CommitmentComputer, RealCommitmentComputer}, + utils::{ + convert_vm_events_to_log_queries, pubdata_to_blob_linear_hashes, read_aggregation_root, + CommitmentComputer, RealCommitmentComputer, + }, }; mod metrics; @@ -263,14 +266,40 @@ impl CommitmentGenerator { } state_diffs.sort_unstable_by_key(|rec| (rec.address, rec.key)); - let blob_commitments = if protocol_version.is_post_1_4_2() { + let blob_hashes = if protocol_version.is_post_1_4_2() { let pubdata_input = header.pubdata_input.with_context(|| { format!("`pubdata_input` is missing for L1 batch #{l1_batch_number}") })?; - pubdata_to_blob_commitments(num_blobs_required(&protocol_version), &pubdata_input) + let commitments = pubdata_to_blob_commitments( + num_blobs_required(&protocol_version), + &pubdata_input, + ); + let linear_hashes = pubdata_to_blob_linear_hashes( + num_blobs_required(&protocol_version), + pubdata_input, + ); + + commitments + .into_iter() + .zip(linear_hashes) + .map(|(commitment, linear_hash)| BlobHash { + commitment, + linear_hash, + }) + .collect::>() } else { - vec![H256::zero(); num_blobs_required(&protocol_version)] + vec![Default::default(); num_blobs_required(&protocol_version)] + }; + + let aggregation_root = if protocol_version.is_pre_gateway() { + let mut connection = self + .connection_pool + .connection_tagged("commitment_generator") + .await?; + read_aggregation_root(&mut connection, l1_batch_number).await? + } else { + H256::zero() }; CommitmentInput::PostBoojum { @@ -278,7 +307,8 @@ impl CommitmentGenerator { system_logs: header.system_logs, state_diffs, aux_commitments, - blob_commitments, + blob_hashes, + aggregation_root, } }; @@ -357,14 +387,10 @@ impl CommitmentGenerator { (L1BatchCommitmentMode::Rollup, _) => { // Do nothing } - - ( - L1BatchCommitmentMode::Validium, - CommitmentInput::PostBoojum { - blob_commitments, .. - }, - ) => { - blob_commitments.fill(H256::zero()); + (L1BatchCommitmentMode::Validium, CommitmentInput::PostBoojum { blob_hashes, .. }) => { + for hashes in blob_hashes { + hashes.commitment = H256::zero(); + } } (L1BatchCommitmentMode::Validium, _) => { /* Do nothing */ } } @@ -374,14 +400,9 @@ impl CommitmentGenerator { match (self.commitment_mode, &mut commitment.auxiliary_output) { ( L1BatchCommitmentMode::Validium, - L1BatchAuxiliaryOutput::PostBoojum { - blob_linear_hashes, - blob_commitments, - .. - }, + L1BatchAuxiliaryOutput::PostBoojum { blob_hashes, .. }, ) => { - blob_linear_hashes.fill(H256::zero()); - blob_commitments.fill(H256::zero()); + blob_hashes.fill(Default::default()); } _ => { /* Do nothing */ } } diff --git a/core/node/commitment_generator/src/utils.rs b/core/node/commitment_generator/src/utils.rs index 86643b6b581b..d405a1256a29 100644 --- a/core/node/commitment_generator/src/utils.rs +++ b/core/node/commitment_generator/src/utils.rs @@ -2,6 +2,7 @@ use std::fmt; +use anyhow::Context; use itertools::Itertools; use zk_evm_1_3_3::{ aux_structures::Timestamp as Timestamp_1_3_3, @@ -15,13 +16,18 @@ use zk_evm_1_5_0::{ aux_structures::Timestamp as Timestamp_1_5_0, zk_evm_abstractions::queries::LogQuery as LogQuery_1_5_0, }; +use zksync_dal::{Connection, Core, CoreDal}; +use zksync_l1_contract_interface::i_executor::commit::kzg::ZK_SYNC_BYTES_PER_BLOB; use zksync_multivm::{interface::VmEvent, utils::get_used_bootloader_memory_bytes}; +use zksync_system_constants::message_root::{AGG_TREE_HEIGHT_KEY, AGG_TREE_NODES_KEY}; use zksync_types::{ vm::VmVersion, + web3::keccak256, zk_evm_types::{LogQuery, Timestamp}, - ProtocolVersionId, EVENT_WRITER_ADDRESS, H256, U256, + AccountTreeId, L1BatchNumber, ProtocolVersionId, StorageKey, EVENT_WRITER_ADDRESS, H256, + L2_MESSAGE_ROOT_ADDRESS, U256, }; -use zksync_utils::{address_to_u256, expand_memory_contents, h256_to_u256}; +use zksync_utils::{address_to_u256, expand_memory_contents, h256_to_u256, u256_to_h256}; /// Encapsulates computations of commitment components. /// @@ -68,7 +74,8 @@ impl CommitmentComputer for RealCommitmentComputer { ), )), VmVersion::Vm1_5_0SmallBootloaderMemory - | VmVersion::Vm1_5_0IncreasedBootloaderMemory => Ok(H256( + | VmVersion::Vm1_5_0IncreasedBootloaderMemory + | VmVersion::VmGateway => Ok(H256( circuit_sequencer_api_1_5_0::commitments::events_queue_commitment_fixed( &events_queue .iter() @@ -106,7 +113,8 @@ impl CommitmentComputer for RealCommitmentComputer { ), )), VmVersion::Vm1_5_0SmallBootloaderMemory - | VmVersion::Vm1_5_0IncreasedBootloaderMemory => Ok(H256( + | VmVersion::Vm1_5_0IncreasedBootloaderMemory + | VmVersion::VmGateway => Ok(H256( circuit_sequencer_api_1_5_0::commitments::initial_heap_content_commitment_fixed( &full_bootloader_memory, ), @@ -234,3 +242,75 @@ pub(crate) fn convert_vm_events_to_log_queries(events: &[VmEvent]) -> Vec, +) -> Vec { + // Now, we need to calculate the linear hashes of the blobs. + // Firstly, let's pad the pubdata to the size of the blob. + if pubdata_input.len() % ZK_SYNC_BYTES_PER_BLOB != 0 { + pubdata_input.resize( + pubdata_input.len() + + (ZK_SYNC_BYTES_PER_BLOB - pubdata_input.len() % ZK_SYNC_BYTES_PER_BLOB), + 0, + ); + } + + let mut result = vec![H256::zero(); blobs_required]; + + pubdata_input + .chunks(ZK_SYNC_BYTES_PER_BLOB) + .enumerate() + .for_each(|(i, chunk)| { + result[i] = H256(keccak256(chunk)); + }); + + result +} + +pub(crate) async fn read_aggregation_root( + connection: &mut Connection<'_, Core>, + l1_batch_number: L1BatchNumber, +) -> anyhow::Result { + let (_, last_l2_block) = connection + .blocks_dal() + .get_l2_block_range_of_l1_batch(l1_batch_number) + .await? + .context("No range for batch")?; + + let agg_tree_height_slot = StorageKey::new( + AccountTreeId::new(L2_MESSAGE_ROOT_ADDRESS), + H256::from_low_u64_be(AGG_TREE_HEIGHT_KEY as u64), + ); + + let agg_tree_height = connection + .storage_web3_dal() + .get_historical_value_unchecked(agg_tree_height_slot.hashed_key(), last_l2_block) + .await?; + let agg_tree_height = h256_to_u256(agg_tree_height); + + // `nodes[height][0]` + let agg_tree_root_hash_key = + n_dim_array_key_in_layout(AGG_TREE_NODES_KEY, &[agg_tree_height, U256::zero()]); + let agg_tree_root_hash_slot = StorageKey::new( + AccountTreeId::new(L2_MESSAGE_ROOT_ADDRESS), + agg_tree_root_hash_key, + ); + + Ok(connection + .storage_web3_dal() + .get_historical_value_unchecked(agg_tree_root_hash_slot.hashed_key(), last_l2_block) + .await?) +} + +fn n_dim_array_key_in_layout(array_key: usize, indices: &[U256]) -> H256 { + let mut key: H256 = u256_to_h256(array_key.into()); + + for index in indices { + key = H256(keccak256(key.as_bytes())); + key = u256_to_h256(h256_to_u256(key).overflowing_add(*index).0); + } + + key +} diff --git a/core/node/consensus/src/storage/store.rs b/core/node/consensus/src/storage/store.rs index 7267d7e1c822..53be2fc63c75 100644 --- a/core/node/consensus/src/storage/store.rs +++ b/core/node/consensus/src/storage/store.rs @@ -28,6 +28,13 @@ fn to_fetched_block( .context("Integer overflow converting block number")?, ); let payload = Payload::decode(payload).context("Payload::decode()")?; + let pubdata_params = if payload.protocol_version.is_pre_gateway() { + payload.pubdata_params.unwrap_or_default() + } else { + payload + .pubdata_params + .context("Missing `pubdata_params` for post-gateway payload")? + }; Ok(FetchedBlock { number, l1_batch_number: payload.l1_batch_number, @@ -38,6 +45,7 @@ fn to_fetched_block( l1_gas_price: payload.l1_gas_price, l2_fair_gas_price: payload.l2_fair_gas_price, fair_pubdata_price: payload.fair_pubdata_price, + pubdata_params, virtual_blocks: payload.virtual_blocks, operator_address: payload.operator_address, transactions: payload diff --git a/core/node/consensus/src/testonly.rs b/core/node/consensus/src/testonly.rs index 4ebcf5c9a617..db433665e570 100644 --- a/core/node/consensus/src/testonly.rs +++ b/core/node/consensus/src/testonly.rs @@ -295,6 +295,7 @@ impl StateKeeper { timestamp: self.last_timestamp, virtual_blocks: 1, }, + pubdata_params: Default::default(), }, number: self.last_batch, first_l2_block_number: self.last_block, @@ -568,9 +569,11 @@ impl StateKeeperRunner { let (stop_send, stop_recv) = sync::watch::channel(false); let (persistence, l2_block_sealer) = StateKeeperPersistence::new( self.pool.0.clone(), - ethabi::Address::repeat_byte(11), + Some(ethabi::Address::repeat_byte(11)), 5, - ); + ) + .await + .unwrap(); let io = ExternalIO::new( self.pool.0.clone(), @@ -675,9 +678,11 @@ impl StateKeeperRunner { let (stop_send, stop_recv) = sync::watch::channel(false); let (persistence, l2_block_sealer) = StateKeeperPersistence::new( self.pool.0.clone(), - ethabi::Address::repeat_byte(11), + Some(ethabi::Address::repeat_byte(11)), 5, - ); + ) + .await + .unwrap(); let tree_writes_persistence = TreeWritesPersistence::new(self.pool.0.clone()); let io = ExternalIO::new( diff --git a/core/node/db_pruner/src/tests.rs b/core/node/db_pruner/src/tests.rs index a5458e996e1e..99fbada423dc 100644 --- a/core/node/db_pruner/src/tests.rs +++ b/core/node/db_pruner/src/tests.rs @@ -122,6 +122,7 @@ async fn insert_l2_blocks( virtual_blocks: 0, gas_limit: 0, logs_bloom: Default::default(), + pubdata_params: Default::default(), }; conn.blocks_dal() diff --git a/core/node/eth_sender/src/tests.rs b/core/node/eth_sender/src/tests.rs index 9e844a8b8537..8e5032a69cfc 100644 --- a/core/node/eth_sender/src/tests.rs +++ b/core/node/eth_sender/src/tests.rs @@ -126,6 +126,10 @@ pub(crate) fn default_l1_batch_metadata() -> L1BatchMetadata { events_queue_commitment: Some(H256::zero()), bootloader_initial_content_commitment: Some(H256::zero()), state_diffs_compressed: vec![], + state_diff_hash: Some(H256::default()), + local_root: Some(H256::default()), + aggregation_root: Some(H256::default()), + da_inclusion_data: Some(vec![]), } } diff --git a/core/node/eth_watch/src/lib.rs b/core/node/eth_watch/src/lib.rs index a832733b3559..4185878d2ac4 100644 --- a/core/node/eth_watch/src/lib.rs +++ b/core/node/eth_watch/src/lib.rs @@ -140,7 +140,7 @@ impl EthWatch { let finalized_block = client.finalized_block_number().await?; let from_block = storage - .processed_events_dal() + .eth_watcher_dal() .get_or_set_next_block_to_process( processor.event_type(), chain_id, @@ -180,7 +180,7 @@ impl EthWatch { }; storage - .processed_events_dal() + .eth_watcher_dal() .update_next_block_to_process( processor.event_type(), chain_id, diff --git a/core/node/fee_model/src/l1_gas_price/gas_adjuster/mod.rs b/core/node/fee_model/src/l1_gas_price/gas_adjuster/mod.rs index 459b8855b961..6fce46f77225 100644 --- a/core/node/fee_model/src/l1_gas_price/gas_adjuster/mod.rs +++ b/core/node/fee_model/src/l1_gas_price/gas_adjuster/mod.rs @@ -88,8 +88,8 @@ impl GasAdjuster { anyhow::ensure!(client.gateway_mode, "Must be L2 client in L2 mode"); anyhow::ensure!( - matches!(pubdata_sending_mode, PubdataSendingMode::RelayedL2Calldata), - "Only relayed L2 calldata is available for L2 mode, got: {pubdata_sending_mode:?}" + matches!(pubdata_sending_mode, PubdataSendingMode::RelayedL2Calldata | PubdataSendingMode::Custom), + "Only relayed L2 calldata or Custom is available for L2 mode, got: {pubdata_sending_mode:?}" ); } else { anyhow::ensure!(!client.gateway_mode, "Must be L1 client in L1 mode"); diff --git a/core/node/genesis/src/lib.rs b/core/node/genesis/src/lib.rs index 3e4c0ee30b94..82732342b407 100644 --- a/core/node/genesis/src/lib.rs +++ b/core/node/genesis/src/lib.rs @@ -409,6 +409,7 @@ pub async fn create_genesis_l1_batch( virtual_blocks: 0, gas_limit: 0, logs_bloom: Bloom::zero(), + pubdata_params: Default::default(), }; let mut transaction = storage.start_transaction().await?; diff --git a/core/node/logs_bloom_backfill/src/lib.rs b/core/node/logs_bloom_backfill/src/lib.rs index 4337c0b8dc97..368d2edaf698 100644 --- a/core/node/logs_bloom_backfill/src/lib.rs +++ b/core/node/logs_bloom_backfill/src/lib.rs @@ -158,6 +158,7 @@ mod tests { virtual_blocks: 0, gas_limit: 0, logs_bloom: Default::default(), + pubdata_params: Default::default(), }; conn.blocks_dal() diff --git a/core/node/node_framework/src/implementations/layers/state_keeper/mempool_io.rs b/core/node/node_framework/src/implementations/layers/state_keeper/mempool_io.rs index ec2c415b9bbd..77992f34c7f5 100644 --- a/core/node/node_framework/src/implementations/layers/state_keeper/mempool_io.rs +++ b/core/node/node_framework/src/implementations/layers/state_keeper/mempool_io.rs @@ -4,7 +4,7 @@ use zksync_config::configs::{ wallets, }; use zksync_state_keeper::{MempoolFetcher, MempoolGuard, MempoolIO, SequencerSealer}; -use zksync_types::L2ChainId; +use zksync_types::{commitment::L1BatchCommitmentMode, Address, L2ChainId}; use crate::{ implementations::resources::{ @@ -39,6 +39,8 @@ pub struct MempoolIOLayer { state_keeper_config: StateKeeperConfig, mempool_config: MempoolConfig, wallets: wallets::StateKeeper, + l2_da_validator_addr: Option
, + l1_batch_commit_data_generator_mode: L1BatchCommitmentMode, } #[derive(Debug, FromContext)] @@ -63,12 +65,16 @@ impl MempoolIOLayer { state_keeper_config: StateKeeperConfig, mempool_config: MempoolConfig, wallets: wallets::StateKeeper, + l2_da_validator_addr: Option
, + l1_batch_commit_data_generator_mode: L1BatchCommitmentMode, ) -> Self { Self { zksync_network_id, state_keeper_config, mempool_config, wallets, + l2_da_validator_addr, + l1_batch_commit_data_generator_mode, } } @@ -129,6 +135,8 @@ impl WiringLayer for MempoolIOLayer { self.wallets.fee_account.address(), self.mempool_config.delay_interval(), self.zksync_network_id, + self.l2_da_validator_addr, + self.l1_batch_commit_data_generator_mode, )?; // Create sealer. diff --git a/core/node/node_framework/src/implementations/layers/state_keeper/output_handler.rs b/core/node/node_framework/src/implementations/layers/state_keeper/output_handler.rs index 5f63e4e19475..1a07591c1cd9 100644 --- a/core/node/node_framework/src/implementations/layers/state_keeper/output_handler.rs +++ b/core/node/node_framework/src/implementations/layers/state_keeper/output_handler.rs @@ -35,7 +35,7 @@ use crate::{ /// - `L2BlockSealerTask` #[derive(Debug)] pub struct OutputHandlerLayer { - l2_shared_bridge_addr: Address, + l2_legacy_shared_bridge_addr: Option
, l2_block_seal_queue_capacity: usize, /// Whether transactions should be pre-inserted to DB. /// Should be set to `true` for EN's IO as EN doesn't store transactions in DB @@ -63,9 +63,12 @@ pub struct Output { } impl OutputHandlerLayer { - pub fn new(l2_shared_bridge_addr: Address, l2_block_seal_queue_capacity: usize) -> Self { + pub fn new( + l2_legacy_shared_bridge_addr: Option
, + l2_block_seal_queue_capacity: usize, + ) -> Self { Self { - l2_shared_bridge_addr, + l2_legacy_shared_bridge_addr, l2_block_seal_queue_capacity, pre_insert_txs: false, protective_reads_persistence_enabled: false, @@ -103,11 +106,13 @@ impl WiringLayer for OutputHandlerLayer { .get_custom(L2BlockSealProcess::subtasks_len()) .await .context("Get master pool")?; + let (mut persistence, l2_block_sealer) = StateKeeperPersistence::new( persistence_pool.clone(), - self.l2_shared_bridge_addr, + self.l2_legacy_shared_bridge_addr, self.l2_block_seal_queue_capacity, - ); + ) + .await?; if self.pre_insert_txs { persistence = persistence.with_tx_insertion(); } diff --git a/core/node/node_sync/src/external_io.rs b/core/node/node_sync/src/external_io.rs index a0be233a002e..1be7e00543f1 100644 --- a/core/node/node_sync/src/external_io.rs +++ b/core/node/node_sync/src/external_io.rs @@ -251,7 +251,7 @@ impl StateKeeperIO for ExternalIO { pending_l2_block_header.set_protocol_version(protocol_version); } - let (system_env, l1_batch_env) = self + let (system_env, l1_batch_env, pubdata_params) = self .l1_batch_params_provider .load_l1_batch_params( &mut storage, @@ -274,7 +274,7 @@ impl StateKeeperIO for ExternalIO { .into_unsealed_header(Some(system_env.version)), ) .await?; - let data = load_pending_batch(&mut storage, system_env, l1_batch_env) + let data = load_pending_batch(&mut storage, system_env, l1_batch_env, pubdata_params) .await .with_context(|| { format!( @@ -529,6 +529,7 @@ mod tests { timestamp: 1, virtual_blocks: 1, }, + pubdata_params: Default::default(), }; actions_sender .push_action_unchecked(SyncAction::OpenBatch { diff --git a/core/node/node_sync/src/fetcher.rs b/core/node/node_sync/src/fetcher.rs index 51b9f7c7a060..9c76d1d93ca3 100644 --- a/core/node/node_sync/src/fetcher.rs +++ b/core/node/node_sync/src/fetcher.rs @@ -1,9 +1,10 @@ +use anyhow::Context; use zksync_dal::{Connection, Core, CoreDal}; use zksync_shared_metrics::{TxStage, APP_METRICS}; use zksync_state_keeper::io::{common::IoCursor, L1BatchParams, L2BlockParams}; use zksync_types::{ - api::en::SyncBlock, block::L2BlockHasher, fee_model::BatchFeeInput, helpers::unix_timestamp_ms, - Address, L1BatchNumber, L2BlockNumber, ProtocolVersionId, H256, + api::en::SyncBlock, block::L2BlockHasher, commitment::PubdataParams, fee_model::BatchFeeInput, + helpers::unix_timestamp_ms, Address, L1BatchNumber, L2BlockNumber, ProtocolVersionId, H256, }; use super::{ @@ -51,6 +52,7 @@ pub struct FetchedBlock { pub virtual_blocks: u32, pub operator_address: Address, pub transactions: Vec, + pub pubdata_params: PubdataParams, } impl FetchedBlock { @@ -77,6 +79,14 @@ impl TryFrom for FetchedBlock { )); } + let pubdata_params = if block.protocol_version.is_pre_gateway() { + block.pubdata_params.unwrap_or_default() + } else { + block + .pubdata_params + .context("Missing `pubdata_params` for post-gateway payload")? + }; + Ok(Self { number: block.number, l1_batch_number: block.l1_batch_number, @@ -93,6 +103,7 @@ impl TryFrom for FetchedBlock { .into_iter() .map(FetchedTransaction::new) .collect(), + pubdata_params, }) } } @@ -165,6 +176,7 @@ impl IoCursorExt for IoCursor { timestamp: block.timestamp, virtual_blocks: block.virtual_blocks, }, + pubdata_params: block.pubdata_params, }, number: block.l1_batch_number, first_l2_block_number: block.number, diff --git a/core/node/node_sync/src/sync_action.rs b/core/node/node_sync/src/sync_action.rs index e3fd56ae9bb0..897abfafb2a6 100644 --- a/core/node/node_sync/src/sync_action.rs +++ b/core/node/node_sync/src/sync_action.rs @@ -198,6 +198,7 @@ mod tests { timestamp: 1, virtual_blocks: 1, }, + pubdata_params: Default::default(), }, number: L1BatchNumber(1), first_l2_block_number: L2BlockNumber(1), diff --git a/core/node/node_sync/src/tests.rs b/core/node/node_sync/src/tests.rs index 1ae148709b22..172a00e8c14c 100644 --- a/core/node/node_sync/src/tests.rs +++ b/core/node/node_sync/src/tests.rs @@ -44,6 +44,7 @@ fn open_l1_batch(number: u32, timestamp: u64, first_l2_block_number: u32) -> Syn timestamp, virtual_blocks: 1, }, + pubdata_params: Default::default(), }, number: L1BatchNumber(number), first_l2_block_number: L2BlockNumber(first_l2_block_number), @@ -67,6 +68,7 @@ impl MockMainNodeClient { virtual_blocks: Some(0), hash: Some(snapshot.l2_block_hash), protocol_version: ProtocolVersionId::latest(), + pubdata_params: Default::default(), }; Self { @@ -106,7 +108,9 @@ impl StateKeeperHandles { let sync_state = SyncState::default(); let (persistence, l2_block_sealer) = - StateKeeperPersistence::new(pool.clone(), Address::repeat_byte(1), 5); + StateKeeperPersistence::new(pool.clone(), Some(Address::repeat_byte(1)), 5) + .await + .unwrap(); let tree_writes_persistence = TreeWritesPersistence::new(pool.clone()); let output_handler = OutputHandler::new(Box::new(persistence.with_tx_insertion())) .with_handler(Box::new(tree_writes_persistence)) diff --git a/core/node/proof_data_handler/src/request_processor.rs b/core/node/proof_data_handler/src/request_processor.rs index ee266a88971e..89304724a7c2 100644 --- a/core/node/proof_data_handler/src/request_processor.rs +++ b/core/node/proof_data_handler/src/request_processor.rs @@ -17,7 +17,7 @@ use zksync_types::{ basic_fri_types::Eip4844Blobs, commitment::{serialize_commitments, L1BatchCommitmentMode}, web3::keccak256, - L1BatchNumber, H256, + L1BatchNumber, ProtocolVersionId, H256, STATE_DIFF_HASH_KEY_PRE_GATEWAY, }; use crate::{errors::RequestProcessorError, metrics::METRICS}; @@ -226,58 +226,63 @@ impl RequestProcessor { .unwrap() .expect("Proved block without metadata"); - let is_pre_boojum = l1_batch + let protocol_version = l1_batch .header .protocol_version - .map(|v| v.is_pre_boojum()) - .unwrap_or(true); - if !is_pre_boojum { - let events_queue_state = l1_batch - .metadata - .events_queue_commitment - .expect("No events_queue_commitment"); - let bootloader_heap_initial_content = l1_batch - .metadata - .bootloader_initial_content_commitment - .expect("No bootloader_initial_content_commitment"); - - if events_queue_state != events_queue_state_from_prover - || bootloader_heap_initial_content - != bootloader_heap_initial_content_from_prover - { - let server_values = format!("events_queue_state = {events_queue_state}, bootloader_heap_initial_content = {bootloader_heap_initial_content}"); - let prover_values = format!("events_queue_state = {events_queue_state_from_prover}, bootloader_heap_initial_content = {bootloader_heap_initial_content_from_prover}"); - panic!( - "Auxilary output doesn't match, server values: {} prover values: {}", - server_values, prover_values - ); - } + .unwrap_or_else(ProtocolVersionId::last_potentially_undefined); + + let events_queue_state = l1_batch + .metadata + .events_queue_commitment + .expect("No events_queue_commitment"); + let bootloader_heap_initial_content = l1_batch + .metadata + .bootloader_initial_content_commitment + .expect("No bootloader_initial_content_commitment"); + + if events_queue_state != events_queue_state_from_prover + || bootloader_heap_initial_content + != bootloader_heap_initial_content_from_prover + { + panic!( + "Auxilary output doesn't match\n\ + server values: events_queue_state = {events_queue_state}, bootloader_heap_initial_content = {bootloader_heap_initial_content}\n\ + prover values: events_queue_state = {events_queue_state_from_prover}, bootloader_heap_initial_content = {bootloader_heap_initial_content_from_prover}", + ); } let system_logs = serialize_commitments(&l1_batch.header.system_logs); let system_logs_hash = H256(keccak256(&system_logs)); - if !is_pre_boojum { - let state_diff_hash = l1_batch + let state_diff_hash = if protocol_version.is_pre_gateway() { + l1_batch .header .system_logs - .into_iter() - .find(|elem| elem.0.key == H256::from_low_u64_be(2)) - .expect("No state diff hash key") - .0 - .value; - - if state_diff_hash != state_diff_hash_from_prover - || system_logs_hash != system_logs_hash_from_prover - { - let server_values = format!("system_logs_hash = {system_logs_hash}, state_diff_hash = {state_diff_hash}"); - let prover_values = format!("system_logs_hash = {system_logs_hash_from_prover}, state_diff_hash = {state_diff_hash_from_prover}"); - panic!( - "Auxilary output doesn't match, server values: {} prover values: {}", - server_values, prover_values - ); - } + .iter() + .find_map(|log| { + (log.0.key + == H256::from_low_u64_be(STATE_DIFF_HASH_KEY_PRE_GATEWAY as u64)) + .then_some(log.0.value) + }) + .expect("Failed to get state_diff_hash from system logs") + } else { + l1_batch + .metadata + .state_diff_hash + .expect("Failed to get state_diff_hash from metadata") + }; + + if state_diff_hash != state_diff_hash_from_prover + || system_logs_hash != system_logs_hash_from_prover + { + let server_values = format!("system_logs_hash = {system_logs_hash}, state_diff_hash = {state_diff_hash}"); + let prover_values = format!("system_logs_hash = {system_logs_hash_from_prover}, state_diff_hash = {state_diff_hash_from_prover}"); + panic!( + "Auxilary output doesn't match, server values: {} prover values: {}", + server_values, prover_values + ); } + storage .proof_generation_dal() .save_proof_artifacts_metadata(l1_batch_number, &blob_url) diff --git a/core/node/proof_data_handler/src/tee_request_processor.rs b/core/node/proof_data_handler/src/tee_request_processor.rs index 2c2a56300097..800dede23c76 100644 --- a/core/node/proof_data_handler/src/tee_request_processor.rs +++ b/core/node/proof_data_handler/src/tee_request_processor.rs @@ -130,7 +130,7 @@ impl TeeRequestProcessor { // This means we don't want to reject any execution, therefore we're using MAX as an allow all. let validation_computational_gas_limit = u32::MAX; - let (system_env, l1_batch_env) = l1_batch_params_provider + let (system_env, l1_batch_env, pubdata_params) = l1_batch_params_provider .load_l1_batch_env( &mut connection, l1_batch_number, @@ -149,6 +149,7 @@ impl TeeRequestProcessor { l2_blocks_execution_data, l1_batch_env, system_env, + pubdata_params, })) } diff --git a/core/node/state_keeper/src/executor/tests/tester.rs b/core/node/state_keeper/src/executor/tests/tester.rs index 79072f23aed9..a02aeb47cafa 100644 --- a/core/node/state_keeper/src/executor/tests/tester.rs +++ b/core/node/state_keeper/src/executor/tests/tester.rs @@ -25,6 +25,7 @@ use zksync_state::{OwnedStorage, ReadStorageFactory, RocksdbStorageOptions}; use zksync_test_account::{Account, DeployContractsTx, TxType}; use zksync_types::{ block::L2BlockHasher, + commitment::PubdataParams, ethabi::Token, protocol_version::ProtocolSemanticVersion, snapshots::{SnapshotRecoveryStatus, SnapshotStorageLog}, @@ -104,10 +105,9 @@ impl Tester { &mut self, storage_type: StorageType, ) -> Box> { - let (l1_batch_env, system_env) = self.default_batch_params(); + let (l1_batch_env, system_env, pubdata_params) = self.default_batch_params(); match storage_type { StorageType::AsyncRocksdbCache => { - let (l1_batch_env, system_env) = self.default_batch_params(); let (state_keeper_storage, task) = AsyncRocksdbCache::new( self.pool(), self.state_keeper_db_path(), @@ -122,6 +122,7 @@ impl Tester { Arc::new(state_keeper_storage), l1_batch_env, system_env, + pubdata_params, ) .await } @@ -133,12 +134,18 @@ impl Tester { )), l1_batch_env, system_env, + pubdata_params, ) .await } StorageType::Postgres => { - self.create_batch_executor_inner(Arc::new(self.pool()), l1_batch_env, system_env) - .await + self.create_batch_executor_inner( + Arc::new(self.pool()), + l1_batch_env, + system_env, + pubdata_params, + ) + .await } } } @@ -148,6 +155,7 @@ impl Tester { storage_factory: Arc, l1_batch_env: L1BatchEnv, system_env: SystemEnv, + pubdata_params: PubdataParams, ) -> Box> { let (_stop_sender, stop_receiver) = watch::channel(false); let storage = storage_factory @@ -158,11 +166,11 @@ impl Tester { if self.config.trace_calls { let mut executor = MainBatchExecutorFactory::::new(false); executor.set_fast_vm_mode(self.config.fast_vm_mode); - executor.init_batch(storage, l1_batch_env, system_env) + executor.init_batch(storage, l1_batch_env, system_env, pubdata_params) } else { let mut executor = MainBatchExecutorFactory::<()>::new(false); executor.set_fast_vm_mode(self.config.fast_vm_mode); - executor.init_batch(storage, l1_batch_env, system_env) + executor.init_batch(storage, l1_batch_env, system_env, pubdata_params) } } @@ -212,7 +220,7 @@ impl Tester { snapshot: &SnapshotRecoveryStatus, ) -> Box> { let current_timestamp = snapshot.l2_block_timestamp + 1; - let (mut l1_batch_env, system_env) = + let (mut l1_batch_env, system_env, pubdata_params) = self.batch_params(snapshot.l1_batch_number + 1, current_timestamp); l1_batch_env.previous_batch_hash = Some(snapshot.l1_batch_root_hash); l1_batch_env.first_l2_block = L2BlockEnv { @@ -222,11 +230,11 @@ impl Tester { max_virtual_blocks_to_create: 1, }; - self.create_batch_executor_inner(storage_factory, l1_batch_env, system_env) + self.create_batch_executor_inner(storage_factory, l1_batch_env, system_env, pubdata_params) .await } - pub(super) fn default_batch_params(&self) -> (L1BatchEnv, SystemEnv) { + pub(super) fn default_batch_params(&self) -> (L1BatchEnv, SystemEnv, PubdataParams) { // Not really important for the batch executor - it operates over a single batch. self.batch_params(L1BatchNumber(1), 100) } @@ -236,7 +244,7 @@ impl Tester { &self, l1_batch_number: L1BatchNumber, timestamp: u64, - ) -> (L1BatchEnv, SystemEnv) { + ) -> (L1BatchEnv, SystemEnv, PubdataParams) { let mut system_params = default_system_env(); if let Some(vm_gas_limit) = self.config.vm_gas_limit { system_params.bootloader_gas_limit = vm_gas_limit; @@ -245,7 +253,7 @@ impl Tester { self.config.validation_computational_gas_limit; let mut batch_params = default_l1_batch_env(l1_batch_number.0, timestamp, self.fee_account); batch_params.previous_batch_hash = Some(H256::zero()); // Not important in this context. - (batch_params, system_params) + (batch_params, system_params, PubdataParams::default()) } /// Performs the genesis in the storage. diff --git a/core/node/state_keeper/src/io/common/mod.rs b/core/node/state_keeper/src/io/common/mod.rs index 6bd881414a20..867ffa7fb371 100644 --- a/core/node/state_keeper/src/io/common/mod.rs +++ b/core/node/state_keeper/src/io/common/mod.rs @@ -3,7 +3,7 @@ use std::time::Duration; use anyhow::Context; use zksync_dal::{Connection, Core, CoreDal}; use zksync_multivm::interface::{L1BatchEnv, SystemEnv}; -use zksync_types::{L1BatchNumber, L2BlockNumber, H256}; +use zksync_types::{commitment::PubdataParams, L1BatchNumber, L2BlockNumber, H256}; use super::PendingBatchData; @@ -85,6 +85,7 @@ pub async fn load_pending_batch( storage: &mut Connection<'_, Core>, system_env: SystemEnv, l1_batch_env: L1BatchEnv, + pubdata_params: PubdataParams, ) -> anyhow::Result { let pending_l2_blocks = storage .transactions_dal() @@ -104,6 +105,7 @@ pub async fn load_pending_batch( Ok(PendingBatchData { l1_batch_env, system_env, + pubdata_params, pending_l2_blocks, }) } diff --git a/core/node/state_keeper/src/io/common/tests.rs b/core/node/state_keeper/src/io/common/tests.rs index b2a24acb4956..ec9f906b1cd7 100644 --- a/core/node/state_keeper/src/io/common/tests.rs +++ b/core/node/state_keeper/src/io/common/tests.rs @@ -318,7 +318,7 @@ async fn loading_pending_batch_with_genesis() { .await; let provider = L1BatchParamsProvider::new(&mut storage).await.unwrap(); - let (system_env, l1_batch_env) = provider + let (system_env, l1_batch_env, pubdata_params) = provider .load_l1_batch_env( &mut storage, L1BatchNumber(1), @@ -331,7 +331,7 @@ async fn loading_pending_batch_with_genesis() { assert_eq!(l1_batch_env.first_l2_block.number, 1); - let pending_batch = load_pending_batch(&mut storage, system_env, l1_batch_env) + let pending_batch = load_pending_batch(&mut storage, system_env, l1_batch_env, pubdata_params) .await .unwrap(); @@ -396,7 +396,7 @@ async fn loading_pending_batch_after_snapshot_recovery() { .await; let provider = L1BatchParamsProvider::new(&mut storage).await.unwrap(); - let (system_env, l1_batch_env) = provider + let (system_env, l1_batch_env, pubdata_params) = provider .load_l1_batch_env( &mut storage, snapshot_recovery.l1_batch_number + 1, @@ -406,7 +406,7 @@ async fn loading_pending_batch_after_snapshot_recovery() { .await .unwrap() .expect("no L1 batch"); - let pending_batch = load_pending_batch(&mut storage, system_env, l1_batch_env) + let pending_batch = load_pending_batch(&mut storage, system_env, l1_batch_env, pubdata_params) .await .unwrap(); diff --git a/core/node/state_keeper/src/io/mempool.rs b/core/node/state_keeper/src/io/mempool.rs index 229f54132f76..dfddd36aba71 100644 --- a/core/node/state_keeper/src/io/mempool.rs +++ b/core/node/state_keeper/src/io/mempool.rs @@ -14,7 +14,10 @@ use zksync_mempool::L2TxFilter; use zksync_multivm::{interface::Halt, utils::derive_base_fee_and_gas_per_pubdata}; use zksync_node_fee_model::BatchFeeModelInputProvider; use zksync_types::{ - block::UnsealedL1BatchHeader, protocol_upgrade::ProtocolUpgradeTx, utils::display_timestamp, + block::UnsealedL1BatchHeader, + commitment::{L1BatchCommitmentMode, PubdataParams}, + protocol_upgrade::ProtocolUpgradeTx, + utils::display_timestamp, Address, L1BatchNumber, L2BlockNumber, L2ChainId, ProtocolVersionId, Transaction, H256, U256, }; // TODO (SMA-1206): use seconds instead of milliseconds. @@ -55,6 +58,8 @@ pub struct MempoolIO { // Used to keep track of gas prices to set accepted price per pubdata byte in blocks. batch_fee_input_provider: Arc, chain_id: L2ChainId, + l2_da_validator_address: Option
, + pubdata_type: L1BatchCommitmentMode, } impl IoSealCriteria for MempoolIO { @@ -97,7 +102,7 @@ impl StateKeeperIO for MempoolIO { L2BlockSealProcess::clear_pending_l2_block(&mut storage, cursor.next_l2_block - 1).await?; - let Some((system_env, l1_batch_env)) = self + let Some((system_env, l1_batch_env, pubdata_params)) = self .l1_batch_params_provider .load_l1_batch_env( &mut storage, @@ -109,26 +114,24 @@ impl StateKeeperIO for MempoolIO { else { return Ok((cursor, None)); }; - let pending_batch_data = load_pending_batch(&mut storage, system_env, l1_batch_env) - .await - .with_context(|| { - format!( - "failed loading data for re-execution for pending L1 batch #{}", - cursor.l1_batch - ) - })?; + let pending_batch_data = + load_pending_batch(&mut storage, system_env, l1_batch_env, pubdata_params) + .await + .with_context(|| { + format!( + "failed loading data for re-execution for pending L1 batch #{}", + cursor.l1_batch + ) + })?; - let PendingBatchData { - l1_batch_env, - system_env, - pending_l2_blocks, - } = pending_batch_data; // Initialize the filter for the transactions that come after the pending batch. // We use values from the pending block to match the filter with one used before the restart. - let (base_fee, gas_per_pubdata) = - derive_base_fee_and_gas_per_pubdata(l1_batch_env.fee_input, system_env.version.into()); + let (base_fee, gas_per_pubdata) = derive_base_fee_and_gas_per_pubdata( + pending_batch_data.l1_batch_env.fee_input, + pending_batch_data.system_env.version.into(), + ); self.filter = L2TxFilter { - fee_input: l1_batch_env.fee_input, + fee_input: pending_batch_data.l1_batch_env.fee_input, fee_per_gas: base_fee, gas_per_pubdata: gas_per_pubdata as u32, }; @@ -136,20 +139,14 @@ impl StateKeeperIO for MempoolIO { storage .blocks_dal() .ensure_unsealed_l1_batch_exists( - l1_batch_env + pending_batch_data + .l1_batch_env .clone() - .into_unsealed_header(Some(system_env.version)), + .into_unsealed_header(Some(pending_batch_data.system_env.version)), ) .await?; - Ok(( - cursor, - Some(PendingBatchData { - l1_batch_env, - system_env, - pending_l2_blocks, - }), - )) + Ok((cursor, Some(pending_batch_data))) } async fn wait_for_new_batch_params( @@ -166,10 +163,11 @@ impl StateKeeperIO for MempoolIO { .get_unsealed_l1_batch() .await? { + let protocol_version = unsealed_storage_batch + .protocol_version + .context("unsealed batch is missing protocol version")?; return Ok(Some(L1BatchParams { - protocol_version: unsealed_storage_batch - .protocol_version - .expect("unsealed batch is missing protocol version"), + protocol_version, validation_computational_gas_limit: self.validation_computational_gas_limit, operator_address: unsealed_storage_batch.fee_address, fee_input: unsealed_storage_batch.fee_input, @@ -178,6 +176,7 @@ impl StateKeeperIO for MempoolIO { // This value is effectively ignored by the protocol. virtual_blocks: 1, }, + pubdata_params: self.pubdata_params(protocol_version)?, })); } @@ -247,6 +246,7 @@ impl StateKeeperIO for MempoolIO { // This value is effectively ignored by the protocol. virtual_blocks: 1, }, + pubdata_params: self.pubdata_params(protocol_version)?, })); } Ok(None) @@ -454,6 +454,7 @@ async fn sleep_past(timestamp: u64, l2_block: L2BlockNumber) -> u64 { } impl MempoolIO { + #[allow(clippy::too_many_arguments)] pub fn new( mempool: MempoolGuard, batch_fee_input_provider: Arc, @@ -462,6 +463,8 @@ impl MempoolIO { fee_account: Address, delay_interval: Duration, chain_id: L2ChainId, + l2_da_validator_address: Option
, + pubdata_type: L1BatchCommitmentMode, ) -> anyhow::Result { Ok(Self { mempool, @@ -477,8 +480,26 @@ impl MempoolIO { delay_interval, batch_fee_input_provider, chain_id, + l2_da_validator_address, + pubdata_type, }) } + + fn pubdata_params(&self, protocol_version: ProtocolVersionId) -> anyhow::Result { + let pubdata_params = match ( + protocol_version.is_pre_gateway(), + self.l2_da_validator_address, + ) { + (true, _) => PubdataParams::default(), + (false, Some(l2_da_validator_address)) => PubdataParams { + l2_da_validator_address, + pubdata_type: self.pubdata_type, + }, + (false, None) => anyhow::bail!("L2 DA validator address not found"), + }; + + Ok(pubdata_params) + } } /// Getters required for testing the MempoolIO. diff --git a/core/node/state_keeper/src/io/mod.rs b/core/node/state_keeper/src/io/mod.rs index 0fc5ebb6c082..e2461e72d7b2 100644 --- a/core/node/state_keeper/src/io/mod.rs +++ b/core/node/state_keeper/src/io/mod.rs @@ -4,8 +4,9 @@ use async_trait::async_trait; use zksync_contracts::BaseSystemContracts; use zksync_multivm::interface::{L1BatchEnv, SystemEnv}; use zksync_types::{ - block::L2BlockExecutionData, fee_model::BatchFeeInput, protocol_upgrade::ProtocolUpgradeTx, - Address, L1BatchNumber, L2ChainId, ProtocolVersionId, Transaction, H256, + block::L2BlockExecutionData, commitment::PubdataParams, fee_model::BatchFeeInput, + protocol_upgrade::ProtocolUpgradeTx, Address, L1BatchNumber, L2ChainId, ProtocolVersionId, + Transaction, H256, }; use zksync_vm_executor::storage::l1_batch_params; @@ -38,6 +39,7 @@ pub struct PendingBatchData { /// (e.g. timestamp) are the same, so transaction would have the same result after re-execution. pub(crate) l1_batch_env: L1BatchEnv, pub(crate) system_env: SystemEnv, + pub(crate) pubdata_params: PubdataParams, /// List of L2 blocks and corresponding transactions that were executed within batch. pub(crate) pending_l2_blocks: Vec, } @@ -70,6 +72,8 @@ pub struct L1BatchParams { pub fee_input: BatchFeeInput, /// Parameters of the first L2 block in the batch. pub first_l2_block: L2BlockParams, + /// Params related to how the pubdata should be processed by the bootloader in the batch. + pub pubdata_params: PubdataParams, } impl L1BatchParams { @@ -79,8 +83,8 @@ impl L1BatchParams { contracts: BaseSystemContracts, cursor: &IoCursor, previous_batch_hash: H256, - ) -> (SystemEnv, L1BatchEnv) { - l1_batch_params( + ) -> (SystemEnv, L1BatchEnv, PubdataParams) { + let (system_env, l1_batch_env) = l1_batch_params( cursor.l1_batch, self.operator_address, self.first_l2_block.timestamp, @@ -93,7 +97,9 @@ impl L1BatchParams { self.protocol_version, self.first_l2_block.virtual_blocks, chain_id, - ) + ); + + (system_env, l1_batch_env, self.pubdata_params) } } diff --git a/core/node/state_keeper/src/io/persistence.rs b/core/node/state_keeper/src/io/persistence.rs index 3e11285e11f1..06f1972a02aa 100644 --- a/core/node/state_keeper/src/io/persistence.rs +++ b/core/node/state_keeper/src/io/persistence.rs @@ -7,7 +7,7 @@ use async_trait::async_trait; use tokio::sync::{mpsc, oneshot}; use zksync_dal::{ConnectionPool, Core, CoreDal}; use zksync_shared_metrics::{BlockStage, APP_METRICS}; -use zksync_types::{writes::TreeWrite, Address}; +use zksync_types::{writes::TreeWrite, Address, ProtocolVersionId}; use zksync_utils::u256_to_h256; use crate::{ @@ -29,7 +29,7 @@ struct Completable { #[derive(Debug)] pub struct StateKeeperPersistence { pool: ConnectionPool, - l2_shared_bridge_addr: Address, + l2_legacy_shared_bridge_addr: Option
, pre_insert_txs: bool, insert_protective_reads: bool, commands_sender: mpsc::Sender>, @@ -41,13 +41,45 @@ pub struct StateKeeperPersistence { impl StateKeeperPersistence { const SHUTDOWN_MSG: &'static str = "L2 block sealer unexpectedly shut down"; + async fn validate_l2_legacy_shared_bridge_addr( + pool: &ConnectionPool, + l2_legacy_shared_bridge_addr: Option
, + ) -> anyhow::Result<()> { + let mut connection = pool.connection_tagged("state_keeper").await?; + + if let Some(l2_block) = connection + .blocks_dal() + .get_earliest_l2_block_number() + .await + .context("failed to load earliest l2 block number")? + { + let header = connection + .blocks_dal() + .get_l2_block_header(l2_block) + .await + .context("failed to load L2 block header")? + .context("missing L2 block header")?; + let protocol_version = header + .protocol_version + .unwrap_or_else(ProtocolVersionId::last_potentially_undefined); + + if protocol_version.is_pre_gateway() && l2_legacy_shared_bridge_addr.is_none() { + anyhow::bail!("Missing `l2_legacy_shared_bridge_addr` for chain that was initialized before gateway upgrade"); + } + } + + Ok(()) + } + /// Creates a sealer that will use the provided Postgres connection and will have the specified /// `command_capacity` for unprocessed sealing commands. - pub fn new( + pub async fn new( pool: ConnectionPool, - l2_shared_bridge_addr: Address, + l2_legacy_shared_bridge_addr: Option
, mut command_capacity: usize, - ) -> (Self, L2BlockSealerTask) { + ) -> anyhow::Result<(Self, L2BlockSealerTask)> { + Self::validate_l2_legacy_shared_bridge_addr(&pool, l2_legacy_shared_bridge_addr).await?; + let is_sync = command_capacity == 0; command_capacity = command_capacity.max(1); @@ -60,14 +92,14 @@ impl StateKeeperPersistence { }; let this = Self { pool, - l2_shared_bridge_addr, + l2_legacy_shared_bridge_addr, pre_insert_txs: false, insert_protective_reads: true, commands_sender, latest_completion_receiver: None, is_sync, }; - (this, sealer) + Ok((this, sealer)) } pub fn with_tx_insertion(mut self) -> Self { @@ -157,8 +189,8 @@ impl StateKeeperOutputHandler for StateKeeperPersistence { } async fn handle_l2_block(&mut self, updates_manager: &UpdatesManager) -> anyhow::Result<()> { - let command = - updates_manager.seal_l2_block_command(self.l2_shared_bridge_addr, self.pre_insert_txs); + let command = updates_manager + .seal_l2_block_command(self.l2_legacy_shared_bridge_addr, self.pre_insert_txs); self.submit_l2_block(command).await; Ok(()) } @@ -174,7 +206,7 @@ impl StateKeeperOutputHandler for StateKeeperPersistence { updates_manager .seal_l1_batch( self.pool.clone(), - self.l2_shared_bridge_addr, + self.l2_legacy_shared_bridge_addr, self.insert_protective_reads, ) .await @@ -392,8 +424,13 @@ mod tests { .unwrap(); drop(storage); - let (persistence, l2_block_sealer) = - StateKeeperPersistence::new(pool.clone(), Address::default(), l2_block_sealer_capacity); + let (persistence, l2_block_sealer) = StateKeeperPersistence::new( + pool.clone(), + Some(Address::default()), + l2_block_sealer_capacity, + ) + .await + .unwrap(); let mut output_handler = OutputHandler::new(Box::new(persistence)) .with_handler(Box::new(TreeWritesPersistence::new(pool.clone()))); tokio::spawn(l2_block_sealer.run()); @@ -451,7 +488,8 @@ mod tests { pool: &ConnectionPool, ) -> H256 { let l1_batch_env = default_l1_batch_env(1, 1, Address::random()); - let mut updates = UpdatesManager::new(&l1_batch_env, &default_system_env()); + let mut updates = + UpdatesManager::new(&l1_batch_env, &default_system_env(), Default::default()); pool.connection() .await .unwrap() @@ -538,7 +576,9 @@ mod tests { drop(storage); let (mut persistence, l2_block_sealer) = - StateKeeperPersistence::new(pool.clone(), Address::default(), 1); + StateKeeperPersistence::new(pool.clone(), Some(Address::default()), 1) + .await + .unwrap(); persistence = persistence.with_tx_insertion().without_protective_reads(); let mut output_handler = OutputHandler::new(Box::new(persistence)); tokio::spawn(l2_block_sealer.run()); @@ -577,11 +617,13 @@ mod tests { async fn l2_block_sealer_handle_blocking() { let pool = ConnectionPool::constrained_test_pool(1).await; let (mut persistence, mut sealer) = - StateKeeperPersistence::new(pool, Address::default(), 1); + StateKeeperPersistence::new(pool, Some(Address::default()), 1) + .await + .unwrap(); // The first command should be successfully submitted immediately. let mut updates_manager = create_updates_manager(); - let seal_command = updates_manager.seal_l2_block_command(Address::default(), false); + let seal_command = updates_manager.seal_l2_block_command(Some(Address::default()), false); persistence.submit_l2_block(seal_command).await; // The second command should lead to blocking @@ -589,7 +631,7 @@ mod tests { timestamp: 2, virtual_blocks: 1, }); - let seal_command = updates_manager.seal_l2_block_command(Address::default(), false); + let seal_command = updates_manager.seal_l2_block_command(Some(Address::default()), false); { let submit_future = persistence.submit_l2_block(seal_command); futures::pin_mut!(submit_future); @@ -617,7 +659,7 @@ mod tests { timestamp: 3, virtual_blocks: 1, }); - let seal_command = updates_manager.seal_l2_block_command(Address::default(), false); + let seal_command = updates_manager.seal_l2_block_command(Some(Address::default()), false); persistence.submit_l2_block(seal_command).await; let command = sealer.commands_receiver.recv().await.unwrap(); command.completion_sender.send(()).unwrap(); @@ -628,12 +670,15 @@ mod tests { async fn l2_block_sealer_handle_parallel_processing() { let pool = ConnectionPool::constrained_test_pool(1).await; let (mut persistence, mut sealer) = - StateKeeperPersistence::new(pool, Address::default(), 5); + StateKeeperPersistence::new(pool, Some(Address::default()), 5) + .await + .unwrap(); // 5 L2 block sealing commands can be submitted without blocking. let mut updates_manager = create_updates_manager(); for i in 1..=5 { - let seal_command = updates_manager.seal_l2_block_command(Address::default(), false); + let seal_command = + updates_manager.seal_l2_block_command(Some(Address::default()), false); updates_manager.push_l2_block(L2BlockParams { timestamp: i, virtual_blocks: 1, diff --git a/core/node/state_keeper/src/io/seal_logic/l2_block_seal_subtasks.rs b/core/node/state_keeper/src/io/seal_logic/l2_block_seal_subtasks.rs index 7ef466805e36..4fc58bce5c9e 100644 --- a/core/node/state_keeper/src/io/seal_logic/l2_block_seal_subtasks.rs +++ b/core/node/state_keeper/src/io/seal_logic/l2_block_seal_subtasks.rs @@ -3,7 +3,7 @@ use async_trait::async_trait; use once_cell::sync::Lazy; use zksync_dal::{Connection, Core, CoreDal}; use zksync_multivm::interface::VmEvent; -use zksync_system_constants::CONTRACT_DEPLOYER_ADDRESS; +use zksync_system_constants::{CONTRACT_DEPLOYER_ADDRESS, L2_NATIVE_TOKEN_VAULT_ADDRESS}; use zksync_types::{ ethabi, tokens::{TokenInfo, TokenMetadata}, @@ -18,7 +18,7 @@ use crate::{ }; fn extract_added_tokens( - l2_shared_bridge_addr: Address, + l2_token_deployer_addr: Address, all_generated_events: &[VmEvent], ) -> Vec { let deployed_tokens = all_generated_events @@ -28,7 +28,7 @@ fn extract_added_tokens( event.address == CONTRACT_DEPLOYER_ADDRESS && event.indexed_topics.len() == 4 && event.indexed_topics[0] == VmEvent::DEPLOY_EVENT_SIGNATURE - && h256_to_account_address(&event.indexed_topics[1]) == l2_shared_bridge_addr + && h256_to_account_address(&event.indexed_topics[1]) == l2_token_deployer_addr }) .map(|event| h256_to_account_address(&event.indexed_topics[3])); @@ -334,8 +334,10 @@ impl L2BlockSealSubtask for InsertTokensSubtask { ) -> anyhow::Result<()> { let is_fictive = command.is_l2_block_fictive(); let progress = L2_BLOCK_METRICS.start(L2BlockSealStage::ExtractAddedTokens, is_fictive); - let added_tokens = - extract_added_tokens(command.l2_shared_bridge_addr, &command.l2_block.events); + let token_deployer_address = command + .l2_legacy_shared_bridge_addr + .unwrap_or(L2_NATIVE_TOKEN_VAULT_ADDRESS); + let added_tokens = extract_added_tokens(token_deployer_address, &command.l2_block.events); progress.observe(added_tokens.len()); let progress = L2_BLOCK_METRICS.start(L2BlockSealStage::InsertTokens, is_fictive); @@ -464,6 +466,7 @@ mod tests { use zksync_node_test_utils::create_l2_transaction; use zksync_types::{ block::L2BlockHeader, + commitment::PubdataParams, l2_to_l1_log::{L2ToL1Log, UserL2ToL1Log}, AccountTreeId, Address, L1BatchNumber, ProtocolVersionId, StorageKey, StorageLog, StorageLogKind, StorageLogWithPreviousValue, @@ -552,8 +555,9 @@ mod tests { base_fee_per_gas: Default::default(), base_system_contracts_hashes: Default::default(), protocol_version: Some(ProtocolVersionId::latest()), - l2_shared_bridge_addr: Default::default(), + l2_legacy_shared_bridge_addr: Default::default(), pre_insert_txs: false, + pubdata_params: PubdataParams::default(), }; // Run. @@ -616,6 +620,7 @@ mod tests { virtual_blocks: l2_block_seal_command.l2_block.virtual_blocks, gas_limit: get_max_batch_gas_limit(VmVersion::latest()), logs_bloom: Default::default(), + pubdata_params: l2_block_seal_command.pubdata_params, }; connection .protocol_versions_dal() diff --git a/core/node/state_keeper/src/io/seal_logic/mod.rs b/core/node/state_keeper/src/io/seal_logic/mod.rs index 5859d27786d9..7f05bda7a6f5 100644 --- a/core/node/state_keeper/src/io/seal_logic/mod.rs +++ b/core/node/state_keeper/src/io/seal_logic/mod.rs @@ -46,7 +46,7 @@ impl UpdatesManager { pub(super) async fn seal_l1_batch( &self, pool: ConnectionPool, - l2_shared_bridge_addr: Address, + l2_legacy_shared_bridge_addr: Option
, insert_protective_reads: bool, ) -> anyhow::Result<()> { let started_at = Instant::now(); @@ -59,7 +59,7 @@ impl UpdatesManager { let progress = L1_BATCH_METRICS.start(L1BatchSealStage::FictiveL2Block); // Seal fictive L2 block with last events and storage logs. let l2_block_command = self.seal_l2_block_command( - l2_shared_bridge_addr, + l2_legacy_shared_bridge_addr, false, // fictive L2 blocks don't have txs, so it's fine to pass `false` here. ); @@ -335,8 +335,6 @@ impl L2BlockSealCommand { /// that are created after the last processed tx in the L1 batch: after the last transaction is processed, /// the bootloader enters the "tip" phase in which it can still generate events (e.g., /// one for sending fees to the operator). - /// - /// `l2_shared_bridge_addr` is required to extract the information on newly added tokens. async fn seal_inner( &self, strategy: &mut SealStrategy<'_>, @@ -393,6 +391,7 @@ impl L2BlockSealCommand { virtual_blocks: self.l2_block.virtual_blocks, gas_limit: get_max_batch_gas_limit(definite_vm_version), logs_bloom, + pubdata_params: self.pubdata_params, }; let mut connection = strategy.connection().await?; diff --git a/core/node/state_keeper/src/io/tests/mod.rs b/core/node/state_keeper/src/io/tests/mod.rs index 566eebf7ab72..ece5b67767f6 100644 --- a/core/node/state_keeper/src/io/tests/mod.rs +++ b/core/node/state_keeper/src/io/tests/mod.rs @@ -286,8 +286,9 @@ async fn processing_storage_logs_when_sealing_l2_block() { base_fee_per_gas: 10, base_system_contracts_hashes: BaseSystemContractsHashes::default(), protocol_version: Some(ProtocolVersionId::latest()), - l2_shared_bridge_addr: Address::default(), + l2_legacy_shared_bridge_addr: Some(Address::default()), pre_insert_txs: false, + pubdata_params: Default::default(), }; connection_pool .connection() @@ -376,8 +377,9 @@ async fn processing_events_when_sealing_l2_block() { base_fee_per_gas: 10, base_system_contracts_hashes: BaseSystemContractsHashes::default(), protocol_version: Some(ProtocolVersionId::latest()), - l2_shared_bridge_addr: Address::default(), + l2_legacy_shared_bridge_addr: Some(Address::default()), pre_insert_txs: false, + pubdata_params: Default::default(), }; pool.connection() .await @@ -447,13 +449,13 @@ async fn l2_block_processing_after_snapshot_recovery(commitment_mode: L1BatchCom .await .unwrap() .expect("no batch params generated"); - let (system_env, l1_batch_env) = l1_batch_params.into_env( + let (system_env, l1_batch_env, pubdata_params) = l1_batch_params.into_env( L2ChainId::default(), BASE_SYSTEM_CONTRACTS.clone(), &cursor, previous_batch_hash, ); - let mut updates = UpdatesManager::new(&l1_batch_env, &system_env); + let mut updates = UpdatesManager::new(&l1_batch_env, &system_env, pubdata_params); let tx_hash = tx.hash(); updates.extend_from_executed_transaction( @@ -467,7 +469,9 @@ async fn l2_block_processing_after_snapshot_recovery(commitment_mode: L1BatchCom ); let (mut persistence, l2_block_sealer) = - StateKeeperPersistence::new(connection_pool.clone(), Address::default(), 0); + StateKeeperPersistence::new(connection_pool.clone(), Some(Address::default()), 0) + .await + .unwrap(); tokio::spawn(l2_block_sealer.run()); persistence.handle_l2_block(&updates).await.unwrap(); diff --git a/core/node/state_keeper/src/io/tests/tester.rs b/core/node/state_keeper/src/io/tests/tester.rs index ad189831bad7..daedbebc75e0 100644 --- a/core/node/state_keeper/src/io/tests/tester.rs +++ b/core/node/state_keeper/src/io/tests/tester.rs @@ -147,6 +147,8 @@ impl Tester { wallets.state_keeper.unwrap().fee_account.address(), Duration::from_secs(1), L2ChainId::from(270), + Some(Default::default()), + Default::default(), ) .unwrap(); diff --git a/core/node/state_keeper/src/keeper.rs b/core/node/state_keeper/src/keeper.rs index bd102daa3080..523dd8ecebad 100644 --- a/core/node/state_keeper/src/keeper.rs +++ b/core/node/state_keeper/src/keeper.rs @@ -17,8 +17,9 @@ use zksync_multivm::{ use zksync_shared_metrics::{TxStage, APP_METRICS}; use zksync_state::{OwnedStorage, ReadStorageFactory}; use zksync_types::{ - block::L2BlockExecutionData, l2::TransactionType, protocol_upgrade::ProtocolUpgradeTx, - protocol_version::ProtocolVersionId, utils::display_timestamp, L1BatchNumber, Transaction, + block::L2BlockExecutionData, commitment::PubdataParams, l2::TransactionType, + protocol_upgrade::ProtocolUpgradeTx, protocol_version::ProtocolVersionId, + utils::display_timestamp, L1BatchNumber, Transaction, }; use crate::{ @@ -116,6 +117,7 @@ impl ZkSyncStateKeeper { let PendingBatchData { mut l1_batch_env, mut system_env, + mut pubdata_params, pending_l2_blocks, } = match pending_batch_params { Some(params) => { @@ -132,7 +134,7 @@ impl ZkSyncStateKeeper { } None => { tracing::info!("There is no open pending batch, starting a new empty batch"); - let (system_env, l1_batch_env) = self + let (system_env, l1_batch_env, pubdata_params) = self .wait_for_new_batch_env(&cursor) .await .map_err(|e| e.context("wait_for_new_batch_params()"))?; @@ -140,18 +142,19 @@ impl ZkSyncStateKeeper { l1_batch_env, pending_l2_blocks: Vec::new(), system_env, + pubdata_params, } } }; let protocol_version = system_env.version; - let mut updates_manager = UpdatesManager::new(&l1_batch_env, &system_env); + let mut updates_manager = UpdatesManager::new(&l1_batch_env, &system_env, pubdata_params); let mut protocol_upgrade_tx: Option = self .load_protocol_upgrade_tx(&pending_l2_blocks, protocol_version, l1_batch_env.number) .await?; let mut batch_executor = self - .create_batch_executor(l1_batch_env.clone(), system_env.clone()) + .create_batch_executor(l1_batch_env.clone(), system_env.clone(), pubdata_params) .await?; self.restore_state( &mut *batch_executor, @@ -201,10 +204,11 @@ impl ZkSyncStateKeeper { // Start the new batch. next_cursor.l1_batch += 1; - (system_env, l1_batch_env) = self.wait_for_new_batch_env(&next_cursor).await?; - updates_manager = UpdatesManager::new(&l1_batch_env, &system_env); + (system_env, l1_batch_env, pubdata_params) = + self.wait_for_new_batch_env(&next_cursor).await?; + updates_manager = UpdatesManager::new(&l1_batch_env, &system_env, pubdata_params); batch_executor = self - .create_batch_executor(l1_batch_env.clone(), system_env.clone()) + .create_batch_executor(l1_batch_env.clone(), system_env.clone(), pubdata_params) .await?; let version_changed = system_env.version != sealed_batch_protocol_version; @@ -221,6 +225,7 @@ impl ZkSyncStateKeeper { &mut self, l1_batch_env: L1BatchEnv, system_env: SystemEnv, + pubdata_params: PubdataParams, ) -> Result>, Error> { let storage = self .storage_factory @@ -230,7 +235,7 @@ impl ZkSyncStateKeeper { .ok_or(Error::Canceled)?; Ok(self .batch_executor - .init_batch(storage, l1_batch_env, system_env)) + .init_batch(storage, l1_batch_env, system_env, pubdata_params)) } /// This function is meant to be called only once during the state-keeper initialization. @@ -327,7 +332,7 @@ impl ZkSyncStateKeeper { async fn wait_for_new_batch_env( &mut self, cursor: &IoCursor, - ) -> Result<(SystemEnv, L1BatchEnv), Error> { + ) -> Result<(SystemEnv, L1BatchEnv, PubdataParams), Error> { // `io.wait_for_new_batch_params(..)` is not cancel-safe; once we get new batch params, we must hold onto them // until we get the rest of parameters from I/O or receive a stop signal. let params = self.wait_for_new_batch_params(cursor).await?; diff --git a/core/node/state_keeper/src/testonly/mod.rs b/core/node/state_keeper/src/testonly/mod.rs index d1e82c44bd6f..ad50c8ca8ce6 100644 --- a/core/node/state_keeper/src/testonly/mod.rs +++ b/core/node/state_keeper/src/testonly/mod.rs @@ -14,9 +14,9 @@ use zksync_multivm::interface::{ use zksync_state::OwnedStorage; use zksync_test_account::Account; use zksync_types::{ - fee::Fee, utils::storage_key_for_standard_token_balance, AccountTreeId, Address, Execute, - L1BatchNumber, L2BlockNumber, PriorityOpId, StorageLog, Transaction, L2_BASE_TOKEN_ADDRESS, - SYSTEM_CONTEXT_MINIMAL_BASE_FEE, U256, + commitment::PubdataParams, fee::Fee, utils::storage_key_for_standard_token_balance, + AccountTreeId, Address, Execute, L1BatchNumber, L2BlockNumber, PriorityOpId, StorageLog, + Transaction, L2_BASE_TOKEN_ADDRESS, SYSTEM_CONTEXT_MINIMAL_BASE_FEE, U256, }; use zksync_utils::u256_to_h256; @@ -50,6 +50,7 @@ impl BatchExecutorFactory for MockBatchExecutor { _storage: OwnedStorage, _l1_batch_env: L1BatchEnv, _system_env: SystemEnv, + _pubdata_params: PubdataParams, ) -> Box> { Box::new(Self) } diff --git a/core/node/state_keeper/src/testonly/test_batch_executor.rs b/core/node/state_keeper/src/testonly/test_batch_executor.rs index cb282f3b7d6d..45787b18f3c9 100644 --- a/core/node/state_keeper/src/testonly/test_batch_executor.rs +++ b/core/node/state_keeper/src/testonly/test_batch_executor.rs @@ -27,8 +27,9 @@ use zksync_multivm::{ use zksync_node_test_utils::create_l2_transaction; use zksync_state::{interface::StorageView, OwnedStorage, ReadStorageFactory}; use zksync_types::{ - fee_model::BatchFeeInput, l2_to_l1_log::UserL2ToL1Log, protocol_upgrade::ProtocolUpgradeTx, - Address, L1BatchNumber, L2BlockNumber, L2ChainId, ProtocolVersionId, Transaction, H256, + commitment::PubdataParams, fee_model::BatchFeeInput, l2_to_l1_log::UserL2ToL1Log, + protocol_upgrade::ProtocolUpgradeTx, Address, L1BatchNumber, L2BlockNumber, L2ChainId, + ProtocolVersionId, Transaction, H256, }; use crate::{ @@ -423,6 +424,7 @@ impl BatchExecutorFactory for TestBatchExecutorBuilder { _storage: OwnedStorage, _l1_batch_env: L1BatchEnv, _system_env: SystemEnv, + _pubdata_params: PubdataParams, ) -> Box> { let executor = TestBatchExecutor::new(self.txs.pop_front().unwrap(), self.rollback_set.clone()); @@ -702,6 +704,7 @@ impl StateKeeperIO for TestIO { timestamp: self.timestamp, virtual_blocks: 1, }, + pubdata_params: Default::default(), }; self.l2_block_number += 1; self.timestamp += 1; diff --git a/core/node/state_keeper/src/tests/mod.rs b/core/node/state_keeper/src/tests/mod.rs index 9e971541b204..16eed0b2f7f7 100644 --- a/core/node/state_keeper/src/tests/mod.rs +++ b/core/node/state_keeper/src/tests/mod.rs @@ -59,6 +59,7 @@ pub(crate) fn pending_batch_data(pending_l2_blocks: Vec) - default_validation_computational_gas_limit: BATCH_COMPUTATIONAL_GAS_LIMIT, chain_id: L2ChainId::from(270), }, + pubdata_params: Default::default(), pending_l2_blocks, } } @@ -102,7 +103,7 @@ pub(super) fn default_l1_batch_env( pub(super) fn create_updates_manager() -> UpdatesManager { let l1_batch_env = default_l1_batch_env(1, 1, Address::default()); - UpdatesManager::new(&l1_batch_env, &default_system_env()) + UpdatesManager::new(&l1_batch_env, &default_system_env(), Default::default()) } pub(super) fn create_transaction(fee_per_gas: u64, gas_per_pubdata: u64) -> Transaction { diff --git a/core/node/state_keeper/src/updates/mod.rs b/core/node/state_keeper/src/updates/mod.rs index 6211755eb156..b1bd35c921ca 100644 --- a/core/node/state_keeper/src/updates/mod.rs +++ b/core/node/state_keeper/src/updates/mod.rs @@ -9,8 +9,8 @@ use zksync_multivm::{ utils::{get_batch_base_fee, StorageWritesDeduplicator}, }; use zksync_types::{ - block::BlockGasCount, fee_model::BatchFeeInput, Address, L1BatchNumber, L2BlockNumber, - ProtocolVersionId, Transaction, H256, + block::BlockGasCount, commitment::PubdataParams, fee_model::BatchFeeInput, Address, + L1BatchNumber, L2BlockNumber, ProtocolVersionId, Transaction, H256, }; pub(crate) use self::{l1_batch_updates::L1BatchUpdates, l2_block_updates::L2BlockUpdates}; @@ -41,10 +41,15 @@ pub struct UpdatesManager { pub l1_batch: L1BatchUpdates, pub l2_block: L2BlockUpdates, pub storage_writes_deduplicator: StorageWritesDeduplicator, + pubdata_params: PubdataParams, } impl UpdatesManager { - pub fn new(l1_batch_env: &L1BatchEnv, system_env: &SystemEnv) -> Self { + pub fn new( + l1_batch_env: &L1BatchEnv, + system_env: &SystemEnv, + pubdata_params: PubdataParams, + ) -> Self { let protocol_version = system_env.version; Self { batch_timestamp: l1_batch_env.timestamp, @@ -63,6 +68,7 @@ impl UpdatesManager { ), storage_writes_deduplicator: StorageWritesDeduplicator::new(), storage_view_cache: None, + pubdata_params, } } @@ -85,7 +91,7 @@ impl UpdatesManager { pub(crate) fn seal_l2_block_command( &self, - l2_shared_bridge_addr: Address, + l2_legacy_shared_bridge_addr: Option
, pre_insert_txs: bool, ) -> L2BlockSealCommand { L2BlockSealCommand { @@ -97,8 +103,9 @@ impl UpdatesManager { base_fee_per_gas: self.base_fee_per_gas, base_system_contracts_hashes: self.base_system_contract_hashes, protocol_version: Some(self.protocol_version), - l2_shared_bridge_addr, + l2_legacy_shared_bridge_addr, pre_insert_txs, + pubdata_params: self.pubdata_params, } } @@ -211,11 +218,12 @@ pub struct L2BlockSealCommand { pub base_fee_per_gas: u64, pub base_system_contracts_hashes: BaseSystemContractsHashes, pub protocol_version: Option, - pub l2_shared_bridge_addr: Address, + pub l2_legacy_shared_bridge_addr: Option
, /// Whether transactions should be pre-inserted to DB. /// Should be set to `true` for EN's IO as EN doesn't store transactions in DB /// before they are included into L2 blocks. pub pre_insert_txs: bool, + pub pubdata_params: PubdataParams, } #[cfg(test)] diff --git a/core/node/test_utils/src/lib.rs b/core/node/test_utils/src/lib.rs index 9eb53994eee5..86ce3aadd9a1 100644 --- a/core/node/test_utils/src/lib.rs +++ b/core/node/test_utils/src/lib.rs @@ -45,6 +45,7 @@ pub fn create_l2_block(number: u32) -> L2BlockHeader { virtual_blocks: 1, gas_limit: 0, logs_bloom: Default::default(), + pubdata_params: Default::default(), } } @@ -98,6 +99,10 @@ pub fn create_l1_batch_metadata(number: u32) -> L1BatchMetadata { events_queue_commitment: Some(H256::zero()), bootloader_initial_content_commitment: Some(H256::zero()), state_diffs_compressed: vec![], + state_diff_hash: Some(H256::zero()), + local_root: Some(H256::zero()), + aggregation_root: Some(H256::zero()), + da_inclusion_data: Some(vec![]), } } @@ -128,6 +133,9 @@ pub fn l1_batch_metadata_to_commitment_artifacts( } _ => None, }, + local_root: metadata.local_root.unwrap(), + aggregation_root: metadata.aggregation_root.unwrap(), + state_diff_hash: metadata.state_diff_hash.unwrap(), } } @@ -213,6 +221,7 @@ impl Snapshot { virtual_blocks: 1, gas_limit: 0, logs_bloom: Default::default(), + pubdata_params: Default::default(), }; Snapshot { l1_batch, diff --git a/core/node/vm_runner/src/process.rs b/core/node/vm_runner/src/process.rs index 4f7ac1f97284..dbd218c8dc5f 100644 --- a/core/node/vm_runner/src/process.rs +++ b/core/node/vm_runner/src/process.rs @@ -82,6 +82,7 @@ impl VmRunner { storage, batch_data.l1_batch_env.clone(), batch_data.system_env.clone(), + batch_data.pubdata_params, ); let mut output_handler = self .output_handler_factory diff --git a/core/node/vm_runner/src/storage.rs b/core/node/vm_runner/src/storage.rs index 2285455ba244..9ab4ed87b9f1 100644 --- a/core/node/vm_runner/src/storage.rs +++ b/core/node/vm_runner/src/storage.rs @@ -13,7 +13,9 @@ use zksync_state::{ AsyncCatchupTask, BatchDiff, OwnedStorage, RocksdbCell, RocksdbStorage, RocksdbStorageBuilder, RocksdbWithMemory, }; -use zksync_types::{block::L2BlockExecutionData, L1BatchNumber, L2ChainId}; +use zksync_types::{ + block::L2BlockExecutionData, commitment::PubdataParams, L1BatchNumber, L2ChainId, +}; use zksync_vm_executor::storage::L1BatchParamsProvider; use zksync_vm_interface::{L1BatchEnv, SystemEnv}; @@ -106,6 +108,8 @@ pub struct BatchExecuteData { pub l1_batch_env: L1BatchEnv, /// Execution process parameters. pub system_env: SystemEnv, + /// Pubdata building parameters. + pub pubdata_params: PubdataParams, /// List of L2 blocks and corresponding transactions that were executed within batch. pub l2_blocks: Vec, } @@ -394,7 +398,7 @@ pub(crate) async fn load_batch_execute_data( l1_batch_params_provider: &L1BatchParamsProvider, chain_id: L2ChainId, ) -> anyhow::Result> { - let Some((system_env, l1_batch_env)) = l1_batch_params_provider + let Some((system_env, l1_batch_env, pubdata_params)) = l1_batch_params_provider .load_l1_batch_env( conn, l1_batch_number, @@ -415,6 +419,7 @@ pub(crate) async fn load_batch_execute_data( Ok(Some(BatchExecuteData { l1_batch_env, system_env, + pubdata_params, l2_blocks, })) } diff --git a/core/tests/vm-benchmark/src/vm.rs b/core/tests/vm-benchmark/src/vm.rs index dddef0de82fe..e198be9ea6b2 100644 --- a/core/tests/vm-benchmark/src/vm.rs +++ b/core/tests/vm-benchmark/src/vm.rs @@ -5,7 +5,7 @@ use zksync_contracts::BaseSystemContracts; use zksync_multivm::{ interface::{ storage::{InMemoryStorage, StorageView}, - ExecutionResult, L1BatchEnv, L2BlockEnv, SystemEnv, TxExecutionMode, VmExecutionMode, + ExecutionResult, InspectExecutionMode, L1BatchEnv, L2BlockEnv, SystemEnv, TxExecutionMode, VmExecutionResultAndLogs, VmFactory, VmInterface, VmInterfaceExt, VmInterfaceHistoryEnabled, }, @@ -113,7 +113,7 @@ impl BenchmarkingVmFactory for Fast } let mut tracer = InstructionCount(0); - vm.0.inspect(&mut tracer, VmExecutionMode::OneTx); + vm.0.inspect(&mut tracer, InspectExecutionMode::OneTx); tracer.0 } } @@ -144,7 +144,7 @@ impl BenchmarkingVmFactory for Legacy { &mut InstructionCounter::new(count.clone()) .into_tracer_pointer() .into(), - VmExecutionMode::OneTx, + InspectExecutionMode::OneTx, ); count.take() } @@ -191,7 +191,7 @@ impl Default for BenchmarkingVm { impl BenchmarkingVm { pub fn run_transaction(&mut self, tx: &Transaction) -> VmExecutionResultAndLogs { self.0.push_transaction(tx.clone()); - self.0.execute(VmExecutionMode::OneTx) + self.0.execute(InspectExecutionMode::OneTx) } pub fn run_transaction_full(&mut self, tx: &Transaction) -> VmExecutionResultAndLogs { diff --git a/etc/multivm_bootloaders/vm_gateway/commit b/etc/multivm_bootloaders/vm_gateway/commit new file mode 100644 index 000000000000..a3547f577034 --- /dev/null +++ b/etc/multivm_bootloaders/vm_gateway/commit @@ -0,0 +1 @@ +a8bf0ca28d43899882a2e123e2fdf1379f0fd656 diff --git a/etc/multivm_bootloaders/vm_gateway/fee_estimate.yul/fee_estimate.yul.zbin b/etc/multivm_bootloaders/vm_gateway/fee_estimate.yul/fee_estimate.yul.zbin new file mode 100644 index 0000000000000000000000000000000000000000..fb6017f69cf03b963d490070a1d33555531e5d30 GIT binary patch literal 75296 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 MqpQDmPU|E84^E!&RR910 literal 0 HcmV?d00001 diff --git a/etc/multivm_bootloaders/vm_gateway/gas_test.yul/gas_test.yul.zbin b/etc/multivm_bootloaders/vm_gateway/gas_test.yul/gas_test.yul.zbin new file mode 100644 index 0000000000000000000000000000000000000000..c1726d8301ff2ffc1e8dc3dfdf1552926080a3a3 GIT binary patch literal 71392 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 CQ2T@c literal 0 HcmV?d00001 diff --git a/etc/multivm_bootloaders/vm_gateway/proved_batch.yul/proved_batch.yul.zbin b/etc/multivm_bootloaders/vm_gateway/proved_batch.yul/proved_batch.yul.zbin new file mode 100644 index 0000000000000000000000000000000000000000..2506ce065d74fc6a610beac3843b6c147c63cf10 GIT binary patch literal 71904 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 _42u{WYDg z;vdjF#eP$MCCzVZP@j5BYQPsh4fR1XpN8d@K2hCB<$zDUrOu<|ueHBQ`)OUcFA*^% zUd43T4`28UO@G0|0)q$bUw}b0U$Eb|;O5@1sdlqJ5&XIk%~Te0DS4$pz80cHsWTJg zQ2h2#AKLRHIU5Y%DA$^wNBEgf`jCE1gWq7>L2L$p5yD0MhIwAc`fj0#t3BEmnbyDL zaYOps_>+B;VY!Vz%G;*FZ*+b^+~G*vL7^b@RUWpWOnPRa=BGBt7r%bC9ut4w!~+h+ z1Nd9LPV3PPqDO^)JD}N45L}8wNIx%dd^L)za+Yd6SrWaBa)M*!4V36F)qXL

+$< z!>!Pp1W#qxo47*S$Ma(Cm>2g?@&p)=uUUFIVLr6)i|8Nby=;3`D_?J|cX*VCEm8kE z4@+^#UxkMTwGC%cC~Cy#Zi>UbdkD`g&DKl5{_ zPi#CkX!pI91fRwUf9WixW+=WUd>Q}Atb?qcn?DuAn+rfM$^+W|RF!yh;kg>WWPd=9 zmY3*zjwfk&dOvcH;|t%;=EEY5Tl>3h$2H$B(Q*^ScZjpeFZi6Mx901Xm!au-Xy2pj zccLGnXA9K}@{&D)9(yL?ErqTY|GLR~EaVHDf9s8NedwWAVEjtrTxHfbC7xV}0``yG zpJ#lbcV6~e{~|L)cGUd^;vVcDBnZ*PB0bcJ6mxjeFo;hGtz7IjvK>F6)WCV1 zUp4*l_}V|o&z1N47-yQ^7XAzMax#B}t+ymdbJSKWRKzl7z<{e|Urf08Fv zyv_mr?-e1UCBn~1=1Vib%a@9s)A@*Sed{+< $*1a2fZL;IR`mU3kA$cZ$i=@x& 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 literal 0 HcmV?d00001 diff --git a/prover/Cargo.lock b/prover/Cargo.lock index e5b42f1601b1..dbc3b3425e49 100644 --- a/prover/Cargo.lock +++ b/prover/Cargo.lock @@ -8159,6 +8159,7 @@ dependencies = [ "zk_evm 0.141.0", "zk_evm 0.150.6", "zksync_contracts", + "zksync_mini_merkle_tree", "zksync_system_constants", "zksync_types", "zksync_utils", diff --git a/yarn.lock b/yarn.lock index 255bd901e035..58511dd1b9ff 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1424,18 +1424,6 @@ resolved "https://registry.yarnpkg.com/@iarna/toml/-/toml-2.2.5.tgz#b32366c89b43c6f8cefbdefac778b9c828e3ba8c" integrity sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg== -"@isaacs/cliui@^8.0.2": - version "8.0.2" - resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550" - integrity sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA== - dependencies: - string-width "^5.1.2" - string-width-cjs "npm:string-width@^4.2.0" - strip-ansi "^7.0.1" - strip-ansi-cjs "npm:strip-ansi@^6.0.1" - wrap-ansi "^8.1.0" - wrap-ansi-cjs "npm:wrap-ansi@^7.0.0" - "@istanbuljs/load-nyc-config@^1.0.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced" @@ -1727,24 +1715,15 @@ resolved "https://registry.yarnpkg.com/@matterlabs/hardhat-zksync-deploy/-/hardhat-zksync-deploy-1.5.0.tgz#40cb454fb187da4bb354f3acb48762a6657fcb36" integrity sha512-7LAgYYwoKWHeR+3CyWEvA3NKBKtt7ktcr7SX6ZPgbEYqHAdXH02vxJZGwNADtMWpyYm8h+fEQkpPIgErD4NhmA== dependencies: - "@matterlabs/hardhat-zksync-solc" "^1.0.5" - chalk "4.1.2" - ts-morph "^19.0.0" - -"@matterlabs/hardhat-zksync-deploy@^1.3.0": - version "1.3.0" - resolved "https://registry.yarnpkg.com/@matterlabs/hardhat-zksync-deploy/-/hardhat-zksync-deploy-1.3.0.tgz#5c2b723318ddf6c4d3929ec225401864ff54557a" - integrity sha512-4UHOgOwIBC4JA3W8DE9GHqbAuBhCPAjtM+Oew1aiYYGkIsPUAMYsH35+4I2FzJsYyE6mD6ATmoS/HfZweQHTlQ== - dependencies: - "@matterlabs/hardhat-zksync-solc" "^1.0.4" - chai "^4.3.6" - chalk "4.1.2" + "@matterlabs/hardhat-zksync-solc" "^1.2.0" + chai "^4.3.4" + chalk "^4.1.2" fs-extra "^11.2.0" - glob "^10.3.10" + glob "^10.4.1" lodash "^4.17.21" - sinon "^17.0.1" + sinon "^18.0.0" sinon-chai "^3.7.0" - ts-morph "^21.0.1" + ts-morph "^22.0.0" "@matterlabs/hardhat-zksync-node@^0.0.1-beta.7": version "0.0.1" @@ -1789,7 +1768,7 @@ chalk "4.1.2" dockerode "^3.3.4" -"@matterlabs/hardhat-zksync-solc@^1.0.4", "@matterlabs/hardhat-zksync-solc@^1.0.5", "@matterlabs/hardhat-zksync-solc@^1.1.4": +"@matterlabs/hardhat-zksync-solc@^1.0.5", "@matterlabs/hardhat-zksync-solc@^1.1.4": version "1.1.4" resolved "https://registry.yarnpkg.com/@matterlabs/hardhat-zksync-solc/-/hardhat-zksync-solc-1.1.4.tgz#04a2fad6fb6b6944c64ad969080ee65b9af3f617" integrity sha512-4/usbogh9neewR2/v8Dn2OzqVblZMUuT/iH2MyPZgPRZYQlL4SlZtMvokU9UQjZT6iSoaKCbbdWESHDHSzfUjA== @@ -1823,10 +1802,10 @@ sinon-chai "^3.7.0" undici "^6.18.2" -"@matterlabs/hardhat-zksync-verify@^0.4.0": - version "0.4.0" - resolved "https://registry.yarnpkg.com/@matterlabs/hardhat-zksync-verify/-/hardhat-zksync-verify-0.4.0.tgz#f812c19950022fc36728f3796f6bdae5633e2fcd" - integrity sha512-GPZmAumFl3ZMPKbECX7Qw8CriwZKWd1DlCRhoG/6YYc6mFy4+MXkF1XsHLMs5r34N+GDOfbVZVMeftIlJC96Kg== +"@matterlabs/hardhat-zksync-solc@^1.2.4": + version "1.2.5" + resolved "https://registry.yarnpkg.com/@matterlabs/hardhat-zksync-solc/-/hardhat-zksync-solc-1.2.5.tgz#fbeeabc3fea0dd232fa3c8cb31bd93c103eba11a" + integrity sha512-iZyznWl1Hoe/Z46hnUe1s2drBZBjJOS/eN+Ql2lIBX9B6NevBl9DYzkKzH5HEIMCLGnX9sWpRAJqUQJWy9UB6w== dependencies: "@nomiclabs/hardhat-docker" "^2.0.2" chai "^4.3.4" @@ -1871,20 +1850,20 @@ sinon "^18.0.0" sinon-chai "^3.7.0" -"@matterlabs/hardhat-zksync-vyper@^1.0.8": - version "1.0.8" - resolved "https://registry.yarnpkg.com/@matterlabs/hardhat-zksync-vyper/-/hardhat-zksync-vyper-1.0.8.tgz#d5bd496715a1e322b0bf3926b4146b4e18ab64ff" - integrity sha512-XR7rbfDuBG5/LZWYfhQTP9gD+U24hSJHDuZ9U55wgIfiQTOxPoztFwEbQNiC39vjT5MjP/Nv8/IDrlEBkaVCgw== +"@matterlabs/hardhat-zksync-vyper@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@matterlabs/hardhat-zksync-vyper/-/hardhat-zksync-vyper-1.1.0.tgz#b3fb304429e88a84b4abc3fe4e5a83b2f5e907bd" + integrity sha512-zDjHPeIuHRpumXiWZUbhoji4UJe09jTDRn4xnxsuVkLH7qLAm0VDFzCXYNMvEuySZSdhbSbekxJsH9Kunc5ycA== dependencies: - "@nomiclabs/hardhat-docker" "^2.0.0" - chai "^4.3.6" - chalk "4.1.2" + "@nomiclabs/hardhat-docker" "^2.0.2" + chai "^4.3.4" + chalk "^4.1.2" dockerode "^4.0.2" - fs-extra "^11.1.1" - semver "^7.5.4" - sinon "^17.0.1" + fs-extra "^11.2.0" + semver "^7.6.2" + sinon "^18.0.0" sinon-chai "^3.7.0" - undici "^5.14.0" + undici "^6.18.2" "@matterlabs/prettier-config@^1.0.3": version "1.0.3" @@ -2324,11 +2303,6 @@ resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-4.9.6.tgz#2a880a24eb19b4f8b25adc2a5095f2aa27f39677" integrity sha512-xSmezSupL+y9VkHZJGDoCBpmnB2ogM13ccaYDWqJTfS3dbuHkgjuwDFUmaFauBCboQMGB/S5UqUl2y54X99BmA== -"@pkgjs/parseargs@^0.11.0": - version "0.11.0" - resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" - integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== - "@pkgr/core@^0.1.0": version "0.1.1" resolved "https://registry.yarnpkg.com/@pkgr/core/-/core-0.1.1.tgz#1ec17e2edbec25c8306d424ecfbf13c7de1aaa31" @@ -2659,16 +2633,6 @@ mkdirp "^2.1.6" path-browserify "^1.0.1" -"@ts-morph/common@~0.22.0": - version "0.22.0" - resolved "https://registry.yarnpkg.com/@ts-morph/common/-/common-0.22.0.tgz#8951d451622a26472fbc3a227d6c3a90e687a683" - integrity sha512-HqNBuV/oIlMKdkLshXd1zKBqNQCsuPEsgQOkfFQ/eUKjRlwndXW1AjN9LVkBEIukm00gGXSRmfkl0Wv5VXLnlw== - dependencies: - fast-glob "^3.3.2" - minimatch "^9.0.3" - mkdirp "^3.0.1" - path-browserify "^1.0.1" - "@tsconfig/node10@^1.0.7": version "1.0.11" resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.11.tgz#6ee46400685f130e278128c7b38b7e031ff5b2f2" @@ -3341,11 +3305,6 @@ ansi-regex@^5.0.1: resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== -ansi-regex@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a" - integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== - ansi-styles@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" @@ -3365,11 +3324,6 @@ ansi-styles@^5.0.0: resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b" integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== -ansi-styles@^6.1.0: - version "6.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5" - integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug== - antlr4@^4.11.0: version "4.13.1" resolved "https://registry.yarnpkg.com/antlr4/-/antlr4-4.13.1.tgz#1e0a1830a08faeb86217cb2e6c34716004e4253d" @@ -4481,7 +4435,7 @@ cross-spawn@^6.0.5: shebang-command "^1.2.0" which "^1.2.9" -cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3: +cross-spawn@^7.0.2, cross-spawn@^7.0.3: version "7.0.3" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== @@ -4784,11 +4738,6 @@ dotenv@^8.2.0: resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.6.0.tgz#061af664d19f7f4d8fc6e4ff9b584ce237adcb8b" integrity sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g== -eastasianwidth@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" - integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== - ecc-jsbn@~0.1.1: version "0.1.2" resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" @@ -4855,11 +4804,6 @@ emoji-regex@^8.0.0: resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== -emoji-regex@^9.2.2: - version "9.2.2" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" - integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== - encoding-down@^6.3.0: version "6.3.0" resolved "https://registry.yarnpkg.com/encoding-down/-/encoding-down-6.3.0.tgz#b1c4eb0e1728c146ecaef8e32963c549e76d082b" @@ -5830,14 +5774,6 @@ for-each@^0.3.3: dependencies: is-callable "^1.1.3" -foreground-child@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-3.1.1.tgz#1d173e776d75d2772fed08efe4a0de1ea1b12d0d" - integrity sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg== - dependencies: - cross-spawn "^7.0.0" - signal-exit "^4.0.1" - forever-agent@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" @@ -6126,17 +6062,6 @@ glob@8.1.0, glob@^8.0.3: minimatch "^5.0.1" once "^1.3.0" -glob@^10.3.10: - version "10.3.16" - resolved "https://registry.yarnpkg.com/glob/-/glob-10.3.16.tgz#bf6679d5d51279c8cfae4febe0d051d2a4bf4c6f" - integrity sha512-JDKXl1DiuuHJ6fVS2FXjownaavciiHNUU4mOvV/B793RLh05vZL1rcPnCSaOgv1hDT6RDlY7AB7ZUvFYAtPgAw== - dependencies: - foreground-child "^3.1.0" - jackspeak "^3.1.2" - minimatch "^9.0.1" - minipass "^7.0.4" - path-scurry "^1.11.0" - glob@^5.0.15: version "5.0.15" resolved "https://registry.yarnpkg.com/glob/-/glob-5.0.15.tgz#1bc936b9e02f4a603fcc222ecf7633d30b8b93b1" @@ -7049,15 +6974,6 @@ istanbul-reports@^3.1.3: html-escaper "^2.0.0" istanbul-lib-report "^3.0.0" -jackspeak@^3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-3.1.2.tgz#eada67ea949c6b71de50f1b09c92a961897b90ab" - integrity sha512-kWmLKn2tRtfYMF/BakihVVRzBKOxz4gJMiL2Rj91WnAB5TPZumSH99R/Yf1qE1u4uRimvCSJfm6hnxohXeEXjQ== - dependencies: - "@isaacs/cliui" "^8.0.2" - optionalDependencies: - "@pkgjs/parseargs" "^0.11.0" - jest-changed-files@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-29.7.0.tgz#1c06d07e77c78e1585d020424dedc10d6e17ac3a" @@ -7961,11 +7877,6 @@ lowercase-keys@^3.0.0: resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-3.0.0.tgz#c5e7d442e37ead247ae9db117a9d0a467c89d4f2" integrity sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ== -lru-cache@^10.2.0: - version "10.2.2" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.2.2.tgz#48206bc114c1252940c41b25b41af5b545aca878" - integrity sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ== - lru-cache@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" @@ -8264,13 +8175,6 @@ minimatch@^7.4.3: dependencies: brace-expansion "^2.0.1" -minimatch@^9.0.1, minimatch@^9.0.3: - version "9.0.4" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.4.tgz#8e49c731d1749cbec05050ee5145147b32496a51" - integrity sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw== - dependencies: - brace-expansion "^2.0.1" - minimatch@~3.0.4: version "3.0.8" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.8.tgz#5e6a59bd11e2ab0de1cfb843eb2d82e546c321c1" @@ -8283,11 +8187,6 @@ minimist@^1.2.0, minimist@^1.2.5, minimist@^1.2.6, minimist@^1.2.8, minimist@~1. resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== -"minipass@^5.0.0 || ^6.0.2 || ^7.0.0", minipass@^7.0.4: - version "7.1.1" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.1.1.tgz#f7f85aff59aa22f110b20e27692465cf3bf89481" - integrity sha512-UZ7eQ+h8ywIRAW1hIEl2AqdwzJucU/Kp59+8kkZeSvafXhZjul247BvIJjEVFVeON6d7lM46XX1HXCduKAS8VA== - mkdirp-classic@^0.5.2: version "0.5.3" resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113" @@ -8310,11 +8209,6 @@ mkdirp@^2.1.6: resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-2.1.6.tgz#964fbcb12b2d8c5d6fbc62a963ac95a273e2cc19" integrity sha512-+hEnITedc8LAtIP9u3HJDFIdcLV2vXP33sqLLIzkv1Db1zO/1OxbvYf0Y1OC/S/Qo5dxHXepofhmxL02PsKe+A== -mkdirp@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-3.0.1.tgz#e44e4c5607fb279c168241713cc6e0fea9adcb50" - integrity sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg== - mnemonist@^0.38.0: version "0.38.5" resolved "https://registry.yarnpkg.com/mnemonist/-/mnemonist-0.38.5.tgz#4adc7f4200491237fe0fa689ac0b86539685cade" @@ -8780,16 +8674,6 @@ package-json@^8.1.0: registry-url "^6.0.0" semver "^7.3.7" -package-json@^8.1.0: - version "8.1.1" - resolved "https://registry.yarnpkg.com/package-json/-/package-json-8.1.1.tgz#3e9948e43df40d1e8e78a85485f1070bf8f03dc8" - integrity sha512-cbH9IAIJHNj9uXi196JVsRlt7cHKak6u/e6AkL/bkRelZ7rlL3X1YKxsZwa36xipOEKAsdtmaG6aAJoM1fx2zA== - dependencies: - got "^12.1.0" - registry-auth-token "^5.0.1" - registry-url "^6.0.0" - semver "^7.3.7" - parent-module@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" @@ -8855,14 +8739,6 @@ path-parse@^1.0.6, path-parse@^1.0.7: resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== -path-scurry@^1.11.0: - version "1.11.1" - resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.11.1.tgz#7960a668888594a0720b12a911d1a742ab9f11d2" - integrity sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA== - dependencies: - lru-cache "^10.2.0" - minipass "^5.0.0 || ^6.0.2 || ^7.0.0" - path-to-regexp@^6.2.1: version "6.2.2" resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-6.2.2.tgz#324377a83e5049cbecadc5554d6a63a9a4866b36" @@ -9863,11 +9739,6 @@ signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7: resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== -signal-exit@^4.0.1: - version "4.1.0" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04" - integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== - sinon-chai@^3.7.0: version "3.7.0" resolved "https://registry.yarnpkg.com/sinon-chai/-/sinon-chai-3.7.0.tgz#cfb7dec1c50990ed18c153f1840721cf13139783" @@ -10199,15 +10070,6 @@ string-length@^4.0.1: char-regex "^1.0.2" strip-ansi "^6.0.0" -"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2, string-width@^4.2.3: - version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - string-width@^2.1.0, string-width@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" @@ -10216,14 +10078,14 @@ string-width@^2.1.0, string-width@^2.1.1: is-fullwidth-code-point "^2.0.0" strip-ansi "^4.0.0" -string-width@^5.0.1, string-width@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794" - integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== +string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2, string-width@^4.2.3: + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== dependencies: - eastasianwidth "^0.2.0" - emoji-regex "^9.2.2" - strip-ansi "^7.0.1" + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" string.prototype.padend@^3.0.0: version "3.1.6" @@ -10282,13 +10144,6 @@ string_decoder@~1.1.1: dependencies: safe-buffer "~5.1.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - strip-ansi@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" @@ -10303,12 +10158,12 @@ strip-ansi@^5.1.0: dependencies: ansi-regex "^4.1.0" -strip-ansi@^7.0.1: - version "7.1.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" - integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ== +strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== dependencies: - ansi-regex "^6.0.1" + ansi-regex "^5.0.1" strip-bom@^3.0.0: version "3.0.0" @@ -10413,6 +10268,7 @@ synckit@^0.8.6: fast-glob "^3.3.2" hardhat "=2.22.2" preprocess "^3.2.0" + zksync-ethers "^5.9.0" table-layout@^1.0.2: version "1.0.2" @@ -10664,14 +10520,6 @@ ts-morph@^19.0.0: "@ts-morph/common" "~0.20.0" code-block-writer "^12.0.0" -ts-morph@^21.0.1: - version "21.0.1" - resolved "https://registry.yarnpkg.com/ts-morph/-/ts-morph-21.0.1.tgz#712302a0f6e9dbf1aa8d9cf33a4386c4b18c2006" - integrity sha512-dbDtVdEAncKctzrVZ+Nr7kHpHkv+0JDJb2MjjpBaj8bFeCkePU9rHfMklmhuLFnpeq/EJZk2IhStY6NzqgjOkg== - dependencies: - "@ts-morph/common" "~0.22.0" - code-block-writer "^12.0.0" - ts-node@^10.1.0, ts-node@^10.7.0: version "10.9.2" resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.2.tgz#70f021c9e185bccdca820e26dc413805c101c71f" @@ -11152,7 +11000,7 @@ workerpool@6.2.1: resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.1.tgz#46fc150c17d826b86a008e5a4508656777e9c343" integrity sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw== -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: +wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== @@ -11161,15 +11009,6 @@ workerpool@6.2.1: string-width "^4.1.0" strip-ansi "^6.0.0" -wrap-ansi@^8.1.0: - version "8.1.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" - integrity sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ== - dependencies: - ansi-styles "^6.1.0" - string-width "^5.0.1" - strip-ansi "^7.0.1" - wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" diff --git a/zkstack_cli/crates/config/src/contracts.rs b/zkstack_cli/crates/config/src/contracts.rs index e6676989e68c..6d336b5cfc17 100644 --- a/zkstack_cli/crates/config/src/contracts.rs +++ b/zkstack_cli/crates/config/src/contracts.rs @@ -85,6 +85,7 @@ impl ContractsConfig { ) -> anyhow::Result<()> { self.bridges.shared.l2_address = Some(initialize_bridges_output.l2_shared_bridge_proxy); self.bridges.erc20.l2_address = Some(initialize_bridges_output.l2_shared_bridge_proxy); + self.l2.legacy_shared_bridge_addr = Some(initialize_bridges_output.l2_shared_bridge_proxy); Ok(()) } @@ -159,4 +160,5 @@ pub struct L2Contracts { pub default_l2_upgrader: Address, pub consensus_registry: Option

, pub multicall3: Option
, + pub legacy_shared_bridge_addr: Option
, } From ee73a3973b0c65b1d4acef12e4b64db8f813e77d Mon Sep 17 00:00:00 2001 From: Daniyar Itegulov Date: Thu, 24 Oct 2024 20:51:48 +1100 Subject: [PATCH 27/27] feat(zkstack_cli): use docker-managed volumes (#3140) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## What ❔ Host-bound volumes never get cleaned even if you do `docker compose down -v`. Existing dev flows don't seem to rely on volumes being on the host machine, so this is PoC of how we can move to Docker-managed volumes. ## Why ❔ Avoid pesky bugs that prevent user from deleting `./volumes`, rely on Docker to persist and dispose of data as need be ## Checklist - [ ] PR title corresponds to the body of PR (we generate changelog entries from PRs). - [ ] Tests for the changes have been added / updated. - [ ] Documentation comments have been added / updated. - [ ] Code has been formatted via `zkstack dev fmt` and `zkstack dev lint`. --- .../workflows/build-contract-verifier-template.yml | 1 - .github/workflows/build-core-template.yml | 1 - .github/workflows/build-local-node-docker.yml | 1 - .github/workflows/build-prover-template.yml | 1 - .../workflows/build-witness-generator-template.yml | 1 - .github/workflows/ci-common-reusable.yml | 1 - .github/workflows/ci-prover-e2e.yml | 1 - .github/workflows/ci-prover-reusable.yml | 2 -- bin/ci_localnet_up | 1 - docker-compose-gpu-runner-cuda-12-0.yml | 8 ++++++-- docker-compose-runner-nightly.yml | 5 ++++- docker-compose-unit-tests.yml | 1 - docker-compose.yml | 13 ++++++++----- zkstack_cli/crates/common/src/docker.rs | 6 +++++- .../crates/zkstack/src/commands/containers.rs | 12 ------------ .../zkstack/src/commands/dev/commands/clean/mod.rs | 6 +----- .../crates/zkstack/src/commands/dev/messages.rs | 4 +--- 17 files changed, 25 insertions(+), 40 deletions(-) diff --git a/.github/workflows/build-contract-verifier-template.yml b/.github/workflows/build-contract-verifier-template.yml index e4d04b90410e..1481e542de57 100644 --- a/.github/workflows/build-contract-verifier-template.yml +++ b/.github/workflows/build-contract-verifier-template.yml @@ -101,7 +101,6 @@ jobs: - name: start-services run: | echo "IMAGE_TAG_SUFFIX=${{ env.IMAGE_TAG_SUFFIX }}" >> .env - mkdir -p ./volumes/postgres run_retried docker compose pull zk postgres docker compose up -d zk postgres ci_run pre_download_compilers.sh diff --git a/.github/workflows/build-core-template.yml b/.github/workflows/build-core-template.yml index fe1d23427645..15d4432191dd 100644 --- a/.github/workflows/build-core-template.yml +++ b/.github/workflows/build-core-template.yml @@ -114,7 +114,6 @@ jobs: - name: start-services run: | echo "IMAGE_TAG_SUFFIX=${{ env.IMAGE_TAG_SUFFIX }}" >> .env - mkdir -p ./volumes/postgres run_retried docker compose pull zk postgres docker compose up -d zk postgres ci_run pre_download_compilers.sh diff --git a/.github/workflows/build-local-node-docker.yml b/.github/workflows/build-local-node-docker.yml index 80142cb6005c..cbb4239b5725 100644 --- a/.github/workflows/build-local-node-docker.yml +++ b/.github/workflows/build-local-node-docker.yml @@ -50,7 +50,6 @@ jobs: - name: start-services run: | - mkdir -p ./volumes/postgres run_retried docker compose pull zk postgres docker compose up -d zk postgres diff --git a/.github/workflows/build-prover-template.yml b/.github/workflows/build-prover-template.yml index 2dcb5dadb174..91de5dd51ecf 100644 --- a/.github/workflows/build-prover-template.yml +++ b/.github/workflows/build-prover-template.yml @@ -75,7 +75,6 @@ jobs: - name: start-services run: | echo "IMAGE_TAG_SUFFIX=${{ env.IMAGE_TAG_SUFFIX }}" >> .env - mkdir -p ./volumes/postgres run_retried docker compose pull zk postgres docker compose up -d zk postgres ci_run sccache --start-server diff --git a/.github/workflows/build-witness-generator-template.yml b/.github/workflows/build-witness-generator-template.yml index 33d78b3cf2fc..d9493f97cae1 100644 --- a/.github/workflows/build-witness-generator-template.yml +++ b/.github/workflows/build-witness-generator-template.yml @@ -75,7 +75,6 @@ jobs: - name: start-services run: | echo "IMAGE_TAG_SUFFIX=${{ env.IMAGE_TAG_SUFFIX }}" >> .env - mkdir -p ./volumes/postgres run_retried docker compose pull zk postgres docker compose up -d zk postgres ci_run sccache --start-server diff --git a/.github/workflows/ci-common-reusable.yml b/.github/workflows/ci-common-reusable.yml index 7d75fb224d6e..ea91fc4a7cd6 100644 --- a/.github/workflows/ci-common-reusable.yml +++ b/.github/workflows/ci-common-reusable.yml @@ -27,7 +27,6 @@ jobs: - name: Start services run: | run_retried docker-compose -f ${RUNNER_COMPOSE_FILE} pull - mkdir -p ./volumes/postgres docker-compose -f ${RUNNER_COMPOSE_FILE} up --build -d zk postgres - name: Install zkstack diff --git a/.github/workflows/ci-prover-e2e.yml b/.github/workflows/ci-prover-e2e.yml index 105ae1f1485d..b0b9caf888fc 100644 --- a/.github/workflows/ci-prover-e2e.yml +++ b/.github/workflows/ci-prover-e2e.yml @@ -29,7 +29,6 @@ jobs: - name: Start services run: | run_retried docker-compose -f ${RUNNER_COMPOSE_FILE} pull - mkdir -p ./volumes/postgres ./volumes/reth/data docker-compose -f ${RUNNER_COMPOSE_FILE} --profile runner up -d --wait ci_run sccache --start-server diff --git a/.github/workflows/ci-prover-reusable.yml b/.github/workflows/ci-prover-reusable.yml index 4154885549b8..7f719b2240db 100644 --- a/.github/workflows/ci-prover-reusable.yml +++ b/.github/workflows/ci-prover-reusable.yml @@ -27,7 +27,6 @@ jobs: - name: Start services run: | run_retried docker-compose -f ${RUNNER_COMPOSE_FILE} pull - mkdir -p ./volumes/postgres docker-compose -f ${RUNNER_COMPOSE_FILE} up --build -d zk postgres - name: Install zkstack @@ -68,7 +67,6 @@ jobs: - name: Start services run: | run_retried docker-compose -f ${RUNNER_COMPOSE_FILE} pull - mkdir -p ./volumes/postgres docker-compose -f ${RUNNER_COMPOSE_FILE} up --build -d zk postgres - name: Install zkstack diff --git a/bin/ci_localnet_up b/bin/ci_localnet_up index 8673a909af77..c399de410d74 100755 --- a/bin/ci_localnet_up +++ b/bin/ci_localnet_up @@ -4,6 +4,5 @@ set -e cd $ZKSYNC_HOME -mkdir -p ./volumes/postgres ./volumes/reth/data run_retried docker-compose pull docker-compose --profile runner up -d --wait diff --git a/docker-compose-gpu-runner-cuda-12-0.yml b/docker-compose-gpu-runner-cuda-12-0.yml index c930fa376f5e..bd91a5a5b0e4 100644 --- a/docker-compose-gpu-runner-cuda-12-0.yml +++ b/docker-compose-gpu-runner-cuda-12-0.yml @@ -6,8 +6,8 @@ services: ports: - 127.0.0.1:8545:8545 volumes: - - type: bind - source: ./volumes/reth/data + - type: volume + source: reth-data target: /rethdata - type: bind source: ./etc/reth/chaindata @@ -69,3 +69,7 @@ services: environment: # We bind only to 127.0.0.1, so setting insecure password is acceptable here - POSTGRES_PASSWORD=notsecurepassword + +volumes: + postgres-data: + reth-data: \ No newline at end of file diff --git a/docker-compose-runner-nightly.yml b/docker-compose-runner-nightly.yml index cadd1009f7a6..4a854aa0b0a4 100644 --- a/docker-compose-runner-nightly.yml +++ b/docker-compose-runner-nightly.yml @@ -1,4 +1,3 @@ -version: '3.2' services: zk: image: ghcr.io/matter-labs/zk-environment:latest2.0-lightweight-nightly @@ -15,3 +14,7 @@ services: extends: file: docker-compose.yml service: reth + +volumes: + postgres-data: + reth-data: \ No newline at end of file diff --git a/docker-compose-unit-tests.yml b/docker-compose-unit-tests.yml index ddbc76bb196c..b839be2d9f4f 100644 --- a/docker-compose-unit-tests.yml +++ b/docker-compose-unit-tests.yml @@ -1,4 +1,3 @@ -version: '3.2' name: unit_tests services: # An instance of postgres configured to execute Rust unit-tests, tuned for performance. diff --git a/docker-compose.yml b/docker-compose.yml index 1e3a273ec9a4..d8f40720fe84 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,4 +1,3 @@ -version: '3.2' services: reth: restart: always @@ -6,8 +5,8 @@ services: ports: - 127.0.0.1:8545:8545 volumes: - - type: bind - source: ./volumes/reth/data + - type: volume + source: reth-data target: /rethdata - type: bind source: ./etc/reth/chaindata @@ -22,8 +21,8 @@ services: ports: - 127.0.0.1:5432:5432 volumes: - - type: bind - source: ./volumes/postgres + - type: volume + source: postgres-data target: /var/lib/postgresql/data environment: # We bind only to 127.0.0.1, so setting insecure password is acceptable here @@ -56,3 +55,7 @@ services: profiles: - runner network_mode: host + +volumes: + postgres-data: + reth-data: \ No newline at end of file diff --git a/zkstack_cli/crates/common/src/docker.rs b/zkstack_cli/crates/common/src/docker.rs index a5731808814f..71e2040ee31c 100644 --- a/zkstack_cli/crates/common/src/docker.rs +++ b/zkstack_cli/crates/common/src/docker.rs @@ -14,7 +14,11 @@ pub fn up(shell: &Shell, docker_compose_file: &str, detach: bool) -> anyhow::Res } pub fn down(shell: &Shell, docker_compose_file: &str) -> anyhow::Result<()> { - Ok(Cmd::new(cmd!(shell, "docker compose -f {docker_compose_file} down")).run()?) + Ok(Cmd::new(cmd!( + shell, + "docker compose -f {docker_compose_file} down -v" + )) + .run()?) } pub fn run(shell: &Shell, docker_image: &str, docker_args: Vec) -> anyhow::Result<()> { diff --git a/zkstack_cli/crates/zkstack/src/commands/containers.rs b/zkstack_cli/crates/zkstack/src/commands/containers.rs index 9c11cc2e3efc..8367289bd67f 100644 --- a/zkstack_cli/crates/zkstack/src/commands/containers.rs +++ b/zkstack_cli/crates/zkstack/src/commands/containers.rs @@ -36,10 +36,6 @@ pub fn run(shell: &Shell, args: ContainersArgs) -> anyhow::Result<()> { } pub fn initialize_docker(shell: &Shell, ecosystem: &EcosystemConfig) -> anyhow::Result<()> { - if !shell.path_exists("volumes") { - create_docker_folders(shell)?; - }; - if !shell.path_exists(DOCKER_COMPOSE_FILE) { copy_dockerfile(shell, ecosystem.link_to_code.clone())?; }; @@ -75,14 +71,6 @@ pub fn start_containers(shell: &Shell, observability: bool) -> anyhow::Result<() Ok(()) } -fn create_docker_folders(shell: &Shell) -> anyhow::Result<()> { - shell.create_dir("volumes")?; - shell.create_dir("volumes/postgres")?; - shell.create_dir("volumes/reth")?; - shell.create_dir("volumes/reth/data")?; - Ok(()) -} - fn copy_dockerfile(shell: &Shell, link_to_code: PathBuf) -> anyhow::Result<()> { let docker_compose_file = link_to_code.join(DOCKER_COMPOSE_FILE); diff --git a/zkstack_cli/crates/zkstack/src/commands/dev/commands/clean/mod.rs b/zkstack_cli/crates/zkstack/src/commands/dev/commands/clean/mod.rs index 4cb419ce7a46..0929f5e4623f 100644 --- a/zkstack_cli/crates/zkstack/src/commands/dev/commands/clean/mod.rs +++ b/zkstack_cli/crates/zkstack/src/commands/dev/commands/clean/mod.rs @@ -5,8 +5,7 @@ use config::{EcosystemConfig, DOCKER_COMPOSE_FILE}; use xshell::Shell; use crate::commands::dev::messages::{ - MSG_CONTRACTS_CLEANING, MSG_CONTRACTS_CLEANING_FINISHED, MSG_DOCKER_COMPOSE_CLEANED, - MSG_DOCKER_COMPOSE_DOWN, MSG_DOCKER_COMPOSE_REMOVE_VOLUMES, + MSG_CONTRACTS_CLEANING, MSG_CONTRACTS_CLEANING_FINISHED, MSG_DOCKER_COMPOSE_DOWN, }; #[derive(Subcommand, Debug)] @@ -35,9 +34,6 @@ pub fn run(shell: &Shell, args: CleanCommands) -> anyhow::Result<()> { pub fn containers(shell: &Shell) -> anyhow::Result<()> { logger::info(MSG_DOCKER_COMPOSE_DOWN); docker::down(shell, DOCKER_COMPOSE_FILE)?; - logger::info(MSG_DOCKER_COMPOSE_REMOVE_VOLUMES); - shell.remove_path("volumes")?; - logger::info(MSG_DOCKER_COMPOSE_CLEANED); Ok(()) } diff --git a/zkstack_cli/crates/zkstack/src/commands/dev/messages.rs b/zkstack_cli/crates/zkstack/src/commands/dev/messages.rs index a38fff5a178a..3d31497b7ebc 100644 --- a/zkstack_cli/crates/zkstack/src/commands/dev/messages.rs +++ b/zkstack_cli/crates/zkstack/src/commands/dev/messages.rs @@ -157,9 +157,7 @@ pub(super) const MSG_UPGRADE_TEST_RUN_INFO: &str = "Running upgrade test"; pub(super) const MSG_UPGRADE_TEST_RUN_SUCCESS: &str = "Upgrade test ran successfully"; // Cleaning related messages -pub(super) const MSG_DOCKER_COMPOSE_DOWN: &str = "docker compose down"; -pub(super) const MSG_DOCKER_COMPOSE_REMOVE_VOLUMES: &str = "docker compose remove volumes"; -pub(super) const MSG_DOCKER_COMPOSE_CLEANED: &str = "docker compose network cleaned"; +pub(super) const MSG_DOCKER_COMPOSE_DOWN: &str = "docker compose down -v"; pub(super) const MSG_CONTRACTS_CLEANING: &str = "Removing contracts building and deployment artifacts"; pub(super) const MSG_CONTRACTS_CLEANING_FINISHED: &str =