From 9b773ebb3c170dc3d503ec83fb33d8d463614b4f Mon Sep 17 00:00:00 2001 From: perekopskiy <53865202+perekopskiy@users.noreply.github.com> Date: Mon, 26 Feb 2024 14:36:55 +0200 Subject: [PATCH] feat(commitment-generator): Commitment for 1.4.2 (#1234) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## What ❔ Adds support for 1.4.2 commitment (blob hashes are taken into account) ## 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 fmt` and `zk lint`. - [ ] Spellcheck has been run via `zk spellcheck`. - [ ] Linkcheck has been run via `zk linkcheck`. --- Cargo.lock | 4 +- checks-config/era.dic | 1 + core/bin/external_node/src/config/mod.rs | 7 + core/bin/external_node/src/main.rs | 5 +- core/bin/zksync_server/src/main.rs | 5 +- core/lib/config/src/configs/kzg.rs | 14 + core/lib/config/src/configs/mod.rs | 2 + core/lib/constants/src/contracts.rs | 5 + core/lib/constants/src/system_logs.rs | 6 + core/lib/env_config/src/kzg.rs | 35 + core/lib/env_config/src/lib.rs | 1 + .../src/i_executor/commit/kzg.rs | 40 +- .../src/i_executor/commit/mod.rs | 2 +- .../src/i_executor/mod.rs | 3 +- .../src/versions/vm_latest/tests/block_tip.rs | 9 +- core/lib/protobuf_config/src/kzg.rs | 22 + core/lib/protobuf_config/src/lib.rs | 1 + core/lib/protobuf_config/src/proto/kzg.proto | 7 + core/lib/types/src/commitment/mod.rs | 67 +- core/lib/types/src/commitment/tests/mod.rs | 9 +- ..._test.json => post_boojum_1_4_1_test.json} | 7 +- .../tests/post_boojum_1_4_2_test.json | 847 ++++++++++++++++++ core/lib/types/src/l2_to_l1_log.rs | 26 +- core/lib/types/src/protocol_version.rs | 8 + .../src/api_server/web3/namespaces/zks.rs | 19 +- .../src/commitment_generator/mod.rs | 43 +- core/lib/zksync_core/src/lib.rs | 4 +- core/lib/zksync_core/src/temp_config_store.rs | 5 +- core/tests/upgrade-test/tests/upgrade.test.ts | 6 +- docker/external-node/Dockerfile | 1 + docker/server-v2/Dockerfile | 1 + etc/env/base/kzg.toml | 2 + etc/env/dev.toml | 1 + 33 files changed, 1155 insertions(+), 60 deletions(-) create mode 100644 core/lib/config/src/configs/kzg.rs create mode 100644 core/lib/env_config/src/kzg.rs create mode 100644 core/lib/protobuf_config/src/kzg.rs create mode 100644 core/lib/protobuf_config/src/proto/kzg.proto rename core/lib/types/src/commitment/tests/{post_boojum_test.json => post_boojum_1_4_1_test.json} (97%) create mode 100644 core/lib/types/src/commitment/tests/post_boojum_1_4_2_test.json create mode 100644 etc/env/base/kzg.toml diff --git a/Cargo.lock b/Cargo.lock index c465e487f70..8003e316c08 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4276,9 +4276,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.18.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "oorandom" diff --git a/checks-config/era.dic b/checks-config/era.dic index d8248e0afa4..14a5e715230 100644 --- a/checks-config/era.dic +++ b/checks-config/era.dic @@ -905,3 +905,4 @@ shivini balancer lookups stateful +WIP diff --git a/core/bin/external_node/src/config/mod.rs b/core/bin/external_node/src/config/mod.rs index 34dd6b1f422..5a9f0fe0d24 100644 --- a/core/bin/external_node/src/config/mod.rs +++ b/core/bin/external_node/src/config/mod.rs @@ -222,6 +222,9 @@ pub struct OptionalENConfig { /// 0 means that sealing is synchronous; this is mostly useful for performance comparison, testing etc. #[serde(default = "OptionalENConfig::default_miniblock_seal_queue_capacity")] pub miniblock_seal_queue_capacity: usize, + /// Path to KZG trusted setup path. + #[serde(default = "OptionalENConfig::default_kzg_trusted_setup_path")] + pub kzg_trusted_setup_path: String, } impl OptionalENConfig { @@ -328,6 +331,10 @@ impl OptionalENConfig { 10 } + fn default_kzg_trusted_setup_path() -> String { + "./trusted_setup.json".to_owned() + } + pub fn polling_interval(&self) -> Duration { Duration::from_millis(self.polling_interval) } diff --git a/core/bin/external_node/src/main.rs b/core/bin/external_node/src/main.rs index 0aa061955cf..4775ccc4dde 100644 --- a/core/bin/external_node/src/main.rs +++ b/core/bin/external_node/src/main.rs @@ -264,7 +264,10 @@ async fn init_tasks( .build() .await .context("failed to build a commitment_generator_pool")?; - let commitment_generator = CommitmentGenerator::new(commitment_generator_pool); + let commitment_generator = CommitmentGenerator::new( + commitment_generator_pool, + &config.optional.kzg_trusted_setup_path, + ); app_health.insert_component(commitment_generator.health_check()); let commitment_generator_handle = tokio::spawn(commitment_generator.run(stop_receiver.clone())); diff --git a/core/bin/zksync_server/src/main.rs b/core/bin/zksync_server/src/main.rs index fe75a47e7ae..b6ac8195eb6 100644 --- a/core/bin/zksync_server/src/main.rs +++ b/core/bin/zksync_server/src/main.rs @@ -11,8 +11,8 @@ use zksync_config::{ }, fri_prover_group::FriProverGroupConfig, house_keeper::HouseKeeperConfig, - FriProofCompressorConfig, FriProverConfig, FriWitnessGeneratorConfig, ObservabilityConfig, - PrometheusConfig, ProofDataHandlerConfig, WitnessGeneratorConfig, + FriProofCompressorConfig, FriProverConfig, FriWitnessGeneratorConfig, KzgConfig, + ObservabilityConfig, PrometheusConfig, ProofDataHandlerConfig, WitnessGeneratorConfig, }, ApiConfig, ContractsConfig, DBConfig, ETHClientConfig, ETHSenderConfig, ETHWatchConfig, GasAdjusterConfig, ObjectStoreConfig, PostgresConfig, @@ -125,6 +125,7 @@ async fn main() -> anyhow::Result<()> { eth_watch_config: ETHWatchConfig::from_env().ok(), gas_adjuster_config: GasAdjusterConfig::from_env().ok(), object_store_config: ObjectStoreConfig::from_env().ok(), + kzg_config: KzgConfig::from_env().ok(), consensus_config: None, }; diff --git a/core/lib/config/src/configs/kzg.rs b/core/lib/config/src/configs/kzg.rs new file mode 100644 index 00000000000..8a7c8f5f022 --- /dev/null +++ b/core/lib/config/src/configs/kzg.rs @@ -0,0 +1,14 @@ +use serde::Deserialize; + +#[derive(Debug, Deserialize, Clone, PartialEq)] +pub struct KzgConfig { + /// Path to KZG trusted setup file. + #[serde(default = "KzgConfig::default_trusted_setup_path")] + pub trusted_setup_path: String, +} + +impl KzgConfig { + fn default_trusted_setup_path() -> String { + "./trusted_setup.json".to_owned() + } +} diff --git a/core/lib/config/src/configs/mod.rs b/core/lib/config/src/configs/mod.rs index f9ad80dbe34..b86e0dcc385 100644 --- a/core/lib/config/src/configs/mod.rs +++ b/core/lib/config/src/configs/mod.rs @@ -13,6 +13,7 @@ pub use self::{ fri_prover_gateway::FriProverGatewayConfig, fri_witness_generator::FriWitnessGeneratorConfig, fri_witness_vector_generator::FriWitnessVectorGeneratorConfig, + kzg::KzgConfig, object_store::ObjectStoreConfig, observability::ObservabilityConfig, proof_data_handler::ProofDataHandlerConfig, @@ -37,6 +38,7 @@ pub mod fri_prover_group; pub mod fri_witness_generator; pub mod fri_witness_vector_generator; pub mod house_keeper; +pub mod kzg; pub mod object_store; pub mod observability; pub mod proof_data_handler; diff --git a/core/lib/constants/src/contracts.rs b/core/lib/constants/src/contracts.rs index 9d167f7346a..cd071252bcf 100644 --- a/core/lib/constants/src/contracts.rs +++ b/core/lib/constants/src/contracts.rs @@ -83,6 +83,11 @@ pub const COMPLEX_UPGRADER_ADDRESS: Address = H160([ 0x00, 0x00, 0x80, 0x0f, ]); +pub const PUBDATA_CHUNK_PUBLISHER_ADDRESS: Address = H160([ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x11, +]); + /// The `ecrecover` system contract address. pub const ECRECOVER_PRECOMPILE_ADDRESS: Address = H160([ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, diff --git a/core/lib/constants/src/system_logs.rs b/core/lib/constants/src/system_logs.rs index 081670f0cb5..bd4167b3d02 100644 --- a/core/lib/constants/src/system_logs.rs +++ b/core/lib/constants/src/system_logs.rs @@ -3,3 +3,9 @@ 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 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; diff --git a/core/lib/env_config/src/kzg.rs b/core/lib/env_config/src/kzg.rs new file mode 100644 index 00000000000..d59a3806330 --- /dev/null +++ b/core/lib/env_config/src/kzg.rs @@ -0,0 +1,35 @@ +use zksync_config::configs::KzgConfig; + +use crate::{envy_load, FromEnv}; + +impl FromEnv for KzgConfig { + fn from_env() -> anyhow::Result { + envy_load("kzg", "KZG_") + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::test_utils::EnvMutex; + + static MUTEX: EnvMutex = EnvMutex::new(); + + fn expected_config() -> KzgConfig { + KzgConfig { + trusted_setup_path: "dir/file.json".to_owned(), + } + } + + #[test] + fn from_env() { + let mut lock = MUTEX.lock(); + let config = r#" + KZG_TRUSTED_SETUP_PATH="dir/file.json" + "#; + lock.set_env(config); + + let actual = KzgConfig::from_env().unwrap(); + assert_eq!(actual, expected_config()); + } +} diff --git a/core/lib/env_config/src/lib.rs b/core/lib/env_config/src/lib.rs index 973e2ff9ae5..55a1e21b509 100644 --- a/core/lib/env_config/src/lib.rs +++ b/core/lib/env_config/src/lib.rs @@ -17,6 +17,7 @@ mod fri_prover_group; mod fri_witness_generator; mod fri_witness_vector_generator; mod house_keeper; +mod kzg; pub mod object_store; mod observability; mod proof_data_handler; diff --git a/core/lib/l1_contract_interface/src/i_executor/commit/kzg.rs b/core/lib/l1_contract_interface/src/i_executor/commit/kzg.rs index 8ffd9c39599..f8e90dcece3 100644 --- a/core/lib/l1_contract_interface/src/i_executor/commit/kzg.rs +++ b/core/lib/l1_contract_interface/src/i_executor/commit/kzg.rs @@ -6,8 +6,9 @@ use std::convert::TryInto; use sha2::Sha256; use sha3::{Digest, Keccak256}; use zkevm_test_harness_1_3_3::ff::{PrimeField, PrimeFieldRepr}; +pub use zkevm_test_harness_1_4_1::kzg::KzgSettings; use zkevm_test_harness_1_4_1::{ - kzg::{compute_commitment, compute_proof, compute_proof_poly, KzgSettings}, + kzg::{compute_commitment, compute_proof, compute_proof_poly}, zkevm_circuits::{ boojum::pairing::{ bls12_381::{Fr, FrRepr, G1Affine}, @@ -20,6 +21,7 @@ use zkevm_test_harness_1_4_1::{ }, }, }; +use zksync_types::H256; const ZK_SYNC_BYTES_PER_BLOB: usize = BLOB_CHUNK_SIZE * ELEMENTS_PER_4844_BLOCK; const EIP_4844_BYTES_PER_BLOB: usize = 32 * ELEMENTS_PER_4844_BLOCK; @@ -102,6 +104,20 @@ impl KzgInfo { res } + pub fn to_blob_commitment(&self) -> [u8; 32] { + let mut commitment = [0u8; 32]; + let hash = &Keccak256::digest( + [ + self.versioned_hash.to_vec(), + self.opening_point[16..].to_vec(), + self.opening_value.to_vec(), + ] + .concat(), + ); + commitment.copy_from_slice(hash); + commitment + } + /// Deserializes `Self::SERIALIZED_SIZE` bytes into `KzgInfo` struct pub fn from_slice(data: &[u8]) -> Self { assert_eq!(data.len(), Self::SERIALIZED_SIZE); @@ -246,6 +262,28 @@ impl KzgInfo { } } +pub fn pubdata_to_blob_commitments(pubdata_input: &[u8], kzg_settings: &KzgSettings) -> [H256; 2] { + assert!( + pubdata_input.len() <= 2 * ZK_SYNC_BYTES_PER_BLOB, + "Pubdata length exceeds size of 2 blobs" + ); + + let blob_commitments = pubdata_input + .chunks(ZK_SYNC_BYTES_PER_BLOB) + .map(|blob| { + let kzg_info = KzgInfo::new(kzg_settings, blob.to_vec()); + H256(kzg_info.to_blob_commitment()) + }) + .collect::>(); + + // If length of `pubdata_input` is less than or equal to `ZK_SYNC_BYTES_PER_BLOB` (126976) + // then only one blob will be used and 32 zero bytes will be used as a commitment for the second blob. + [ + blob_commitments.get(0).copied().unwrap_or_default(), + blob_commitments.get(1).copied().unwrap_or_default(), + ] +} + #[cfg(test)] mod tests { use serde::{Deserialize, Serialize}; diff --git a/core/lib/l1_contract_interface/src/i_executor/commit/mod.rs b/core/lib/l1_contract_interface/src/i_executor/commit/mod.rs index e048c0e9fa4..d883d742e85 100644 --- a/core/lib/l1_contract_interface/src/i_executor/commit/mod.rs +++ b/core/lib/l1_contract_interface/src/i_executor/commit/mod.rs @@ -1 +1 @@ -mod kzg; +pub mod kzg; diff --git a/core/lib/l1_contract_interface/src/i_executor/mod.rs b/core/lib/l1_contract_interface/src/i_executor/mod.rs index 4b4a127a34b..5080cfed0a2 100644 --- a/core/lib/l1_contract_interface/src/i_executor/mod.rs +++ b/core/lib/l1_contract_interface/src/i_executor/mod.rs @@ -1,6 +1,5 @@ //! Different interfaces exposed by the `IExecutor.sol`. -mod commit; - +pub mod commit; pub mod methods; pub mod structures; diff --git a/core/lib/multivm/src/versions/vm_latest/tests/block_tip.rs b/core/lib/multivm/src/versions/vm_latest/tests/block_tip.rs index fc6a2f26d6e..962a6809475 100644 --- a/core/lib/multivm/src/versions/vm_latest/tests/block_tip.rs +++ b/core/lib/multivm/src/versions/vm_latest/tests/block_tip.rs @@ -9,8 +9,11 @@ use zksync_system_constants::{ CONTRACT_FORCE_DEPLOYER_ADDRESS, KNOWN_CODES_STORAGE_ADDRESS, L1_MESSENGER_ADDRESS, }; use zksync_types::{ - commitment::SerializeCommitment, get_code_key, l2_to_l1_log::L2ToL1Log, - writes::StateDiffRecord, Address, Execute, H256, U256, + commitment::SerializeCommitment, + get_code_key, + l2_to_l1_log::{l2_to_l1_logs_tree_size, L2ToL1Log}, + writes::StateDiffRecord, + Address, Execute, ProtocolVersionId, H256, U256, }; use zksync_utils::{bytecode::hash_bytecode, bytes_to_be_words, h256_to_u256, u256_to_h256}; @@ -209,7 +212,7 @@ fn test_dry_run_upper_bound() { // 4. Lots of storage slot updates. let max_logs = execute_test(L1MessengerTestData { - l2_to_l1_logs: L2ToL1Log::MIN_L2_L1_LOGS_TREE_SIZE, + l2_to_l1_logs: l2_to_l1_logs_tree_size(ProtocolVersionId::Version20), ..Default::default() }); diff --git a/core/lib/protobuf_config/src/kzg.rs b/core/lib/protobuf_config/src/kzg.rs new file mode 100644 index 00000000000..6446eac9aaf --- /dev/null +++ b/core/lib/protobuf_config/src/kzg.rs @@ -0,0 +1,22 @@ +use anyhow::Context as _; +use zksync_config::configs; +use zksync_protobuf::required; + +use crate::{proto, repr::ProtoRepr}; + +impl ProtoRepr for proto::Kzg { + type Type = configs::KzgConfig; + fn read(&self) -> anyhow::Result { + Ok(Self::Type { + trusted_setup_path: required(&self.trusted_setup_path) + .context("trusted_setup_path")? + .clone(), + }) + } + + fn build(this: &Self::Type) -> Self { + Self { + trusted_setup_path: Some(this.trusted_setup_path.clone()), + } + } +} diff --git a/core/lib/protobuf_config/src/lib.rs b/core/lib/protobuf_config/src/lib.rs index b0814b364a1..834fb6cbe8f 100644 --- a/core/lib/protobuf_config/src/lib.rs +++ b/core/lib/protobuf_config/src/lib.rs @@ -20,6 +20,7 @@ mod fri_prover_group; mod fri_witness_generator; mod fri_witness_vector_generator; mod house_keeper; +mod kzg; mod object_store; mod observability; mod proof_data_handler; diff --git a/core/lib/protobuf_config/src/proto/kzg.proto b/core/lib/protobuf_config/src/proto/kzg.proto new file mode 100644 index 00000000000..875cc0dda31 --- /dev/null +++ b/core/lib/protobuf_config/src/proto/kzg.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; + +package zksync.config; + +message Kzg { + optional string trusted_setup_path = 1; // required; fs path +} diff --git a/core/lib/types/src/commitment/mod.rs b/core/lib/types/src/commitment/mod.rs index a65faca0e50..6e096bd6195 100644 --- a/core/lib/types/src/commitment/mod.rs +++ b/core/lib/types/src/commitment/mod.rs @@ -12,14 +12,15 @@ use serde::{Deserialize, Serialize}; use zksync_contracts::BaseSystemContractsHashes; 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, + BLOB1_LINEAR_HASH_KEY, BLOB2_LINEAR_HASH_KEY, KNOWN_CODES_STORAGE_ADDRESS, + L2_TO_L1_LOGS_TREE_ROOT_KEY, PUBDATA_CHUNK_PUBLISHER_ADDRESS, STATE_DIFF_HASH_KEY, ZKPORTER_IS_AVAILABLE, }; use zksync_utils::u256_to_h256; use crate::{ block::{L1BatchHeader, L1BatchTreeData}, - l2_to_l1_log::{L2ToL1Log, SystemL2ToL1Log, UserL2ToL1Log}, + l2_to_l1_log::{l2_to_l1_logs_tree_size, L2ToL1Log, SystemL2ToL1Log, UserL2ToL1Log}, web3::signing::keccak256, writes::{ compress_state_diffs, InitialStorageWrite, RepeatedStorageWrite, StateDiffRecord, @@ -279,6 +280,8 @@ enum L1BatchAuxiliaryOutput { state_diffs_compressed: Vec, state_diffs_hash: H256, aux_commitments: AuxCommitments, + blob_linear_hashes: [H256; 2], + blob_commitments: [H256; 2], }, } @@ -298,7 +301,7 @@ impl L1BatchAuxiliaryOutput { .map(|chunk| <[u8; UserL2ToL1Log::SERIALIZED_SIZE]>::try_from(chunk).unwrap()); let l2_l1_logs_merkle_root = MiniMerkleTree::new( merkle_tree_leaves, - Some(L2ToL1Log::PRE_BOOJUM_MIN_L2_L1_LOGS_TREE_SIZE), + Some(l2_to_l1_logs_tree_size(common_input.protocol_version)), ) .merkle_root(); let l2_l1_logs_linear_hash = H256::from(keccak256(&l2_l1_logs_compressed)); @@ -327,20 +330,34 @@ impl L1BatchAuxiliaryOutput { system_logs, state_diffs, aux_commitments, + blob_commitments, } => { + // TODO (PLA-815): Remove `IGNORE_1_4_2_UPGRADE_FOR_UPGRADE_TEST`. + // This is used only in upgrade test, because our system isn't flexible enough right now to support WIP changes to contracts. + let protocol_version = + if std::env::var("IGNORE_1_4_2_UPGRADE_FOR_UPGRADE_TEST").is_ok() { + if common_input.protocol_version.is_post_1_4_2() { + ProtocolVersionId::Version20 + } else { + common_input.protocol_version + } + } else { + common_input.protocol_version + }; + 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( merkle_tree_leaves, - Some(L2ToL1Log::MIN_L2_L1_LOGS_TREE_SIZE), + Some(l2_to_l1_logs_tree_size(protocol_version)), ) .merkle_root(); let common_output = L1BatchAuxiliaryCommonOutput { l2_l1_logs_merkle_root, - protocol_version: common_input.protocol_version, + protocol_version, }; let system_logs_compressed = serialize_commitments(&system_logs); @@ -350,6 +367,31 @@ 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 = if protocol_version.is_post_1_4_2() { + let blob1_linear_hash = system_logs.iter().find_map(|log| { + (log.0.sender == PUBDATA_CHUNK_PUBLISHER_ADDRESS + && log.0.key == H256::from_low_u64_be(BLOB1_LINEAR_HASH_KEY as u64)) + .then_some(log.0.value) + }); + let blob2_linear_hash = system_logs.iter().find_map(|log| { + (log.0.sender == PUBDATA_CHUNK_PUBLISHER_ADDRESS + && log.0.key == H256::from_low_u64_be(BLOB2_LINEAR_HASH_KEY as u64)) + .then_some(log.0.value) + }); + match (&blob1_linear_hash, &blob2_linear_hash) { + (Some(_), None) | (None, Some(_)) => { + panic!("Only one blob hash was found in system logs") + } + _ => {} + } + [ + blob1_linear_hash.unwrap_or_else(H256::zero), + blob2_linear_hash.unwrap_or_else(H256::zero), + ] + } else { + [H256::zero(), H256::zero()] + }; + // 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 @@ -383,6 +425,8 @@ impl L1BatchAuxiliaryOutput { state_diffs_compressed, state_diffs_hash, aux_commitments, + blob_linear_hashes, + blob_commitments, } } } @@ -409,6 +453,8 @@ impl L1BatchAuxiliaryOutput { system_logs_linear_hash, state_diffs_hash, aux_commitments, + blob_linear_hashes, + blob_commitments, .. } => { result.extend(system_logs_linear_hash.as_bytes()); @@ -420,12 +466,17 @@ impl L1BatchAuxiliaryOutput { ); result.extend(aux_commitments.events_queue_commitment.as_bytes()); - if common.protocol_version.is_post_1_4_1() { - // For now, we are using zeroes as commitments to the KZG pubdata. + if common.protocol_version.is_1_4_1() { + // We are using zeroes as commitments to the KZG pubdata as per convention. result.extend(H256::zero().as_bytes()); result.extend(H256::zero().as_bytes()); result.extend(H256::zero().as_bytes()); result.extend(H256::zero().as_bytes()); + } else if common.protocol_version.is_post_1_4_2() { + result.extend(blob_linear_hashes[0].as_bytes()); + result.extend(blob_commitments[0].as_bytes()); + result.extend(blob_linear_hashes[1].as_bytes()); + result.extend(blob_commitments[1].as_bytes()); } } } @@ -643,6 +694,7 @@ pub enum CommitmentInput { system_logs: Vec, state_diffs: Vec, aux_commitments: AuxCommitments, + blob_commitments: [H256; 2], }, } @@ -683,6 +735,7 @@ impl CommitmentInput { events_queue_commitment: H256::zero(), bootloader_initial_content_commitment: H256::zero(), }, + blob_commitments: [H256::zero(), H256::zero()], } } } diff --git a/core/lib/types/src/commitment/tests/mod.rs b/core/lib/types/src/commitment/tests/mod.rs index 7fec231a31a..4a9253c3933 100644 --- a/core/lib/types/src/commitment/tests/mod.rs +++ b/core/lib/types/src/commitment/tests/mod.rs @@ -37,6 +37,11 @@ fn pre_boojum() { } #[test] -fn post_boojum() { - run_test("post_boojum_test"); +fn post_boojum_1_4_1() { + run_test("post_boojum_1_4_1_test"); +} + +#[test] +fn post_boojum_1_4_2() { + run_test("post_boojum_1_4_2_test"); } diff --git a/core/lib/types/src/commitment/tests/post_boojum_test.json b/core/lib/types/src/commitment/tests/post_boojum_1_4_1_test.json similarity index 97% rename from core/lib/types/src/commitment/tests/post_boojum_test.json rename to core/lib/types/src/commitment/tests/post_boojum_1_4_1_test.json index 2007829492c..224b7a6cfec 100644 --- a/core/lib/types/src/commitment/tests/post_boojum_test.json +++ b/core/lib/types/src/commitment/tests/post_boojum_1_4_1_test.json @@ -450,7 +450,8 @@ "aux_commitments": { "events_queue_commitment": "0x6193a5098eb140796387bdf40700a3855eeb010474b5478f30bf917172c67883", "bootloader_initial_content_commitment": "0xf031b4491c37f20516c4ebf428f4765156409f67089e64772f4106fd2d9f3351" - } + }, + "blob_commitments": ["0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000"] } }, "pass_through_data": { @@ -816,7 +817,9 @@ "aux_commitments": { "events_queue_commitment": "0x6193a5098eb140796387bdf40700a3855eeb010474b5478f30bf917172c67883", "bootloader_initial_content_commitment": "0xf031b4491c37f20516c4ebf428f4765156409f67089e64772f4106fd2d9f3351" - } + }, + "blob_linear_hashes": ["0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000"], + "blob_commitments": ["0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000"] } }, "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 new file mode 100644 index 00000000000..c72224bd63c --- /dev/null +++ b/core/lib/types/src/commitment/tests/post_boojum_1_4_2_test.json @@ -0,0 +1,847 @@ +{ + "input": { + "PostBoojum": { + "common": { + "l2_to_l1_logs": [ + { + "shard_id": 0, + "is_service": true, + "tx_number_in_block": 0, + "sender": "0x0000000000000000000000000000000000008001", + "key": "0x7814f203b8e02f6a676b8f7faefcf732d8b4368bab25239ea4525010aa85d5ee", + "value": "0x0000000000000000000000000000000000000000000000000000000000000001" + } + ], + "rollup_last_leaf_index": 89, + "rollup_root_hash": "0xe47f013d1ecd4ce53b6872f6b762670b393815e7ddacdf2b0886af9c7f3a555b", + "bootloader_code_hash": "0x010007ed0e328b940e241f7666a6303b7ffd4e3fd7e8c154d6e7556befe6cd6d", + "default_aa_code_hash": "0x0100055b7a8be90522251be8be1a186464d056462973502ac8a0437c85e4d2a9", + "protocol_version": "Version21" + }, + "system_logs": [ + { + "shard_id": 0, + "is_service": false, + "tx_number_in_block": 0, + "sender": "0x000000000000000000000000000000000000800b", + "key": "0x0000000000000000000000000000000000000000000000000000000000000004", + "value": "0x55618db5ff24aee4d236921b6f4272101161137115a3b4c4a65f8677b124c01c" + }, + { + "shard_id": 0, + "is_service": false, + "tx_number_in_block": 1, + "sender": "0x000000000000000000000000000000000000800b", + "key": "0x0000000000000000000000000000000000000000000000000000000000000003", + "value": "0x00000000000000000000000065c22f8000000000000000000000000065c22f81" + }, + { + "shard_id": 0, + "is_service": true, + "tx_number_in_block": 1, + "sender": "0x0000000000000000000000000000000000008001", + "key": "0x0000000000000000000000000000000000000000000000000000000000000005", + "value": "0x155c82febe94e07df0065c153e8ed403b5351fd64d657c8dffbfbee8ec3d2ba3" + }, + { + "shard_id": 0, + "is_service": true, + "tx_number_in_block": 1, + "sender": "0x0000000000000000000000000000000000008001", + "key": "0x0000000000000000000000000000000000000000000000000000000000000006", + "value": "0x0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "shard_id": 0, + "is_service": true, + "tx_number_in_block": 1, + "sender": "0x0000000000000000000000000000000000008008", + "key": "0x0000000000000000000000000000000000000000000000000000000000000000", + "value": "0x0b6e1ad4643cc2bee06b5e173184ec822d80826e5720f5715172898350433299" + }, + { + "shard_id": 0, + "is_service": true, + "tx_number_in_block": 1, + "sender": "0x0000000000000000000000000000000000008008", + "key": "0x0000000000000000000000000000000000000000000000000000000000000001", + "value": "0x85a7fb853512ba6575c99ee121dd560559523a4587a2cd7e83cd359cd9ea2aed" + }, + { + "shard_id": 0, + "is_service": true, + "tx_number_in_block": 1, + "sender": "0x0000000000000000000000000000000000008008", + "key": "0x0000000000000000000000000000000000000000000000000000000000000002", + "value": "0xb18f72a4a5b4b8ce1b7e41095fb1332a211a140376bcc2607910875d236708e0" + }, + { + "shard_id": 0, + "is_service": true, + "tx_number_in_block": 1, + "sender": "0x0000000000000000000000000000000000008011", + "key": "0x0000000000000000000000000000000000000000000000000000000000000007", + "value": "0x0000000000000000000000000000000000000000000000000000000000000003" + }, + { + "shard_id": 0, + "is_service": true, + "tx_number_in_block": 1, + "sender": "0x0000000000000000000000000000000000008011", + "key": "0x0000000000000000000000000000000000000000000000000000000000000008", + "value": "0x0000000000000000000000000000000000000000000000000000000000000004" + } + ], + "state_diffs": [ + { + "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": 49, + "initial_value": "0x18776f28c303800", + "final_value": "0x708da482cab20760" + }, + { + "address": "0x000000000000000000000000000000000000800a", + "key": "0x294a00337abeee2b3cd948ffeed92231e2a3acc2eb11210400e0aa9557f23e26", + "derived_key": [ + 45, + 90, + 105, + 98, + 204, + 206, + 229, + 212, + 173, + 180, + 138, + 54, + 187, + 191, + 68, + 58, + 83, + 23, + 33, + 72, + 67, + 129, + 18, + 89, + 55, + 243, + 0, + 26, + 197, + 255, + 135, + 91 + ], + "enumeration_index": 50, + "initial_value": "0xf5559e28fd66c0", + "final_value": "0xf5a19b324caf80" + }, + { + "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": "0x6f05e193353286a0" + }, + { + "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": 53, + "initial_value": "0x100000000000000000000000065c22e3e", + "final_value": "0x200000000000000000000000065c22f80" + }, + { + "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": 54, + "initial_value": "0x200000000000000000000000065c22e3f", + "final_value": "0x400000000000000000000000065c22f81" + }, + { + "address": "0x000000000000000000000000000000000000800b", + "key": "0xd", + "derived_key": [ + 235, + 221, + 239, + 221, + 164, + 142, + 178, + 170, + 127, + 102, + 236, + 247, + 148, + 10, + 40, + 14, + 158, + 243, + 251, + 46, + 149, + 219, + 9, + 149, + 83, + 132, + 64, + 166, + 42, + 247, + 152, + 97 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0xebbe609cd3ccd11f273eb94374d6d3a2f7856c5f1039dc4877c6a334188ac7c1" + }, + { + "address": "0x000000000000000000000000000000000000800b", + "key": "0xe", + "derived_key": [ + 70, + 64, + 215, + 56, + 69, + 54, + 78, + 198, + 145, + 246, + 222, + 251, + 96, + 106, + 58, + 114, + 253, + 165, + 215, + 173, + 51, + 209, + 125, + 4, + 153, + 90, + 142, + 37, + 44, + 74, + 6, + 216 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x708e7fcf68ebab6c87322686cac4bcdb5f2bd4c71f337b18d147fd9a6c44ad13" + }, + { + "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": 57, + "initial_value": "0x200000000000000000000000065c22e3f", + "final_value": "0x400000000000000000000000065c22f81" + }, + { + "address": "0x000000000000000000000000000000000000800b", + "key": "0xad67d757c34507f157cacfa2e3153e9f260a2244f30428821be7be64587ac55f", + "derived_key": [ + 12, + 194, + 74, + 180, + 47, + 190, + 197, + 49, + 125, + 155, + 26, + 44, + 164, + 124, + 169, + 185, + 59, + 158, + 195, + 109, + 121, + 142, + 253, + 124, + 218, + 167, + 57, + 36, + 22, + 48, + 203, + 70 + ], + "enumeration_index": 0, + "initial_value": "0x0", + "final_value": "0x55618db5ff24aee4d236921b6f4272101161137115a3b4c4a65f8677b124c01c" + } + ], + "aux_commitments": { + "events_queue_commitment": "0x6193a5098eb140796387bdf40700a3855eeb010474b5478f30bf917172c67883", + "bootloader_initial_content_commitment": "0xf031b4491c37f20516c4ebf428f4765156409f67089e64772f4106fd2d9f3351" + }, + "blob_commitments": ["0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000002"] + } + }, + "pass_through_data": { + "shared_states": [ + { + "last_leaf_index": 89, + "root_hash": "0xe47f013d1ecd4ce53b6872f6b762670b393815e7ddacdf2b0886af9c7f3a555b" + }, + { + "last_leaf_index": 0, + "root_hash": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + ] + }, + "meta_parameters": { + "zkporter_is_available": false, + "bootloader_code_hash": "0x010007ed0e328b940e241f7666a6303b7ffd4e3fd7e8c154d6e7556befe6cd6d", + "default_aa_code_hash": "0x0100055b7a8be90522251be8be1a186464d056462973502ac8a0437c85e4d2a9" + }, + "auxiliary_output": { + "PostBoojum": { + "common": { + "l2_l1_logs_merkle_root": "0x0b6e1ad4643cc2bee06b5e173184ec822d80826e5720f5715172898350433299", + "protocol_version": "Version21" + }, + "system_logs_linear_hash": "0xc559d154f69af74a0017e2380afa3a861822cf47bc5b99e3a76f7fc4de6cca09", + "state_diffs_compressed": [ + 1, + 0, + 1, + 72, + 4, + 0, + 4, + 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, + 111, + 5, + 225, + 147, + 53, + 50, + 134, + 160, + 235, + 221, + 239, + 221, + 164, + 142, + 178, + 170, + 127, + 102, + 236, + 247, + 148, + 10, + 40, + 14, + 158, + 243, + 251, + 46, + 149, + 219, + 9, + 149, + 83, + 132, + 64, + 166, + 42, + 247, + 152, + 97, + 0, + 235, + 190, + 96, + 156, + 211, + 204, + 209, + 31, + 39, + 62, + 185, + 67, + 116, + 214, + 211, + 162, + 247, + 133, + 108, + 95, + 16, + 57, + 220, + 72, + 119, + 198, + 163, + 52, + 24, + 138, + 199, + 193, + 70, + 64, + 215, + 56, + 69, + 54, + 78, + 198, + 145, + 246, + 222, + 251, + 96, + 106, + 58, + 114, + 253, + 165, + 215, + 173, + 51, + 209, + 125, + 4, + 153, + 90, + 142, + 37, + 44, + 74, + 6, + 216, + 0, + 112, + 142, + 127, + 207, + 104, + 235, + 171, + 108, + 135, + 50, + 38, + 134, + 202, + 196, + 188, + 219, + 95, + 43, + 212, + 199, + 31, + 51, + 123, + 24, + 209, + 71, + 253, + 154, + 108, + 68, + 173, + 19, + 12, + 194, + 74, + 180, + 47, + 190, + 197, + 49, + 125, + 155, + 26, + 44, + 164, + 124, + 169, + 185, + 59, + 158, + 195, + 109, + 121, + 142, + 253, + 124, + 218, + 167, + 57, + 36, + 22, + 48, + 203, + 70, + 0, + 85, + 97, + 141, + 181, + 255, + 36, + 174, + 228, + 210, + 54, + 146, + 27, + 111, + 66, + 114, + 16, + 17, + 97, + 19, + 113, + 21, + 163, + 180, + 196, + 166, + 95, + 134, + 119, + 177, + 36, + 192, + 28, + 0, + 0, + 0, + 49, + 65, + 111, + 6, + 45, + 144, + 62, + 129, + 207, + 96, + 0, + 0, + 0, + 50, + 49, + 75, + 253, + 9, + 79, + 72, + 192, + 0, + 0, + 0, + 53, + 137, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 66, + 0, + 0, + 0, + 54, + 137, + 2, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 66, + 0, + 0, + 0, + 57, + 137, + 2, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 66 + ], + "state_diffs_hash": "0xb18f72a4a5b4b8ce1b7e41095fb1332a211a140376bcc2607910875d236708e0", + "aux_commitments": { + "events_queue_commitment": "0x6193a5098eb140796387bdf40700a3855eeb010474b5478f30bf917172c67883", + "bootloader_initial_content_commitment": "0xf031b4491c37f20516c4ebf428f4765156409f67089e64772f4106fd2d9f3351" + }, + "blob_linear_hashes": ["0x0000000000000000000000000000000000000000000000000000000000000003", "0x0000000000000000000000000000000000000000000000000000000000000004"], + "blob_commitments": ["0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000002"] + } + }, + "hashes": { + "pass_through_data": "0x6a3ffc0f55d4abce9498b8bcb01a3018bc2b83d96acb27e23772fe9347954725", + "aux_output": "0xa6410b9d726740cc0e3309565816ed7a929fb2ad7ab69b46cde006e7ea60dd5b", + "meta_parameters": "0x3fec00ec17ecaff24bbbcbc15850ca3528ce1c287d3a35fee97a6c65655866c1", + "commitment": "0x3b2e443dd853fb0c15c5956db1deb2527661c2b2b64011ab345120c620bc5faa" + } +} diff --git a/core/lib/types/src/l2_to_l1_log.rs b/core/lib/types/src/l2_to_l1_log.rs index 434e17e8bb2..32cc6b517d2 100644 --- a/core/lib/types/src/l2_to_l1_log.rs +++ b/core/lib/types/src/l2_to_l1_log.rs @@ -1,6 +1,6 @@ use serde::{Deserialize, Serialize}; -use crate::{commitment::SerializeCommitment, Address, H256}; +use crate::{commitment::SerializeCommitment, Address, ProtocolVersionId, H256}; #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default, Eq)] pub struct L2ToL1Log { @@ -24,14 +24,6 @@ pub struct UserL2ToL1Log(pub L2ToL1Log); pub struct SystemL2ToL1Log(pub L2ToL1Log); impl L2ToL1Log { - /// Determines the minimum number of items in the Merkle tree built from L2-to-L1 logs - /// for a certain batch. - pub const MIN_L2_L1_LOGS_TREE_SIZE: usize = 2048; - - /// Determines the minimum number of items in the Merkle tree built from L2-to-L1 logs - /// for a pre-boojum batch. - pub const PRE_BOOJUM_MIN_L2_L1_LOGS_TREE_SIZE: usize = 512; - pub fn from_slice(data: &[u8]) -> Self { assert_eq!(data.len(), Self::SERIALIZED_SIZE); Self { @@ -63,6 +55,22 @@ impl L2ToL1Log { } } +/// Returns the number of items in the Merkle tree built from L2-to-L1 logs +/// for a certain protocol version. +pub fn l2_to_l1_logs_tree_size(protocol_version: ProtocolVersionId) -> usize { + pub const PRE_BOOJUM_L2_L1_LOGS_TREE_SIZE: usize = 512; + pub const VM_1_4_0_L2_L1_LOGS_TREE_SIZE: usize = 2048; + pub const VM_1_4_2_L2_L1_LOGS_TREE_SIZE: usize = 4096; + + if protocol_version.is_pre_boojum() { + PRE_BOOJUM_L2_L1_LOGS_TREE_SIZE + } else if protocol_version.is_1_4_0() || protocol_version.is_1_4_1() { + VM_1_4_0_L2_L1_LOGS_TREE_SIZE + } else { + VM_1_4_2_L2_L1_LOGS_TREE_SIZE + } +} + #[cfg(test)] mod tests { use zksync_basic_types::U256; diff --git a/core/lib/types/src/protocol_version.rs b/core/lib/types/src/protocol_version.rs index 5d8b982aef5..d2b49746b2e 100644 --- a/core/lib/types/src/protocol_version.rs +++ b/core/lib/types/src/protocol_version.rs @@ -103,9 +103,17 @@ impl ProtocolVersionId { self >= &ProtocolVersionId::Version18 && self < &ProtocolVersionId::Version20 } + pub fn is_1_4_1(&self) -> bool { + self == &ProtocolVersionId::Version20 + } + pub fn is_post_1_4_1(&self) -> bool { self >= &ProtocolVersionId::Version20 } + + pub fn is_post_1_4_2(&self) -> bool { + self >= &ProtocolVersionId::Version21 + } } impl Default for ProtocolVersionId { diff --git a/core/lib/zksync_core/src/api_server/web3/namespaces/zks.rs b/core/lib/zksync_core/src/api_server/web3/namespaces/zks.rs index 6bef4b5e234..231c8c6e0bd 100644 --- a/core/lib/zksync_core/src/api_server/web3/namespaces/zks.rs +++ b/core/lib/zksync_core/src/api_server/web3/namespaces/zks.rs @@ -12,12 +12,12 @@ use zksync_types::{ fee_model::FeeParams, l1::L1Tx, l2::L2Tx, - l2_to_l1_log::L2ToL1Log, + l2_to_l1_log::{l2_to_l1_logs_tree_size, L2ToL1Log}, tokens::ETHEREUM_ADDRESS, transaction_request::CallRequest, utils::storage_key_for_standard_token_balance, - AccountTreeId, L1BatchNumber, MiniblockNumber, StorageKey, Transaction, L1_MESSENGER_ADDRESS, - L2_ETH_TOKEN_ADDRESS, REQUIRED_L1_TO_L2_GAS_PER_PUBDATA_BYTE, U256, U64, + AccountTreeId, L1BatchNumber, MiniblockNumber, ProtocolVersionId, StorageKey, Transaction, + L1_MESSENGER_ADDRESS, L2_ETH_TOKEN_ADDRESS, REQUIRED_L1_TO_L2_GAS_PER_PUBDATA_BYTE, U256, U64, }; use zksync_utils::{address_to_h256, h256_to_u256}; use zksync_web3_decl::{ @@ -334,17 +334,12 @@ impl ZksNamespace { let merkle_tree_leaves = all_l1_logs_in_batch.iter().map(L2ToL1Log::to_bytes); - let min_tree_size = if batch + let protocol_version = batch .protocol_version - .map(|v| v.is_pre_boojum()) - .unwrap_or(true) - { - Some(L2ToL1Log::PRE_BOOJUM_MIN_L2_L1_LOGS_TREE_SIZE) - } else { - Some(L2ToL1Log::MIN_L2_L1_LOGS_TREE_SIZE) - }; + .unwrap_or_else(ProtocolVersionId::last_potentially_undefined); + let tree_size = l2_to_l1_logs_tree_size(protocol_version); - let (root, proof) = MiniMerkleTree::new(merkle_tree_leaves, min_tree_size) + let (root, proof) = MiniMerkleTree::new(merkle_tree_leaves, Some(tree_size)) .merkle_root_and_path(l1_log_index); Ok(Some(L2ToL1LogProof { proof, diff --git a/core/lib/zksync_core/src/commitment_generator/mod.rs b/core/lib/zksync_core/src/commitment_generator/mod.rs index 3e868000317..e9a44d818c7 100644 --- a/core/lib/zksync_core/src/commitment_generator/mod.rs +++ b/core/lib/zksync_core/src/commitment_generator/mod.rs @@ -8,6 +8,9 @@ use tokio::{sync::watch, task::JoinHandle}; use zksync_commitment_utils::{bootloader_initial_content_commitment, events_queue_commitment}; use zksync_dal::ConnectionPool; use zksync_health_check::{Health, HealthStatus, HealthUpdater, ReactiveHealthCheck}; +use zksync_l1_contract_interface::i_executor::commit::kzg::{ + pubdata_to_blob_commitments, KzgSettings, +}; use zksync_types::{ commitment::{AuxCommitments, CommitmentCommonInput, CommitmentInput, L1BatchCommitment}, writes::{InitialStorageWrite, RepeatedStorageWrite, StateDiffRecord}, @@ -23,13 +26,15 @@ const SLEEP_INTERVAL: Duration = Duration::from_millis(100); pub struct CommitmentGenerator { connection_pool: ConnectionPool, health_updater: HealthUpdater, + kzg_settings: KzgSettings, } impl CommitmentGenerator { - pub fn new(connection_pool: ConnectionPool) -> Self { + pub fn new(connection_pool: ConnectionPool, kzg_trusted_setup_path: &str) -> Self { Self { connection_pool, health_updater: ReactiveHealthCheck::new("commitment_generator").1, + kzg_settings: KzgSettings::new(kzg_trusted_setup_path), } } @@ -50,12 +55,14 @@ impl CommitmentGenerator { .blocks_dal() .get_events_queue(l1_batch_number) .await? - .context("Events queue is required for post-boojum batch")?; + .with_context(|| format!("Events queue is missing for L1 batch #{l1_batch_number}"))?; let initial_bootloader_contents = connection .blocks_dal() .get_initial_bootloader_heap(l1_batch_number) .await? - .context("Bootloader initial heap is missing")?; + .with_context(|| { + format!("Bootloader initial heap is missing for L1 batch #{l1_batch_number}") + })?; drop(connection); let events_commitment_task: JoinHandle> = @@ -82,12 +89,15 @@ impl CommitmentGenerator { Ok(bootloader_initial_content_commitment) }); - let events_queue_commitment = events_commitment_task - .await - .context("`events_commitment_task` failed")??; - let bootloader_initial_content_commitment = bootloader_memory_commitment_task - .await - .context("`bootloader_memory_commitment_task` failed")??; + let events_queue_commitment = events_commitment_task.await.with_context(|| { + format!("`events_commitment_task` failed for L1 batch #{l1_batch_number}") + })??; + let bootloader_initial_content_commitment = + bootloader_memory_commitment_task.await.with_context(|| { + format!( + "`bootloader_memory_commitment_task` failed for L1 batch #{l1_batch_number}" + ) + })??; Ok(AuxCommitments { events_queue_commitment, @@ -107,12 +117,12 @@ impl CommitmentGenerator { .blocks_dal() .get_l1_batch_header(l1_batch_number) .await? - .context("header is missing for batch")?; + .with_context(|| format!("header is missing for L1 batch #{l1_batch_number}"))?; let tree_data = connection .blocks_dal() .get_l1_batch_tree_data(l1_batch_number) .await? - .context("tree data is missing for batch")?; + .with_context(|| format!("`tree_data` is missing for L1 batch #{l1_batch_number}"))?; // TODO(PLA-731): ensure that the protocol version is always available. let protocol_version = header @@ -210,11 +220,22 @@ 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 pubdata_input = header.pubdata_input.with_context(|| { + format!("`pubdata_input` is missing for L1 batch #{l1_batch_number}") + })?; + + pubdata_to_blob_commitments(&pubdata_input, &self.kzg_settings) + } else { + [H256::zero(), H256::zero()] + }; + CommitmentInput::PostBoojum { common, system_logs: header.system_logs, state_diffs, aux_commitments, + blob_commitments, } }; diff --git a/core/lib/zksync_core/src/lib.rs b/core/lib/zksync_core/src/lib.rs index 61c66d527a8..4f3c9d7faf8 100644 --- a/core/lib/zksync_core/src/lib.rs +++ b/core/lib/zksync_core/src/lib.rs @@ -742,11 +742,13 @@ pub async fn initialize_components( } if components.contains(&Component::CommitmentGenerator) { + let kzg_config = configs.kzg_config.clone().context("kzg_config")?; let commitment_generator_pool = ConnectionPool::singleton(postgres_config.master_url()?) .build() .await .context("failed to build commitment_generator_pool")?; - let commitment_generator = CommitmentGenerator::new(commitment_generator_pool); + let commitment_generator = + CommitmentGenerator::new(commitment_generator_pool, &kzg_config.trusted_setup_path); app_health.insert_component(commitment_generator.health_check()); task_futures.push(tokio::spawn( commitment_generator.run(stop_receiver.clone()), diff --git a/core/lib/zksync_core/src/temp_config_store.rs b/core/lib/zksync_core/src/temp_config_store.rs index d50460a0924..010170594e3 100644 --- a/core/lib/zksync_core/src/temp_config_store.rs +++ b/core/lib/zksync_core/src/temp_config_store.rs @@ -7,8 +7,8 @@ use zksync_config::{ }, fri_prover_group::FriProverGroupConfig, house_keeper::HouseKeeperConfig, - FriProofCompressorConfig, FriProverConfig, FriWitnessGeneratorConfig, PrometheusConfig, - ProofDataHandlerConfig, WitnessGeneratorConfig, + FriProofCompressorConfig, FriProverConfig, FriWitnessGeneratorConfig, KzgConfig, + PrometheusConfig, ProofDataHandlerConfig, WitnessGeneratorConfig, }, ApiConfig, ContractsConfig, DBConfig, ETHClientConfig, ETHSenderConfig, ETHWatchConfig, GasAdjusterConfig, ObjectStoreConfig, PostgresConfig, @@ -46,5 +46,6 @@ pub struct TempConfigStore { pub eth_watch_config: Option, pub gas_adjuster_config: Option, pub object_store_config: Option, + pub kzg_config: Option, pub consensus_config: Option, } diff --git a/core/tests/upgrade-test/tests/upgrade.test.ts b/core/tests/upgrade-test/tests/upgrade.test.ts index aa6b4e74e0d..258964df733 100644 --- a/core/tests/upgrade-test/tests/upgrade.test.ts +++ b/core/tests/upgrade-test/tests/upgrade.test.ts @@ -65,8 +65,9 @@ describe('Upgrade test', function () { // Must be > 1s, because bootloader requires l1 batch timestamps to be incremental. process.env.CHAIN_STATE_KEEPER_BLOCK_COMMIT_DEADLINE_MS = '2000'; // Run server in background. + // TODO (PLA-815): Remove `IGNORE_1_4_2_UPGRADE_FOR_UPGRADE_TEST=true` utils.background( - 'cd $ZKSYNC_HOME && cargo run --bin zksync_server --release -- --components=api,tree,eth,state_keeper,commitment_generator', + 'cd $ZKSYNC_HOME && IGNORE_1_4_2_UPGRADE_FOR_UPGRADE_TEST=true cargo run --bin zksync_server --release -- --components=api,tree,eth,state_keeper,commitment_generator', [null, logs, logs] ); // Server may need some time to recompile if it's a cold run, so wait for it. @@ -256,8 +257,9 @@ describe('Upgrade test', function () { await utils.sleep(10); // Run again. + // TODO (PLA-815): Remove `IGNORE_1_4_2_UPGRADE_FOR_UPGRADE_TEST=true` utils.background( - 'cd $ZKSYNC_HOME && cargo run --bin zksync_server --release -- --components=api,tree,eth,state_keeper,commitment_generator &> upgrade.log', + 'cd $ZKSYNC_HOME && IGNORE_1_4_2_UPGRADE_FOR_UPGRADE_TEST=true cargo run --bin zksync_server --release -- --components=api,tree,eth,state_keeper,commitment_generator &> upgrade.log', [null, logs, logs] ); await utils.sleep(10); diff --git a/docker/external-node/Dockerfile b/docker/external-node/Dockerfile index 02dca4cd50c..6743ae2cff0 100644 --- a/docker/external-node/Dockerfile +++ b/docker/external-node/Dockerfile @@ -25,6 +25,7 @@ COPY etc/tokens/ /etc/tokens/ COPY etc/ERC20/ /etc/ERC20/ COPY etc/multivm_bootloaders/ /etc/multivm_bootloaders/ COPY core/lib/dal/migrations/ /migrations +COPY trusted_setup.json / RUN chmod +x /usr/bin/entrypoint.sh diff --git a/docker/server-v2/Dockerfile b/docker/server-v2/Dockerfile index e5d378c3b6d..39434076278 100644 --- a/docker/server-v2/Dockerfile +++ b/docker/server-v2/Dockerfile @@ -29,5 +29,6 @@ COPY contracts/l2-contracts/artifacts-zk/ /contracts/l2-contracts/artifacts-zk/ COPY etc/tokens/ /etc/tokens/ COPY etc/ERC20/ /etc/ERC20/ COPY etc/multivm_bootloaders/ /etc/multivm_bootloaders/ +COPY trusted_setup.json / ENTRYPOINT ["zksync_server"] diff --git a/etc/env/base/kzg.toml b/etc/env/base/kzg.toml new file mode 100644 index 00000000000..365c71dbc0f --- /dev/null +++ b/etc/env/base/kzg.toml @@ -0,0 +1,2 @@ +[kzg] +trusted_setup_path="./trusted_setup.json" diff --git a/etc/env/dev.toml b/etc/env/dev.toml index e95ad7b9e9e..1c31b2f2580 100644 --- a/etc/env/dev.toml +++ b/etc/env/dev.toml @@ -16,6 +16,7 @@ base = [ 'base/private.toml', 'base/witness_generator.toml', 'base/house_keeper.toml', + 'base/kzg.toml', 'base/fri_prover.toml', 'base/fri_witness_generator.toml', 'base/fri_prover_group.toml',