From 867f2bf3b1135bb48f4aea9dedecd5de34361368 Mon Sep 17 00:00:00 2001 From: Marcin M <128217157+mm-zk@users.noreply.github.com> Date: Thu, 5 Oct 2023 10:05:16 +0200 Subject: [PATCH] feat(boojum): added flag to control prover selection at genesis (#158) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # What ❔ * Added CONTRACTS_PROVER_AT_GENESIS flag to control which prover should be used during genesis * Updated zk status command to compare the keys in the database and in the contracts ## Why ❔ * without this flag, we were pushing the old keys to the contracts, which resulted in failed proofs. --- core/lib/config/src/configs/contracts.rs | 4 +- core/lib/zksync_core/src/lib.rs | 36 ++++++++++----- etc/env/base/contracts.toml | 3 ++ infrastructure/zk/src/status.ts | 59 +++++++++++++++++++++++- 4 files changed, 89 insertions(+), 13 deletions(-) diff --git a/core/lib/config/src/configs/contracts.rs b/core/lib/config/src/configs/contracts.rs index b3fbcf030ccd..eafaf49e0ff3 100644 --- a/core/lib/config/src/configs/contracts.rs +++ b/core/lib/config/src/configs/contracts.rs @@ -34,6 +34,7 @@ pub struct ContractsConfig { pub fri_recursion_scheduler_level_vk_hash: H256, pub fri_recursion_node_level_vk_hash: H256, pub fri_recursion_leaf_level_vk_hash: H256, + pub prover_at_genesis: String, } impl ContractsConfig { @@ -93,6 +94,7 @@ mod tests { fri_recursion_leaf_level_vk_hash: hash( "0x72167c43a46cf38875b267d67716edc4563861364a3c03ab7aee73498421e828", ), + prover_at_genesis: "fri".to_string(), } } @@ -126,7 +128,7 @@ CONTRACTS_L1_MULTICALL3_ADDR="0xcA11bde05977b3631167028862bE2a173976CA11" CONTRACTS_FRI_RECURSION_SCHEDULER_LEVEL_VK_HASH="0x201d4c7d8e781d51a3bbd451a43a8f45240bb765b565ae6ce69192d918c3563d" CONTRACTS_FRI_RECURSION_NODE_LEVEL_VK_HASH="0x5a3ef282b21e12fe1f4438e5bb158fc5060b160559c5158c6389d62d9fe3d080" CONTRACTS_FRI_RECURSION_LEAF_LEVEL_VK_HASH="0x72167c43a46cf38875b267d67716edc4563861364a3c03ab7aee73498421e828" - +CONTRACTS_PROVER_AT_GENESIS="fri" "#; lock.set_env(config); diff --git a/core/lib/zksync_core/src/lib.rs b/core/lib/zksync_core/src/lib.rs index dee14e7a2f1f..bfc83c9020c1 100644 --- a/core/lib/zksync_core/src/lib.rs +++ b/core/lib/zksync_core/src/lib.rs @@ -122,6 +122,30 @@ pub async fn genesis_init( ) .context("Failed to restore operator address from private key")?; + // Select the first prover to be used during genesis. + // Later we can change provers using the system upgrades, but for genesis + // we should select one using the environment config. + let first_l1_verifier_config = if contracts_config.prover_at_genesis == "fri" { + L1VerifierConfig { + params: VerifierParams { + recursion_node_level_vk_hash: contracts_config.fri_recursion_node_level_vk_hash, + recursion_leaf_level_vk_hash: contracts_config.fri_recursion_leaf_level_vk_hash, + recursion_circuits_set_vks_hash: zksync_types::H256::zero(), + }, + recursion_scheduler_level_vk_hash: contracts_config + .fri_recursion_scheduler_level_vk_hash, + } + } else { + L1VerifierConfig { + params: VerifierParams { + recursion_node_level_vk_hash: contracts_config.recursion_node_level_vk_hash, + recursion_leaf_level_vk_hash: contracts_config.recursion_leaf_level_vk_hash, + recursion_circuits_set_vks_hash: contracts_config.recursion_circuits_set_vks_hash, + }, + recursion_scheduler_level_vk_hash: contracts_config.recursion_scheduler_level_vk_hash, + } + }; + genesis::ensure_genesis_state( &mut storage, L2ChainId(network_config.zksync_network_id), @@ -132,17 +156,7 @@ pub async fn genesis_init( base_system_contracts: BaseSystemContracts::load_from_disk(), system_contracts: get_system_smart_contracts(), first_verifier_address: contracts_config.verifier_addr, - first_l1_verifier_config: L1VerifierConfig { - params: VerifierParams { - recursion_node_level_vk_hash: contracts_config.recursion_node_level_vk_hash, - recursion_leaf_level_vk_hash: contracts_config.recursion_leaf_level_vk_hash, - recursion_circuits_set_vks_hash: contracts_config - .recursion_circuits_set_vks_hash, - }, - // FIXME: we should have a flag to decide on the type of proofs at genesis. - recursion_scheduler_level_vk_hash: contracts_config - .fri_recursion_scheduler_level_vk_hash, - }, + first_l1_verifier_config, }, ) .await?; diff --git a/etc/env/base/contracts.toml b/etc/env/base/contracts.toml index c68c21170c50..82f795e83899 100644 --- a/etc/env/base/contracts.toml +++ b/etc/env/base/contracts.toml @@ -42,6 +42,9 @@ FRI_RECURSION_LEAF_LEVEL_VK_HASH ="0x72167c43a46cf38875b267d67716edc4563861364a3 FRI_RECURSION_NODE_LEVEL_VK_HASH ="0x5a3ef282b21e12fe1f4438e5bb158fc5060b160559c5158c6389d62d9fe3d080" FRI_RECURSION_SCHEDULER_LEVEL_VK_HASH ="0x4be443afd605a782b6e56d199df2460a025c81b3dea144e135bece83612563f2" +# Prover that should be used at genesis. 'fri' or 'snark' +PROVER_AT_GENESIS="fri" + [contracts.test] dummy_verifier=true easy_priority_mode=false diff --git a/infrastructure/zk/src/status.ts b/infrastructure/zk/src/status.ts index 11f8bdf7e260..5311b47843c1 100644 --- a/infrastructure/zk/src/status.ts +++ b/infrastructure/zk/src/status.ts @@ -9,7 +9,8 @@ let pool: Pool | null = null; const GETTER_ABI = [ 'function getTotalBlocksCommitted() view returns (uint256)', - 'function getTotalBlocksVerified() view returns (uint256)' + 'function getTotalBlocksVerified() view returns (uint256)', + 'function getVerifierParams() view returns (bytes32, bytes32, bytes32)' ]; const VERIFIER_ABI = ['function verificationKeyHash() view returns (bytes32)']; @@ -120,10 +121,65 @@ async function compareVerificationKeys() { console.log( `${redStart}Verification hash in DB differs from the one in contract.${resetColor} State keeper might not send prove requests.` ); + } else { + console.log(`${greenStart}Verifier hash matches.${resetColor}`); + } +} + +async function compareVerificationParams() { + // Setup a provider + let provider = new ethers.providers.JsonRpcProvider(process.env.ETH_CLIENT_WEB3_URL); + + // Create a contract instance (diamond proxy doesn't expose this one) + let contract = new ethers.Contract(process.env.CONTRACTS_DIAMOND_PROXY_ADDR!, GETTER_ABI, provider); + let node, leaf, circuits; + try { + [node, leaf, circuits] = await contract.getVerifierParams(); + console.log(`Verifier params on contract are ${node}, ${leaf}, ${circuits}`); + } catch (error) { + console.error(`Error calling L1 contract: ${error}`); + return; + } + + let protocol_version = await query( + 'select recursion_node_level_vk_hash, recursion_leaf_level_vk_hash, recursion_circuits_set_vks_hash from prover_fri_protocol_versions' + ); + if (protocol_version.rowCount != 1) { + console.log(`${redStart}Got ${protocol_version.rowCount} rows with protocol versions, expected 1${resetColor}`); + return; + } + let dbNode = '0x' + bytesToHex(protocol_version.rows[0].recursion_node_level_vk_hash); + let dbLeaf = '0x' + bytesToHex(protocol_version.rows[0].recursion_leaf_level_vk_hash); + let dbCircuit = '0x' + bytesToHex(protocol_version.rows[0].recursion_circuits_set_vks_hash); + + let fail = false; + + if (dbNode != node) { + fail = true; + console.log( + `${redStart}Verification node in DB differs from the one in contract ${dbNode} vs ${node}.${resetColor}` + ); + } + if (dbLeaf != leaf) { + fail = true; + console.log( + `${redStart}Verification leaf in DB differs from the one in contract ${dbLeaf} vs ${leaf}.${resetColor}` + ); + } + if (dbCircuit != circuits) { + fail = true; + console.log( + `${redStart}Verification circuits in DB differs from the one in contract ${dbCircuit} vs ${circuits}.${resetColor}` + ); + } + + if (fail == false) { + console.log(`${greenStart}Verifcation params match.${resetColor}`); } } const redStart = '\x1b[31m'; +const greenStart = '\x1b[32m'; const resetColor = '\x1b[0m'; export async function statusProver() { @@ -151,6 +207,7 @@ export async function statusProver() { return; } await compareVerificationKeys(); + await compareVerificationParams(); const nextBlockForVerification = blockVerified + 1;