From b4ffcd237ee594fc659ccfa96668868f5a87d5e3 Mon Sep 17 00:00:00 2001 From: Vladislav Volosnikov Date: Fri, 16 Aug 2024 13:49:36 +0200 Subject: [PATCH] feat(prover): parallelized memory queues simulation in BWG (#2652) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## What ❔ The updated logic of memory queue simulation in the test_harness requires changing the structure of the BWG artifacts. When processing memory queues for ram permutation circuit, part of the witness is sent to storage separately. For this reason, a new type of circuit wrapper has been added - partial base circuit. Also added logic required to transform a partial base layer circuit into a full one (merging structures) for WVG and proving. These changes can significantly reduce peak RAM usage in BWG, while speeding up the slowest part of the witness generation process. ## 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`. --- Cargo.lock | 56 ++++---- Cargo.toml | 6 +- core/lib/object_store/src/file.rs | 1 + core/lib/object_store/src/raw.rs | 2 + prover/Cargo.lock | 100 ++++++------- prover/Cargo.toml | 10 +- .../prover_cli/src/commands/get_file_info.rs | 2 +- .../src/gpu_prover_job_processor.rs | 2 + .../prover_fri/src/prover_job_processor.rs | 1 + prover/crates/bin/prover_fri/src/utils.rs | 1 + .../witness_generator/src/basic_circuits.rs | 135 +++++++++++++++--- .../crates/bin/witness_generator/src/utils.rs | 55 +++++-- .../witness_vector_generator/src/generator.rs | 3 + .../crates/lib/prover_fri_types/src/keys.rs | 8 ++ prover/crates/lib/prover_fri_types/src/lib.rs | 32 +++++ prover/crates/lib/prover_fri_utils/src/lib.rs | 60 +++++++- 16 files changed, 349 insertions(+), 125 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b65826900d4..a8ecbd7636d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1045,14 +1045,14 @@ dependencies = [ [[package]] name = "circuit_encodings" -version = "0.150.2" +version = "0.150.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ba840a74f8d0b8b1334e93e4c87514a27c9be83d42d9f78d0c577572bb5f435" +checksum = "2593c02ad6b4b31ba63506c3f807f666133dd36bf47422f99b1d2947cf3c8dc1" dependencies = [ "derivative", "serde", - "zk_evm 0.150.0", - "zkevm_circuits 0.150.3", + "zk_evm 0.150.4", + "zkevm_circuits 0.150.4", ] [[package]] @@ -1112,12 +1112,12 @@ dependencies = [ [[package]] name = "circuit_sequencer_api" -version = "0.150.2" +version = "0.150.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79f3177b2bcd4ef5da9d2ca6916f6de31fb1973dfece27907a8dc7c69233494d" +checksum = "42d1a86b9c2207f3bb2dff5f00d1af1cb95004b6d07e9bacb6519fe08f12c04b" dependencies = [ "bellman_ce", - "circuit_encodings 0.150.2", + "circuit_encodings 0.150.4", "derivative", "rayon", "serde", @@ -7296,8 +7296,8 @@ source = "git+https://github.com/matter-labs/vm2.git?rev=9a38900d7af9b1d72b47ce3 dependencies = [ "enum_dispatch", "primitive-types", - "zk_evm_abstractions 0.150.0", - "zkevm_opcode_defs 0.150.0", + "zk_evm_abstractions 0.150.4", + "zkevm_opcode_defs 0.150.4", ] [[package]] @@ -7873,9 +7873,9 @@ dependencies = [ [[package]] name = "zk_evm" -version = "0.150.0" +version = "0.150.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5bf91304aa14827758afa3def8cf622f9a7f9fb65fe5d5099018dbacf0c5984" +checksum = "e2dbb0ed38d61fbd04bd7575755924d1303e129c04c909abba7f5bfcc6260bcf" dependencies = [ "anyhow", "lazy_static", @@ -7883,7 +7883,7 @@ dependencies = [ "serde", "serde_json", "static_assertions", - "zk_evm_abstractions 0.150.0", + "zk_evm_abstractions 0.150.4", ] [[package]] @@ -7914,15 +7914,15 @@ dependencies = [ [[package]] name = "zk_evm_abstractions" -version = "0.150.0" +version = "0.150.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc313cea4ac9ef6b855264b1425cbe9de30dd8f009559dabcb6b2896122da5db" +checksum = "31460aacfe65b39ac484a2a2e0bbb02baf141f65264bf48e1e4f59ab375fe933" dependencies = [ "anyhow", "num_enum 0.6.1", "serde", "static_assertions", - "zkevm_opcode_defs 0.150.0", + "zkevm_opcode_defs 0.150.4", ] [[package]] @@ -7971,9 +7971,9 @@ dependencies = [ [[package]] name = "zkevm_circuits" -version = "0.150.3" +version = "0.150.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2d64bda28dec766324d2e5095a46fb141540d86a232106760dfb20ab4ae6e5c" +checksum = "abdfaa95dfe0878fda219dd17a6cc8c28711e2067785910c0e06d3ffdca78629" dependencies = [ "arrayvec 0.7.4", "boojum", @@ -7986,7 +7986,7 @@ dependencies = [ "seq-macro", "serde", "smallvec", - "zkevm_opcode_defs 0.150.0", + "zkevm_opcode_defs 0.150.4", ] [[package]] @@ -8033,9 +8033,9 @@ dependencies = [ [[package]] name = "zkevm_opcode_defs" -version = "0.150.0" +version = "0.150.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3328c012d444bdbfadb754a72c01a56879eb66584efc71eac457e89e7843608" +checksum = "bb7c5c7b4481a646f8696b08cee64a8dec097509a6378d18242f81022f327f1e" dependencies = [ "bitflags 2.6.0", "blake2 0.10.6", @@ -8129,7 +8129,7 @@ dependencies = [ "anyhow", "circuit_sequencer_api 0.140.0", "circuit_sequencer_api 0.141.1", - "circuit_sequencer_api 0.150.2", + "circuit_sequencer_api 0.150.4", "futures 0.3.28", "itertools 0.10.5", "num_cpus", @@ -8140,7 +8140,7 @@ dependencies = [ "vise", "zk_evm 0.133.0", "zk_evm 0.141.0", - "zk_evm 0.150.0", + "zk_evm 0.150.4", "zksync_contracts", "zksync_dal", "zksync_eth_client", @@ -8799,9 +8799,9 @@ dependencies = [ [[package]] name = "zksync_kzg" -version = "0.150.2" +version = "0.150.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b76d0e08b3e0970565f7a9a611278547f4f1dbd6184a250c8c5e743aed61c525" +checksum = "9949f48ea1a9f9a0e73242d4d1e87e681095181827486b3fcc2cf93e5aa03280" dependencies = [ "boojum", "derivative", @@ -8811,7 +8811,7 @@ dependencies = [ "serde", "serde_json", "serde_with", - "zkevm_circuits 0.150.3", + "zkevm_circuits 0.150.4", ] [[package]] @@ -8934,7 +8934,7 @@ dependencies = [ "circuit_sequencer_api 0.140.0", "circuit_sequencer_api 0.141.1", "circuit_sequencer_api 0.142.0", - "circuit_sequencer_api 0.150.2", + "circuit_sequencer_api 0.150.4", "ethabi", "hex", "itertools 0.10.5", @@ -8949,7 +8949,7 @@ dependencies = [ "zk_evm 0.133.0", "zk_evm 0.140.0", "zk_evm 0.141.0", - "zk_evm 0.150.0", + "zk_evm 0.150.4", "zksync_contracts", "zksync_eth_signer", "zksync_system_constants", @@ -9377,7 +9377,7 @@ version = "0.1.0" dependencies = [ "bincode", "chrono", - "circuit_sequencer_api 0.150.2", + "circuit_sequencer_api 0.150.4", "serde", "serde_json", "serde_with", diff --git a/Cargo.toml b/Cargo.toml index d32b6c6a673..f2c62efb453 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -207,15 +207,15 @@ circuit_sequencer_api_1_3_3 = { package = "circuit_sequencer_api", version = "0. circuit_sequencer_api_1_4_0 = { package = "circuit_sequencer_api", version = "0.140" } circuit_sequencer_api_1_4_1 = { package = "circuit_sequencer_api", version = "0.141" } circuit_sequencer_api_1_4_2 = { package = "circuit_sequencer_api", version = "0.142" } -circuit_sequencer_api_1_5_0 = { package = "circuit_sequencer_api", version = "=0.150.2" } +circuit_sequencer_api_1_5_0 = { package = "circuit_sequencer_api", version = "=0.150.4" } crypto_codegen = { package = "zksync_solidity_vk_codegen", version = "=0.1.0" } -kzg = { package = "zksync_kzg", version = "=0.150.2" } +kzg = { package = "zksync_kzg", version = "=0.150.4" } zk_evm = { version = "=0.133.0" } zk_evm_1_3_1 = { package = "zk_evm", version = "0.131.0-rc.2" } zk_evm_1_3_3 = { package = "zk_evm", version = "0.133.0" } zk_evm_1_4_0 = { package = "zk_evm", version = "0.140.0" } zk_evm_1_4_1 = { package = "zk_evm", version = "0.141.0" } -zk_evm_1_5_0 = { package = "zk_evm", version = "=0.150.0" } +zk_evm_1_5_0 = { package = "zk_evm", version = "=0.150.4" } # New VM; pinned to a specific commit because of instability vm2 = { git = "https://github.com/matter-labs/vm2.git", rev = "9a38900d7af9b1d72b47ce3be980e77c1239a61d" } diff --git a/core/lib/object_store/src/file.rs b/core/lib/object_store/src/file.rs index decba534d23..e62f40fb943 100644 --- a/core/lib/object_store/src/file.rs +++ b/core/lib/object_store/src/file.rs @@ -43,6 +43,7 @@ impl FileBackedObjectStore { Bucket::ProofsFri, Bucket::StorageSnapshot, Bucket::TeeVerifierInput, + Bucket::RamPermutationCircuitQueueWitness, ] { let bucket_path = format!("{base_dir}/{bucket}"); fs::create_dir_all(&bucket_path).await?; diff --git a/core/lib/object_store/src/raw.rs b/core/lib/object_store/src/raw.rs index 3c5a89f160a..32deec061bd 100644 --- a/core/lib/object_store/src/raw.rs +++ b/core/lib/object_store/src/raw.rs @@ -20,6 +20,7 @@ pub enum Bucket { StorageSnapshot, DataAvailability, TeeVerifierInput, + RamPermutationCircuitQueueWitness, } impl Bucket { @@ -39,6 +40,7 @@ impl Bucket { Self::StorageSnapshot => "storage_logs_snapshots", Self::DataAvailability => "data_availability", Self::TeeVerifierInput => "tee_verifier_inputs", + Self::RamPermutationCircuitQueueWitness => "ram_permutation_witnesses", } } } diff --git a/prover/Cargo.lock b/prover/Cargo.lock index 65ef5e0eacc..582f15637b5 100644 --- a/prover/Cargo.lock +++ b/prover/Cargo.lock @@ -718,9 +718,9 @@ dependencies = [ [[package]] name = "boojum-cuda" -version = "0.2.0" +version = "0.150.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "407123a79308091866f0199d510ee2fb930727204dd77d6805b3437d6cb859eb" +checksum = "c861b4baec895cb8e53b10825407f0844b0eafda2ac79e7f02de95439f0f1e74" dependencies = [ "boojum", "cmake", @@ -872,11 +872,11 @@ dependencies = [ [[package]] name = "circuit_definitions" -version = "0.150.2" +version = "0.150.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "382960e9ff16705f95157bac88d2b0b556181229019eb57db6c990e3a0fff35f" +checksum = "fffaa17c1585fbf010b9340bb1fd7f4c4eedec2c15cb74a72162fd2d16435d55" dependencies = [ - "circuit_encodings 0.150.2", + "circuit_encodings 0.150.4", "crossbeam 0.8.4", "derivative", "seq-macro", @@ -922,14 +922,14 @@ dependencies = [ [[package]] name = "circuit_encodings" -version = "0.150.2" +version = "0.150.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ba840a74f8d0b8b1334e93e4c87514a27c9be83d42d9f78d0c577572bb5f435" +checksum = "2593c02ad6b4b31ba63506c3f807f666133dd36bf47422f99b1d2947cf3c8dc1" dependencies = [ "derivative", "serde", - "zk_evm 0.150.0", - "zkevm_circuits 0.150.3", + "zk_evm 0.150.4", + "zkevm_circuits 0.150.4", ] [[package]] @@ -989,12 +989,12 @@ dependencies = [ [[package]] name = "circuit_sequencer_api" -version = "0.150.2" +version = "0.150.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79f3177b2bcd4ef5da9d2ca6916f6de31fb1973dfece27907a8dc7c69233494d" +checksum = "42d1a86b9c2207f3bb2dff5f00d1af1cb95004b6d07e9bacb6519fe08f12c04b" dependencies = [ "bellman_ce 0.7.0", - "circuit_encodings 0.150.2", + "circuit_encodings 0.150.4", "derivative", "rayon", "serde", @@ -1824,9 +1824,9 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "era_cudart" -version = "0.2.0" +version = "0.150.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6592e1277ac1ab0f3925151784a3809f4f973b1a63a0244b6d44e3872b413199" +checksum = "4ac97d833b861e32bc0a71d0542bf5c92094f9818c52d65c695227bfa95ffbe3" dependencies = [ "bitflags 2.6.0", "era_cudart_sys", @@ -1835,9 +1835,9 @@ dependencies = [ [[package]] name = "era_cudart_sys" -version = "0.2.0" +version = "0.150.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21767c452b418a7fb2bb9ffb07c744e4616da8d14176db4dcab76649c3206ece" +checksum = "ee6aed60cf09cb6d0b954d74351acb9beb13daab0bacad279691f6b97504b7e6" dependencies = [ "serde_json", ] @@ -5507,9 +5507,9 @@ checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde" [[package]] name = "shivini" -version = "0.150.3" +version = "0.150.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee96349e7395922586c312936b259cb80b3d0a27f227dc3adee480a79d52a4e6" +checksum = "c5e5d862287bb883a4cb0bc4f8ea938ba3fdaa5e495f1a59bc3515231017a0e2" dependencies = [ "bincode", "blake2 0.10.6", @@ -6781,8 +6781,8 @@ source = "git+https://github.com/matter-labs/vm2.git?rev=9a38900d7af9b1d72b47ce3 dependencies = [ "enum_dispatch", "primitive-types", - "zk_evm_abstractions 0.150.0", - "zkevm_opcode_defs 0.150.0", + "zk_evm_abstractions 0.150.4", + "zkevm_opcode_defs 0.150.4", ] [[package]] @@ -7286,9 +7286,9 @@ dependencies = [ [[package]] name = "zk_evm" -version = "0.150.0" +version = "0.150.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5bf91304aa14827758afa3def8cf622f9a7f9fb65fe5d5099018dbacf0c5984" +checksum = "e2dbb0ed38d61fbd04bd7575755924d1303e129c04c909abba7f5bfcc6260bcf" dependencies = [ "anyhow", "lazy_static", @@ -7296,7 +7296,7 @@ dependencies = [ "serde", "serde_json", "static_assertions", - "zk_evm_abstractions 0.150.0", + "zk_evm_abstractions 0.150.4", ] [[package]] @@ -7327,22 +7327,22 @@ dependencies = [ [[package]] name = "zk_evm_abstractions" -version = "0.150.0" +version = "0.150.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc313cea4ac9ef6b855264b1425cbe9de30dd8f009559dabcb6b2896122da5db" +checksum = "31460aacfe65b39ac484a2a2e0bbb02baf141f65264bf48e1e4f59ab375fe933" dependencies = [ "anyhow", "num_enum 0.6.1", "serde", "static_assertions", - "zkevm_opcode_defs 0.150.0", + "zkevm_opcode_defs 0.150.4", ] [[package]] name = "zkevm-assembly" -version = "0.150.0" +version = "0.150.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d55e7082c5a313e46e1017d12ea5acfba9f961af3c260ff580490ce02d52067c" +checksum = "7b69d09d125b94767847c4cdc4ae399654b9e2a2f9304bd8935a7033bef4b07c" dependencies = [ "env_logger 0.9.3", "hex", @@ -7355,7 +7355,7 @@ dependencies = [ "smallvec", "structopt", "thiserror", - "zkevm_opcode_defs 0.150.0", + "zkevm_opcode_defs 0.150.4", ] [[package]] @@ -7404,9 +7404,9 @@ dependencies = [ [[package]] name = "zkevm_circuits" -version = "0.150.3" +version = "0.150.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2d64bda28dec766324d2e5095a46fb141540d86a232106760dfb20ab4ae6e5c" +checksum = "abdfaa95dfe0878fda219dd17a6cc8c28711e2067785910c0e06d3ffdca78629" dependencies = [ "arrayvec 0.7.4", "boojum", @@ -7419,7 +7419,7 @@ dependencies = [ "seq-macro", "serde", "smallvec", - "zkevm_opcode_defs 0.150.0", + "zkevm_opcode_defs 0.150.4", ] [[package]] @@ -7466,9 +7466,9 @@ dependencies = [ [[package]] name = "zkevm_opcode_defs" -version = "0.150.0" +version = "0.150.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3328c012d444bdbfadb754a72c01a56879eb66584efc71eac457e89e7843608" +checksum = "bb7c5c7b4481a646f8696b08cee64a8dec097509a6378d18242f81022f327f1e" dependencies = [ "bitflags 2.6.0", "blake2 0.10.6", @@ -7483,13 +7483,13 @@ dependencies = [ [[package]] name = "zkevm_test_harness" -version = "0.150.2" +version = "0.150.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be67d84d0ac41145a4daed8333feac0936ade29feda6448f46d80ae80285911d" +checksum = "9416dc5fcf7bc403d4c24d37f0e9a492a81926ff0e89a7792dc8a29de69aec1b" dependencies = [ "bincode", "circuit_definitions", - "circuit_sequencer_api 0.150.2", + "circuit_sequencer_api 0.150.4", "codegen", "crossbeam 0.8.4", "derivative", @@ -7510,9 +7510,9 @@ dependencies = [ [[package]] name = "zksync-gpu-ffi" -version = "0.150.0" +version = "0.150.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3143200cfbf1dd8e2e14c2bf2a2b89da8fa5628c7192a4739f13269b9707656e" +checksum = "82fe099f4f4a2cc8ca8ca591d7619ac00b8054f63b712fa6ceee2b84c6e04c62" dependencies = [ "bindgen 0.59.2", "crossbeam 0.8.4", @@ -7524,9 +7524,9 @@ dependencies = [ [[package]] name = "zksync-gpu-prover" -version = "0.150.0" +version = "0.150.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1aeacd406321241ecbcedf9f3025af23511a83e666ecdec2c971935225ea5b98" +checksum = "f73d27e0e4589c7445f5a22e511cb5186e2d205172ca4b26acd7a334b3af9492" dependencies = [ "bit-vec", "cfg-if 1.0.0", @@ -7541,9 +7541,9 @@ dependencies = [ [[package]] name = "zksync-wrapper-prover" -version = "0.150.0" +version = "0.150.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdf646f359c7275451c218dcf3cd99c06afb0d21da9cc518a1aa5222ee44ee8c" +checksum = "1cf4c09adf0a84af0d7ded1fd85a2487fef4cbf1cfc1925412717d0eef03dd5a" dependencies = [ "circuit_definitions", "zkevm_test_harness", @@ -7831,9 +7831,9 @@ dependencies = [ [[package]] name = "zksync_kzg" -version = "0.150.2" +version = "0.150.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b76d0e08b3e0970565f7a9a611278547f4f1dbd6184a250c8c5e743aed61c525" +checksum = "9949f48ea1a9f9a0e73242d4d1e87e681095181827486b3fcc2cf93e5aa03280" dependencies = [ "boojum", "derivative", @@ -7843,7 +7843,7 @@ dependencies = [ "serde", "serde_json", "serde_with", - "zkevm_circuits 0.150.3", + "zkevm_circuits 0.150.4", ] [[package]] @@ -7883,7 +7883,7 @@ dependencies = [ "circuit_sequencer_api 0.140.0", "circuit_sequencer_api 0.141.1", "circuit_sequencer_api 0.142.0", - "circuit_sequencer_api 0.150.2", + "circuit_sequencer_api 0.150.4", "hex", "itertools 0.10.5", "once_cell", @@ -7896,7 +7896,7 @@ dependencies = [ "zk_evm 0.133.0", "zk_evm 0.140.0", "zk_evm 0.141.0", - "zk_evm 0.150.0", + "zk_evm 0.150.4", "zksync_contracts", "zksync_system_constants", "zksync_types", @@ -7955,7 +7955,7 @@ dependencies = [ "anyhow", "async-trait", "bincode", - "circuit_sequencer_api 0.150.2", + "circuit_sequencer_api 0.150.4", "clap 4.5.4", "ctrlc", "futures 0.3.30", @@ -8141,7 +8141,7 @@ name = "zksync_prover_interface" version = "0.1.0" dependencies = [ "chrono", - "circuit_sequencer_api 0.150.2", + "circuit_sequencer_api 0.150.4", "serde", "serde_with", "strum", diff --git a/prover/Cargo.toml b/prover/Cargo.toml index 8be6f355223..4ce85833250 100644 --- a/prover/Cargo.toml +++ b/prover/Cargo.toml @@ -56,13 +56,13 @@ tracing-subscriber = { version = "0.3" } vise = "0.2.0" # Proving dependencies -circuit_definitions = "=0.150.2" -circuit_sequencer_api = "=0.150.2" -zkevm_test_harness = "=0.150.2" +circuit_definitions = "=0.150.4" +circuit_sequencer_api = "=0.150.4" +zkevm_test_harness = "=0.150.4" # GPU proving dependencies -wrapper_prover = { package = "zksync-wrapper-prover", version = "=0.150.0" } -shivini = "=0.150.3" +wrapper_prover = { package = "zksync-wrapper-prover", version = "=0.150.4" } +shivini = "=0.150.4" # Core workspace dependencies zksync_multivm = { path = "../core/lib/multivm", version = "0.1.0" } diff --git a/prover/crates/bin/prover_cli/src/commands/get_file_info.rs b/prover/crates/bin/prover_cli/src/commands/get_file_info.rs index 63d7f25f615..cb4a45ca390 100644 --- a/prover/crates/bin/prover_cli/src/commands/get_file_info.rs +++ b/prover/crates/bin/prover_cli/src/commands/get_file_info.rs @@ -73,7 +73,7 @@ fn pretty_print_scheduler_witness( fn pretty_print_circuit_wrapper(circuit: &CircuitWrapper) { println!(" == Circuit =="); match circuit { - CircuitWrapper::Base(circuit) => { + CircuitWrapper::Base(circuit) | CircuitWrapper::BasePartial((circuit, _)) => { println!( "Type: basic. Id: {:?} ({})", circuit.numeric_circuit_type(), diff --git a/prover/crates/bin/prover_fri/src/gpu_prover_job_processor.rs b/prover/crates/bin/prover_fri/src/gpu_prover_job_processor.rs index 04146473f64..4407dbcd852 100644 --- a/prover/crates/bin/prover_fri/src/gpu_prover_job_processor.rs +++ b/prover/crates/bin/prover_fri/src/gpu_prover_job_processor.rs @@ -154,6 +154,7 @@ pub mod gpu_prover { recursion_layer_proof_config(), circuit.numeric_circuit_type(), ), + CircuitWrapper::BasePartial(_) => panic!("Invalid CircuitWrapper received"), }; let started_at = Instant::now(); @@ -196,6 +197,7 @@ pub mod gpu_prover { CircuitWrapper::Recursive(_) => FriProofWrapper::Recursive( ZkSyncRecursionLayerProof::from_inner(circuit_id, proof), ), + CircuitWrapper::BasePartial(_) => panic!("Received partial base circuit"), }; ProverArtifacts::new(prover_job.block_number, proof_wrapper) } diff --git a/prover/crates/bin/prover_fri/src/prover_job_processor.rs b/prover/crates/bin/prover_fri/src/prover_job_processor.rs index f06f1bbab93..09c9d38348f 100644 --- a/prover/crates/bin/prover_fri/src/prover_job_processor.rs +++ b/prover/crates/bin/prover_fri/src/prover_job_processor.rs @@ -109,6 +109,7 @@ impl Prover { CircuitWrapper::Recursive(recursive_circuit) => { Self::prove_recursive_layer(job.job_id, recursive_circuit, config, setup_data) } + CircuitWrapper::BasePartial(_) => panic!("Received partial base circuit"), }; ProverArtifacts::new(job.block_number, proof) } diff --git a/prover/crates/bin/prover_fri/src/utils.rs b/prover/crates/bin/prover_fri/src/utils.rs index 15a2a6c18bb..2941c15439a 100644 --- a/prover/crates/bin/prover_fri/src/utils.rs +++ b/prover/crates/bin/prover_fri/src/utils.rs @@ -128,6 +128,7 @@ pub fn verify_proof( verify_recursion_layer_proof::(recursive_circuit, proof, vk), recursive_circuit.numeric_circuit_type(), ), + CircuitWrapper::BasePartial(_) => panic!("Invalid CircuitWrapper received"), }; METRICS.proof_verification_time[&circuit_id.to_string()].observe(started_at.elapsed()); diff --git a/prover/crates/bin/witness_generator/src/basic_circuits.rs b/prover/crates/bin/witness_generator/src/basic_circuits.rs index 75326ace7f6..6dc19bd022b 100644 --- a/prover/crates/bin/witness_generator/src/basic_circuits.rs +++ b/prover/crates/bin/witness_generator/src/basic_circuits.rs @@ -8,13 +8,15 @@ use std::{ use anyhow::Context as _; use async_trait::async_trait; use circuit_definitions::{ - circuit_definitions::base_layer::ZkSyncBaseLayerStorage, + circuit_definitions::base_layer::{ZkSyncBaseLayerCircuit, ZkSyncBaseLayerStorage}, encodings::recursion_request::RecursionQueueSimulator, zkevm_circuits::fsm_input_output::ClosedFormInputCompactFormWitness, }; use tokio::sync::Semaphore; use tracing::Instrument; -use zkevm_test_harness::geometry_config::get_geometry_config; +use zkevm_test_harness::{ + geometry_config::get_geometry_config, witness::oracle::WitnessGenerationArtifact, +}; use zksync_config::configs::FriWitnessGeneratorConfig; use zksync_multivm::{ interface::storage::StorageView, @@ -34,7 +36,7 @@ use zksync_prover_fri_types::{ }, get_current_pod_name, keys::ClosedFormInputKey, - AuxOutputWitnessWrapper, + AuxOutputWitnessWrapper, CircuitAuxData, }; use zksync_prover_fri_utils::get_recursive_layer_circuit_id_for_base_layer; use zksync_prover_interface::inputs::WitnessInputData; @@ -49,8 +51,8 @@ use crate::{ precalculated_merkle_paths_provider::PrecalculatedMerklePathsProvider, storage_oracle::StorageOracle, utils::{ - expand_bootloader_contents, save_circuit, ClosedFormInputWrapper, - SchedulerPartialInputWrapper, KZG_TRUSTED_SETUP_FILE, + expand_bootloader_contents, save_circuit, save_ram_premutation_queue_witness, + ClosedFormInputWrapper, SchedulerPartialInputWrapper, KZG_TRUSTED_SETUP_FILE, }, witness::WitnessStorage, }; @@ -432,6 +434,8 @@ async fn generate_witness( let (circuit_sender, mut circuit_receiver) = tokio::sync::mpsc::channel(1); let (queue_sender, mut queue_receiver) = tokio::sync::mpsc::channel(1); + let (ram_permutation_queue_sender, mut ram_permutation_queue_receiver) = + tokio::sync::mpsc::channel(1); let make_circuits_span = tracing::info_span!("make_circuits"); let make_circuits_span_copy = make_circuits_span.clone(); @@ -457,6 +461,29 @@ async fn generate_witness( .to_str() .expect("Path to KZG trusted setup is not a UTF-8 string"); + let artifacts_callback = |artifact: WitnessGenerationArtifact| match artifact { + WitnessGenerationArtifact::BaseLayerCircuit(circuit) => { + let parent_span = span.clone(); + tracing::info_span!(parent: parent_span, "send_circuit").in_scope(|| { + circuit_sender + .blocking_send(circuit) + .expect("failed to send circuit from harness"); + }); + } + WitnessGenerationArtifact::RecursionQueue((a, b, c)) => queue_sender + .blocking_send((a as u8, b, c)) + .expect("failed to send recursion queue from harness"), + a @ WitnessGenerationArtifact::MemoryQueueWitness(_) => { + let parent_span = span.clone(); + tracing::info_span!(parent: parent_span, "send_ram_permutation_queue_witness") + .in_scope(|| { + ram_permutation_queue_sender + .blocking_send(a) + .expect("failed to send ram permutation queue sitness from harness"); + }); + } + }; + let (scheduler_witness, block_witness) = zkevm_test_harness::external_calls::run( Address::zero(), BOOTLOADER_ADDRESS, @@ -474,24 +501,14 @@ async fn generate_witness( tree, path, input.eip_4844_blobs.blobs(), - |circuit| { - let parent_span = span.clone(); - tracing::info_span!(parent: parent_span, "send_circuit").in_scope(|| { - circuit_sender - .blocking_send(circuit) - .expect("failed to send circuit from harness"); - }); - }, - |a, b, c| { - queue_sender - .blocking_send((a as u8, b, c)) - .expect("failed to send recursion queue from harness") - }, + artifacts_callback, ); (scheduler_witness, block_witness) }) .instrument(make_circuits_span); + let semaphore = Arc::new(Semaphore::new(max_circuits_in_flight)); + let mut save_circuit_handles = vec![]; let save_circuits_span = tracing::info_span!("save_circuits"); @@ -503,7 +520,7 @@ async fn generate_witness( // If the order is tampered with, proving will fail (as the proof would be computed for a different sequence of instruction). let mut circuit_sequence = 0; - let semaphore = Arc::new(Semaphore::new(max_circuits_in_flight)); + let mut ram_circuit_sequence = 0; while let Some(circuit) = circuit_receiver .recv() @@ -518,9 +535,27 @@ async fn generate_witness( .acquire_owned() .await .expect("failed to get permit for running save circuit task"); + + let partial_circuit_aux_data = match &circuit { + ZkSyncBaseLayerCircuit::RAMPermutation(_) => { + let circuit_subsequence_number = ram_circuit_sequence; + ram_circuit_sequence += 1; + Some(CircuitAuxData { + circuit_subsequence_number, + }) + } + _ => None, + }; + save_circuit_handles.push(tokio::task::spawn(async move { - let (circuit_id, circuit_url) = - save_circuit(block_number, circuit, sequence, object_store).await; + let (circuit_id, circuit_url) = save_circuit( + block_number, + circuit, + sequence, + partial_circuit_aux_data, + object_store, + ) + .await; drop(permit); (circuit_id, circuit_url) })); @@ -528,6 +563,57 @@ async fn generate_witness( } .instrument(save_circuits_span); + let mut save_ram_queue_witness_handles = vec![]; + + let save_ram_queue_witness_span = tracing::info_span!("save_circuits"); + + // Future which receives part of RAM permutation circuits witnesses and saves them async. + // Uses semaphore because these artifacts are of significant size + let ram_queue_witness_receiver_handle = async { + let mut sorted_sequence = 0; + let mut unsorted_sequence = 0; + + while let Some(witness_artifact) = ram_permutation_queue_receiver + .recv() + .instrument(tracing::info_span!("wait_for_ram_witness")) + .await + { + let object_store = object_store.clone(); + let semaphore = semaphore.clone(); + let permit = semaphore + .acquire_owned() + .await + .expect("failed to get permit for running save ram permutation queue witness task"); + let (is_sorted, witness, sequence) = match witness_artifact { + WitnessGenerationArtifact::MemoryQueueWitness((witness, sorted)) => { + let sequence = if sorted { + let sequence = sorted_sequence; + sorted_sequence += 1; + sequence + } else { + let sequence = unsorted_sequence; + unsorted_sequence += 1; + sequence + }; + (sorted, witness, sequence) + } + _ => panic!("Invalid artifact received"), + }; + save_ram_queue_witness_handles.push(tokio::task::spawn(async move { + let _ = save_ram_premutation_queue_witness( + block_number, + sequence, + is_sorted, + witness, + object_store, + ) + .await; + drop(permit); + })); + } + } + .instrument(save_ram_queue_witness_span); + let mut save_queue_handles = vec![]; let save_queues_span = tracing::info_span!("save_queues"); @@ -553,10 +639,11 @@ async fn generate_witness( } .instrument(save_queues_span); - let (witnesses, _, _) = tokio::join!( + let (witnesses, _, _, _) = tokio::join!( make_circuits_handle, circuit_receiver_handle, - queue_receiver_handle + queue_receiver_handle, + ram_queue_witness_receiver_handle ); let (mut scheduler_witness, block_aux_witness) = witnesses.unwrap(); @@ -581,6 +668,8 @@ async fn generate_witness( .filter(|(circuit_id, _, _)| circuits_present.contains(circuit_id)) .collect(); + futures::future::join_all(save_ram_queue_witness_handles).await; + scheduler_witness.previous_block_meta_hash = input.previous_batch_metadata.meta_hash.0; scheduler_witness.previous_block_aux_hash = input.previous_batch_metadata.aux_hash.0; diff --git a/prover/crates/bin/witness_generator/src/utils.rs b/prover/crates/bin/witness_generator/src/utils.rs index 65fe26d63f5..f8656ac90f4 100644 --- a/prover/crates/bin/witness_generator/src/utils.rs +++ b/prover/crates/bin/witness_generator/src/utils.rs @@ -4,9 +4,12 @@ use std::{ sync::Arc, }; -use circuit_definitions::circuit_definitions::{ - base_layer::ZkSyncBaseLayerCircuit, - recursion_layer::{ZkSyncRecursionLayerStorageType, ZkSyncRecursionProof}, +use circuit_definitions::{ + circuit_definitions::{ + base_layer::ZkSyncBaseLayerCircuit, + recursion_layer::{ZkSyncRecursionLayerStorageType, ZkSyncRecursionProof}, + }, + encodings::memory_query::MemoryQueueStateWitnesses, }; use once_cell::sync::Lazy; use zkevm_test_harness::{ @@ -28,8 +31,8 @@ use zksync_prover_fri_types::{ encodings::recursion_request::RecursionQueueSimulator, zkevm_circuits::scheduler::input::SchedulerCircuitInstanceWitness, }, - keys::{AggregationsKey, ClosedFormInputKey, FriCircuitKey}, - CircuitWrapper, FriProofWrapper, + keys::{AggregationsKey, ClosedFormInputKey, FriCircuitKey, RamPermutationQueueWitnessKey}, + CircuitAuxData, CircuitWrapper, FriProofWrapper, RamPermutationQueueWitness, }; use zksync_types::{basic_fri_types::AggregationRound, L1BatchNumber, ProtocolVersionId, U256}; @@ -125,6 +128,7 @@ pub async fn save_circuit( block_number: L1BatchNumber, circuit: ZkSyncBaseLayerCircuit, sequence_number: usize, + aux_data_for_partial_circuit: Option, object_store: Arc, ) -> (u8, String) { let circuit_id = circuit.numeric_circuit_type(); @@ -135,13 +139,46 @@ pub async fn save_circuit( aggregation_round: AggregationRound::BasicCircuits, depth: 0, }; - let blob_url = object_store - .put(circuit_key, &CircuitWrapper::Base(circuit)) - .await - .unwrap(); + + let blob_url = if let Some(aux_data_for_partial_circuit) = aux_data_for_partial_circuit { + object_store + .put( + circuit_key, + &CircuitWrapper::BasePartial((circuit, aux_data_for_partial_circuit)), + ) + .await + .unwrap() + } else { + object_store + .put(circuit_key, &CircuitWrapper::Base(circuit)) + .await + .unwrap() + }; (circuit_id, blob_url) } +#[tracing::instrument( + skip_all, + fields(l1_batch = %block_number) +)] +pub async fn save_ram_premutation_queue_witness( + block_number: L1BatchNumber, + circuit_subsequence_number: usize, + is_sorted: bool, + witness: MemoryQueueStateWitnesses, + object_store: Arc, +) -> String { + let witness_key = RamPermutationQueueWitnessKey { + block_number, + circuit_subsequence_number, + is_sorted, + }; + object_store + .put(witness_key, &RamPermutationQueueWitness { witness }) + .await + .unwrap() +} + #[tracing::instrument( skip_all, fields(l1_batch = %block_number) diff --git a/prover/crates/bin/witness_vector_generator/src/generator.rs b/prover/crates/bin/witness_vector_generator/src/generator.rs index e26173067fb..800931f5d7c 100644 --- a/prover/crates/bin/witness_vector_generator/src/generator.rs +++ b/prover/crates/bin/witness_vector_generator/src/generator.rs @@ -79,6 +79,9 @@ impl WitnessVectorGenerator { CircuitWrapper::Recursive(recursive_circuit) => { recursive_circuit.synthesis::(&finalization_hints) } + CircuitWrapper::BasePartial(_) => { + panic!("Invalid circuit wrapper received for witness vector generation"); + } }; Ok(WitnessVectorArtifacts::new(cs.witness.unwrap(), job)) } diff --git a/prover/crates/lib/prover_fri_types/src/keys.rs b/prover/crates/lib/prover_fri_types/src/keys.rs index 729db754178..2948fc5f84e 100644 --- a/prover/crates/lib/prover_fri_types/src/keys.rs +++ b/prover/crates/lib/prover_fri_types/src/keys.rs @@ -35,3 +35,11 @@ pub struct CircuitKey<'a> { pub circuit_type: &'a str, pub aggregation_round: AggregationRound, } + +/// Storage key for a [`RamPermutationQueueWitness`]. +#[derive(Debug, Clone, Copy)] +pub struct RamPermutationQueueWitnessKey { + pub block_number: L1BatchNumber, + pub circuit_subsequence_number: usize, + pub is_sorted: bool, +} diff --git a/prover/crates/lib/prover_fri_types/src/lib.rs b/prover/crates/lib/prover_fri_types/src/lib.rs index 423be1f88fa..a327111fe6f 100644 --- a/prover/crates/lib/prover_fri_types/src/lib.rs +++ b/prover/crates/lib/prover_fri_types/src/lib.rs @@ -9,10 +9,12 @@ use circuit_definitions::{ ZkSyncRecursionLayerProof, ZkSyncRecursionLayerStorageType, ZkSyncRecursiveLayerCircuit, }, }, + encodings::memory_query::MemoryQueueStateWitnesses, zkevm_circuits::scheduler::{ aux::BaseLayerCircuitType, block_header::BlockAuxilaryOutputWitness, }, }; +use keys::RamPermutationQueueWitnessKey; use zksync_object_store::{serialize_using_bincode, Bucket, StoredObject}; use zksync_types::{ basic_fri_types::AggregationRound, @@ -33,11 +35,17 @@ pub const PROVER_PROTOCOL_SEMANTIC_VERSION: ProtocolSemanticVersion = ProtocolSe patch: PROVER_PROTOCOL_PATCH, }; +#[derive(serde::Serialize, serde::Deserialize, Clone)] +pub struct CircuitAuxData { + pub circuit_subsequence_number: u32, +} + #[derive(serde::Serialize, serde::Deserialize, Clone)] #[allow(clippy::large_enum_variant)] pub enum CircuitWrapper { Base(ZkSyncBaseLayerCircuit), Recursive(ZkSyncRecursiveLayerCircuit), + BasePartial((ZkSyncBaseLayerCircuit, CircuitAuxData)), } impl StoredObject for CircuitWrapper { @@ -214,3 +222,27 @@ impl StoredObject for AuxOutputWitnessWrapper { pub fn get_current_pod_name() -> String { env::var("POD_NAME").unwrap_or("UNKNOWN_POD".to_owned()) } + +#[derive(serde::Serialize, serde::Deserialize)] +pub struct RamPermutationQueueWitness { + pub witness: MemoryQueueStateWitnesses, +} + +impl StoredObject for RamPermutationQueueWitness { + const BUCKET: Bucket = Bucket::RamPermutationCircuitQueueWitness; + type Key<'a> = RamPermutationQueueWitnessKey; + + fn encode_key(key: Self::Key<'_>) -> String { + let RamPermutationQueueWitnessKey { + block_number, + circuit_subsequence_number, + is_sorted, + } = key; + format!( + "queue_witness_{block_number}_{circuit_subsequence_number}_{}.bin", + is_sorted as u64 + ) + } + + serialize_using_bincode!(); +} diff --git a/prover/crates/lib/prover_fri_utils/src/lib.rs b/prover/crates/lib/prover_fri_utils/src/lib.rs index 0873d505628..02c6da3d5f5 100644 --- a/prover/crates/lib/prover_fri_utils/src/lib.rs +++ b/prover/crates/lib/prover_fri_utils/src/lib.rs @@ -4,14 +4,18 @@ use zksync_object_store::ObjectStore; use zksync_prover_dal::{Connection, Prover, ProverDal}; use zksync_prover_fri_types::{ circuit_definitions::{ - circuit_definitions::recursion_layer::{ - base_circuit_type_into_recursive_leaf_circuit_type, ZkSyncRecursionLayerStorageType, + boojum::gadgets::queue::full_state_queue::FullStateCircuitQueueRawWitness, + circuit_definitions::{ + base_layer::ZkSyncBaseLayerCircuit, + recursion_layer::{ + base_circuit_type_into_recursive_leaf_circuit_type, ZkSyncRecursionLayerStorageType, + }, }, zkevm_circuits::scheduler::aux::BaseLayerCircuitType, }, get_current_pod_name, - keys::FriCircuitKey, - CircuitWrapper, ProverJob, ProverServiceDataKey, + keys::{FriCircuitKey, RamPermutationQueueWitnessKey}, + CircuitWrapper, ProverJob, ProverServiceDataKey, RamPermutationQueueWitness, }; use zksync_types::{ basic_fri_types::{AggregationRound, CircuitIdRoundTuple}, @@ -61,10 +65,52 @@ pub async fn fetch_next_circuit( depth: prover_job.depth, }; let started_at = Instant::now(); - let input = blob_store + let circuit_wrapper = blob_store .get(circuit_key) .await .unwrap_or_else(|err| panic!("{err:?}")); + let input = match circuit_wrapper { + a @ CircuitWrapper::Base(_) => a, + a @ CircuitWrapper::Recursive(_) => a, + CircuitWrapper::BasePartial((circuit, aux_data)) => { + // inject additional data + if let ZkSyncBaseLayerCircuit::RAMPermutation(circuit_instance) = circuit { + let sorted_witness_key = RamPermutationQueueWitnessKey { + block_number: prover_job.block_number, + circuit_subsequence_number: aux_data.circuit_subsequence_number as usize, + is_sorted: true, + }; + + let sorted_witness_handle = blob_store.get(sorted_witness_key); + + let unsorted_witness_key = RamPermutationQueueWitnessKey { + block_number: prover_job.block_number, + circuit_subsequence_number: aux_data.circuit_subsequence_number as usize, + is_sorted: false, + }; + + let unsorted_witness_handle = blob_store.get(unsorted_witness_key); + + let unsorted_witness: RamPermutationQueueWitness = + unsorted_witness_handle.await.unwrap(); + let sorted_witness: RamPermutationQueueWitness = + sorted_witness_handle.await.unwrap(); + + let mut witness = circuit_instance.witness.take().unwrap(); + witness.unsorted_queue_witness = FullStateCircuitQueueRawWitness { + elements: unsorted_witness.witness.into(), + }; + witness.sorted_queue_witness = FullStateCircuitQueueRawWitness { + elements: sorted_witness.witness.into(), + }; + circuit_instance.witness.store(Some(witness)); + + CircuitWrapper::Base(ZkSyncBaseLayerCircuit::RAMPermutation(circuit_instance)) + } else { + panic!("Unexpected circuit received with partial witness"); + } + } + }; let label = CircuitLabels { circuit_type: prover_job.circuit_id, @@ -97,7 +143,9 @@ pub fn get_base_layer_circuit_id_for_recursive_layer(recursive_layer_circuit_id: pub fn get_numeric_circuit_id(circuit_wrapper: &CircuitWrapper) -> u8 { match circuit_wrapper { - CircuitWrapper::Base(circuit) => circuit.numeric_circuit_type(), + CircuitWrapper::Base(circuit) | CircuitWrapper::BasePartial((circuit, _)) => { + circuit.numeric_circuit_type() + } CircuitWrapper::Recursive(circuit) => circuit.numeric_circuit_type(), } }