From 0d00650f3e97248617b88a7e082c515ac48d5d5b Mon Sep 17 00:00:00 2001 From: Vladislav Volosnikov Date: Fri, 2 Aug 2024 13:37:42 +0200 Subject: [PATCH 1/2] feat: optimize LWG and NWG (#2512) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## What ❔ Separating recursive circuits from the AggregationWrapper struct allows them to be used separately and significantly reduces data duplication in the storage. Processing L/N circuits in parallel speeds up processing, also providing an adjustable limits on peak memory. --- Cargo.lock | 76 ++++---- Cargo.toml | 18 +- .../src/configs/fri_witness_generator.rs | 18 +- prover/Cargo.lock | 160 ++++++++--------- prover/Cargo.toml | 10 +- .../witness_generator/src/leaf_aggregation.rs | 153 ++++++++++++----- .../witness_generator/src/node_aggregation.rs | 162 +++++++++++++----- .../crates/bin/witness_generator/src/utils.rs | 31 +--- .../bin/witness_generator/tests/basic_test.rs | 155 ++++++++++++++--- 9 files changed, 504 insertions(+), 279 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f7f8a206137a..d02758df4a7b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -722,9 +722,9 @@ dependencies = [ [[package]] name = "boojum" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f0c2cba247d620ff76123efb335401aa05ec5639551e6ef4e5f977c0809b5cb" +checksum = "0cf10f4b3980dc82dc31709dfa8193b7d6106a3a7ce9f9a9f8872bfb8719aa2d" dependencies = [ "arrayvec 0.7.4", "bincode", @@ -1009,50 +1009,50 @@ dependencies = [ [[package]] name = "circuit_encodings" -version = "0.140.0" +version = "0.140.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7f1168c8fbb45fc7704c1bcdbb65ebdcb019fc9bf1101a475904eff835632f7" +checksum = "b8438d7af992b730143b679e2c6938cb9e0193897ecaf668c59189af8ac296b7" dependencies = [ "derivative", "serde", "zk_evm 0.140.0", - "zkevm_circuits 0.140.0", + "zkevm_circuits 0.140.2", ] [[package]] name = "circuit_encodings" -version = "0.141.0" +version = "0.141.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90b17a11dd3489daef314cbb07e1098e8e34a35a625fdca421b0012f4bb6cbd0" +checksum = "01a2fcc80e97682104f355dd819cb4972583828a6c0f65ec26889a78a84b0c56" dependencies = [ "derivative", "serde", "zk_evm 0.141.0", - "zkevm_circuits 0.141.0", + "zkevm_circuits 0.141.1", ] [[package]] name = "circuit_encodings" -version = "0.142.0" +version = "0.142.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5df3af2244275a1270e2887b2f47625ec78dff14db8dd8a88f7ea1ea0781e48b" +checksum = "94be7afb5ace6024d6e3c105d521b4b9b563bac14a92c2f59c4683e9169a25d8" dependencies = [ "derivative", "serde", "zk_evm 0.141.0", - "zkevm_circuits 0.141.0", + "zkevm_circuits 0.141.1", ] [[package]] name = "circuit_encodings" -version = "0.150.2-rc.1" +version = "0.150.2-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4b69893ec5a2112430adaf8e29b52ea9ec4ef2d6663879f7cc279b4479a8880" +checksum = "e59747066b9a0d1a15d45f5837658aec5d53744fb643954f9dcc412f76c0d346" dependencies = [ "derivative", "serde", "zk_evm 0.150.0", - "zkevm_circuits 0.150.0", + "zkevm_circuits 0.150.1", ] [[package]] @@ -1075,7 +1075,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4b5138e6524c73e6d49fc1d0822b26e62a8d78b2c07e4e1c56061a447c10bec0" dependencies = [ "bellman_ce", - "circuit_encodings 0.140.0", + "circuit_encodings 0.140.1", "derivative", "rayon", "serde", @@ -1084,12 +1084,12 @@ dependencies = [ [[package]] name = "circuit_sequencer_api" -version = "0.141.0" +version = "0.141.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff871d625d002eb7f27394a239c0b19d8449adf1b9ca7805ebb43c8cf0810b51" +checksum = "55a257b31a8ea1c1723cab4fb5661c6b4c0ebe022d4b73bea9eb7c9150bd3bc1" dependencies = [ "bellman_ce", - "circuit_encodings 0.141.0", + "circuit_encodings 0.141.1", "derivative", "rayon", "serde", @@ -1103,7 +1103,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1d861a7a9b8df9389c63092985fc993c46954771da86462d7cab8cbf55a6497" dependencies = [ "bellman_ce", - "circuit_encodings 0.142.0", + "circuit_encodings 0.142.1", "derivative", "rayon", "serde", @@ -1112,12 +1112,12 @@ dependencies = [ [[package]] name = "circuit_sequencer_api" -version = "0.150.2-rc.1" +version = "0.150.2-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "121470724079938b8f878e8a95f757d814624795c9a5ca69dd9dd782035fbe39" +checksum = "dbfeb50910b20c4f05cc51700b2396a655cef9e6f0c84debd71cb02ce4853902" dependencies = [ "bellman_ce", - "circuit_encodings 0.150.2-rc.1", + "circuit_encodings 0.150.2-rc.2", "derivative", "rayon", "serde", @@ -1578,9 +1578,9 @@ dependencies = [ [[package]] name = "cs_derive" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "faa0b8f9fdb5c91dcd5569cc7cbc11f514fd784a34988ead8455db0db2cfc1c7" +checksum = "ab1f510bfddd1fc643a1d1bf8a405e279ffc818ee7ac86ed658e667a44958178" dependencies = [ "proc-macro-error", "proc-macro2 1.0.86", @@ -7913,9 +7913,9 @@ dependencies = [ [[package]] name = "zkevm_circuits" -version = "0.140.0" +version = "0.140.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db7061a85757529d06a9cb1c4697902bff16dfb303484499eeb5c7f20e1ac0d" +checksum = "8beed4cc1ab1f9d99a694506d18705e10059534b30742832be49637c4775e1f8" dependencies = [ "arrayvec 0.7.4", "bincode", @@ -7935,9 +7935,9 @@ dependencies = [ [[package]] name = "zkevm_circuits" -version = "0.141.0" +version = "0.141.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25e0f6e554b88310ad3b086e5334fbebe27154674a91c91643241b64c3d05b3a" +checksum = "20f1a64d256cc5f5c58d19cf976cb45973df54e4e3010ca4a3e6fafe9f06075e" dependencies = [ "arrayvec 0.7.4", "bincode", @@ -7957,9 +7957,9 @@ dependencies = [ [[package]] name = "zkevm_circuits" -version = "0.150.0" +version = "0.150.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4691ca0faeb666120ad48fb1a45750c5bacc90118a851f4450f3e1e903f9b2e3" +checksum = "e8a85c1987a1e7e89f1f8c39ca19bffb61521e719050086372aaea8817f403fc" dependencies = [ "arrayvec 0.7.4", "boojum", @@ -8114,8 +8114,8 @@ version = "0.1.0" dependencies = [ "anyhow", "circuit_sequencer_api 0.140.0", - "circuit_sequencer_api 0.141.0", - "circuit_sequencer_api 0.150.2-rc.1", + "circuit_sequencer_api 0.141.1", + "circuit_sequencer_api 0.150.2-rc.2", "futures 0.3.28", "itertools 0.10.5", "num_cpus", @@ -8767,9 +8767,9 @@ dependencies = [ [[package]] name = "zksync_kzg" -version = "0.150.2-rc.1" +version = "0.150.2-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4672556b6bc06da9dcd38a607e139b8eb3083edfaabcd12981e8a62051ee1f81" +checksum = "c44edd3a3316dcab45aab7e190c96150f2586d4a92fa21f93dcc20178308313a" dependencies = [ "boojum", "derivative", @@ -8779,7 +8779,7 @@ dependencies = [ "serde", "serde_json", "serde_with", - "zkevm_circuits 0.150.0", + "zkevm_circuits 0.150.1", ] [[package]] @@ -8889,9 +8889,9 @@ dependencies = [ "anyhow", "circuit_sequencer_api 0.133.0", "circuit_sequencer_api 0.140.0", - "circuit_sequencer_api 0.141.0", + "circuit_sequencer_api 0.141.1", "circuit_sequencer_api 0.142.0", - "circuit_sequencer_api 0.150.2-rc.1", + "circuit_sequencer_api 0.150.2-rc.2", "ethabi", "hex", "itertools 0.10.5", @@ -9332,7 +9332,7 @@ version = "0.1.0" dependencies = [ "bincode", "chrono", - "circuit_sequencer_api 0.150.2-rc.1", + "circuit_sequencer_api 0.150.2-rc.2", "serde", "serde_json", "serde_with", diff --git a/Cargo.toml b/Cargo.toml index 1427c4b6678c..84148996e890 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -197,19 +197,23 @@ trybuild = "1.0" vise = "0.1.0" vise-exporter = "0.1.0" -circuit_sequencer_api_1_3_3 = { package = "circuit_sequencer_api", version = "=0.133.0" } -circuit_sequencer_api_1_4_0 = { package = "circuit_sequencer_api", version = "=0.140.0" } -circuit_sequencer_api_1_4_1 = { package = "circuit_sequencer_api", version = "=0.141.0" } -circuit_sequencer_api_1_4_2 = { package = "circuit_sequencer_api", version = "=0.142.0" } -circuit_sequencer_api_1_5_0 = { package = "circuit_sequencer_api", version = "=0.150.2-rc.1" } +# Here and below: +# We *always* pin the latest version of protocol to disallow accidental changes in the execution logic. +# However, for the historical version of protocol crates, we have lax requirements. Otherwise, +# Bumping a crypto dependency like `boojum` would require us to republish all the historical packages. +circuit_sequencer_api_1_3_3 = { package = "circuit_sequencer_api", version = "0.133" } +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-rc.2" } crypto_codegen = { package = "zksync_solidity_vk_codegen", version = "=0.1.0" } -kzg = { package = "zksync_kzg", version = "=0.150.2-rc.1" } +kzg = { package = "zksync_kzg", version = "=0.150.2-rc.2" } 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.0" } # Consensus dependencies. zksync_concurrency = "=0.1.0-rc.5" diff --git a/core/lib/config/src/configs/fri_witness_generator.rs b/core/lib/config/src/configs/fri_witness_generator.rs index 44eab27d3b5e..eadfdf02638f 100644 --- a/core/lib/config/src/configs/fri_witness_generator.rs +++ b/core/lib/config/src/configs/fri_witness_generator.rs @@ -26,12 +26,20 @@ pub struct FriWitnessGeneratorConfig { pub prometheus_listener_port: Option, - /// This value corresponds to the maximum number of circuits kept in memory at any given time for a BWG. + /// This value corresponds to the maximum number of circuits kept in memory at any given time for a BWG/LWG/NWG. /// Acts as a throttling mechanism for circuits; the trade-off here is speed vs memory usage. + /// + /// BWG: /// With more circuits in flight, harness does not need to wait for BWG runner to process them. /// But every single circuit in flight eats memory (up to 50MB). + /// + /// LWG/NWG: + /// Each circuit is processed in parallel. + /// Each circuit requires downloading RECURSION_ARITY (32) proofs, each of which can be roughly estimated at 1 MB. + /// So every single circuit should use ~32 MB of RAM + some overhead during serialization + /// /// WARNING: Do NOT change this value unless you're absolutely sure you know what you're doing. - /// It affects the performance and resource usage of BWGs. + /// It affects the performance and resource usage of WGs. #[serde(default = "FriWitnessGeneratorConfig::default_max_circuits_in_flight")] pub max_circuits_in_flight: usize, } @@ -97,10 +105,10 @@ impl FriWitnessGeneratorConfig { self.last_l1_batch_to_process.unwrap_or(u32::MAX) } - /// 500 was picked as a mid-ground between allowing enough circuits in flight to speed up circuit generation, - /// whilst keeping memory as low as possible. At the moment, max size of a circuit is ~50MB. + /// 500 was picked as a mid-ground between allowing enough circuits in flight to speed up BWG circuit generation, + /// whilst keeping memory as low as possible. At the moment, max size of a circuit in BWG is ~50MB. /// This number is important when there are issues with saving circuits (network issues, service unavailability, etc.) - /// Maximum theoretic extra memory consumed is up to 25GB (50MB * 500 circuits), but in reality, worse case scenarios are closer to 5GB (the average space distribution). + /// Maximum theoretic extra memory consumed by BWG is up to 25GB (50MB * 500 circuits), but in reality, worse case scenarios are closer to 5GB (the average space distribution). /// During normal operations (> P95), this will incur an overhead of ~100MB. const fn default_max_circuits_in_flight() -> usize { 500 diff --git a/prover/Cargo.lock b/prover/Cargo.lock index 2fd8a1d1c328..cdeb031c4e6d 100644 --- a/prover/Cargo.lock +++ b/prover/Cargo.lock @@ -698,9 +698,9 @@ dependencies = [ [[package]] name = "boojum" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f0c2cba247d620ff76123efb335401aa05ec5639551e6ef4e5f977c0809b5cb" +checksum = "0cf10f4b3980dc82dc31709dfa8193b7d6106a3a7ce9f9a9f8872bfb8719aa2d" dependencies = [ "arrayvec 0.7.4", "bincode", @@ -730,9 +730,9 @@ dependencies = [ [[package]] name = "boojum-cuda" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04e402ed72733b016d29100aa5b500d5cbcf5eaa2b6805aaba1971a355d202c9" +checksum = "bf1cadeaf29fa0f076c230a08f57932619b2ba46a1977c72bb42160574400f54" dependencies = [ "boojum", "cmake", @@ -921,9 +921,9 @@ dependencies = [ [[package]] name = "circuit_definitions" -version = "0.140.0-gpu-wrapper.0" +version = "0.140.0-gpu-wrapper.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d32d2d377f12c125322717d06701e466eb0389400ba68209c90545fee6408677" +checksum = "a1f38b36c1cbc5e53bb016eebbaa0740f939bec9154100e9e31d28035faed202" dependencies = [ "crossbeam 0.8.4", "derivative", @@ -931,16 +931,16 @@ dependencies = [ "serde", "snark_wrapper", "zk_evm 0.140.0", - "zkevm_circuits 0.140.0", + "zkevm_circuits 0.140.1", ] [[package]] name = "circuit_definitions" -version = "0.150.2-rc.1" +version = "0.150.2-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45eda61fb4b476ceac2dad7aaf85ba4ed02fb834598dd7aafacebe405f2af612" +checksum = "f98221101f42cceafa9baf8ec320ef78aa02bf7c2be5c398bf90e7acf1709bfa" dependencies = [ - "circuit_encodings 0.150.2-rc.1", + "circuit_encodings 0.150.2-rc.2", "crossbeam 0.8.4", "derivative", "seq-macro", @@ -950,50 +950,50 @@ dependencies = [ [[package]] name = "circuit_encodings" -version = "0.140.0" +version = "0.140.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7f1168c8fbb45fc7704c1bcdbb65ebdcb019fc9bf1101a475904eff835632f7" +checksum = "b8438d7af992b730143b679e2c6938cb9e0193897ecaf668c59189af8ac296b7" dependencies = [ "derivative", "serde", "zk_evm 0.140.0", - "zkevm_circuits 0.140.0", + "zkevm_circuits 0.140.1", ] [[package]] name = "circuit_encodings" -version = "0.141.0" +version = "0.141.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90b17a11dd3489daef314cbb07e1098e8e34a35a625fdca421b0012f4bb6cbd0" +checksum = "01a2fcc80e97682104f355dd819cb4972583828a6c0f65ec26889a78a84b0c56" dependencies = [ "derivative", "serde", "zk_evm 0.141.0", - "zkevm_circuits 0.141.0", + "zkevm_circuits 0.141.1", ] [[package]] name = "circuit_encodings" -version = "0.142.0" +version = "0.142.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5df3af2244275a1270e2887b2f47625ec78dff14db8dd8a88f7ea1ea0781e48b" +checksum = "94be7afb5ace6024d6e3c105d521b4b9b563bac14a92c2f59c4683e9169a25d8" dependencies = [ "derivative", "serde", "zk_evm 0.141.0", - "zkevm_circuits 0.141.0", + "zkevm_circuits 0.141.1", ] [[package]] name = "circuit_encodings" -version = "0.150.2-rc.1" +version = "0.150.2-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4b69893ec5a2112430adaf8e29b52ea9ec4ef2d6663879f7cc279b4479a8880" +checksum = "e59747066b9a0d1a15d45f5837658aec5d53744fb643954f9dcc412f76c0d346" dependencies = [ "derivative", "serde", "zk_evm 0.150.0", - "zkevm_circuits 0.150.0", + "zkevm_circuits 0.150.1", ] [[package]] @@ -1016,7 +1016,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4b5138e6524c73e6d49fc1d0822b26e62a8d78b2c07e4e1c56061a447c10bec0" dependencies = [ "bellman_ce 0.7.0", - "circuit_encodings 0.140.0", + "circuit_encodings 0.140.1", "derivative", "rayon", "serde", @@ -1025,12 +1025,12 @@ dependencies = [ [[package]] name = "circuit_sequencer_api" -version = "0.141.0" +version = "0.141.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff871d625d002eb7f27394a239c0b19d8449adf1b9ca7805ebb43c8cf0810b51" +checksum = "55a257b31a8ea1c1723cab4fb5661c6b4c0ebe022d4b73bea9eb7c9150bd3bc1" dependencies = [ - "bellman_ce 0.7.0", - "circuit_encodings 0.141.0", + "bellman_ce 0.8.0", + "circuit_encodings 0.141.1", "derivative", "rayon", "serde", @@ -1044,7 +1044,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1d861a7a9b8df9389c63092985fc993c46954771da86462d7cab8cbf55a6497" dependencies = [ "bellman_ce 0.7.0", - "circuit_encodings 0.142.0", + "circuit_encodings 0.142.1", "derivative", "rayon", "serde", @@ -1053,12 +1053,12 @@ dependencies = [ [[package]] name = "circuit_sequencer_api" -version = "0.150.2-rc.1" +version = "0.150.2-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "121470724079938b8f878e8a95f757d814624795c9a5ca69dd9dd782035fbe39" +checksum = "dbfeb50910b20c4f05cc51700b2396a655cef9e6f0c84debd71cb02ce4853902" dependencies = [ "bellman_ce 0.7.0", - "circuit_encodings 0.150.2-rc.1", + "circuit_encodings 0.150.2-rc.2", "derivative", "rayon", "serde", @@ -1478,9 +1478,9 @@ dependencies = [ [[package]] name = "cs_derive" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "faa0b8f9fdb5c91dcd5569cc7cbc11f514fd784a34988ead8455db0db2cfc1c7" +checksum = "ab1f510bfddd1fc643a1d1bf8a405e279ffc818ee7ac86ed658e667a44958178" dependencies = [ "proc-macro-error", "proc-macro2 1.0.85", @@ -2126,9 +2126,9 @@ dependencies = [ [[package]] name = "franklin-crypto" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77d90323407438ad4fc3385f2dc78f5e92aa4d67a03a08a8562396d68a07f96b" +checksum = "e35c05c35290529cf4704bf667777bda5d1b757d63445591cd19163ee0909df8" dependencies = [ "arr_macro", "bellman_ce 0.8.0", @@ -4507,7 +4507,7 @@ dependencies = [ "anyhow", "bincode", "chrono", - "circuit_definitions 0.150.2-rc.1", + "circuit_definitions 0.150.2-rc.2", "clap 4.5.4", "colored", "dialoguer", @@ -4518,7 +4518,7 @@ dependencies = [ "tokio", "tracing", "tracing-subscriber", - "zkevm_test_harness 0.150.2-rc.1", + "zkevm_test_harness 0.150.2-rc.2", "zksync_basic_types", "zksync_config", "zksync_contracts", @@ -4881,9 +4881,9 @@ dependencies = [ [[package]] name = "rescue_poseidon" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50e3a9a33bb7d2a469247e4f5fc47f7ab87807cd603739d306fa84e06ca0a160" +checksum = "dcf8f3aca783485c92639215977a2219cf25ba26836d088d75a088e7cba842bf" dependencies = [ "addchain", "arrayvec 0.7.4", @@ -5605,15 +5605,15 @@ checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde" [[package]] name = "shivini" -version = "0.150.2-rc.1" +version = "0.150.2-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2e391df42e8e145b12d7c446acd0de300ccc964ee941f5b9013ec970811f70f" +checksum = "85c35f41f876fc986d18e02d97a20a6980ca108c28f77cc844406d1c9c1f6ed9" dependencies = [ "bincode", "blake2 0.10.6", "boojum", "boojum-cuda", - "circuit_definitions 0.150.2-rc.1", + "circuit_definitions 0.150.2-rc.2", "derivative", "era_cudart", "era_cudart_sys", @@ -5712,9 +5712,9 @@ dependencies = [ [[package]] name = "snark_wrapper" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6e57fa6c50ac36e39c58bf411aa5b9ca2f2a878c3da9769fb12736fc77ee346" +checksum = "b7dd2b167b67a0ec5b2727519bf7c03fcbd43edaa3ebf05a6013fb6fbfed20f6" dependencies = [ "derivative", "rand 0.4.6", @@ -6873,7 +6873,7 @@ version = "0.1.0" dependencies = [ "anyhow", "bincode", - "circuit_definitions 0.150.2-rc.1", + "circuit_definitions 0.150.2-rc.2", "clap 4.5.4", "hex", "indicatif", @@ -6890,7 +6890,7 @@ dependencies = [ "toml_edit 0.14.4", "tracing", "tracing-subscriber", - "zkevm_test_harness 0.150.2-rc.1", + "zkevm_test_harness 0.150.2-rc.2", "zksync_config", "zksync_env_config", "zksync_prover_fri_types", @@ -7488,9 +7488,9 @@ dependencies = [ [[package]] name = "zkevm_circuits" -version = "0.140.0" +version = "0.140.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db7061a85757529d06a9cb1c4697902bff16dfb303484499eeb5c7f20e1ac0d" +checksum = "806caf4ccbe34ac68193f7d0dd591d1d866d95a740fe45a358eaefd61c357d8e" dependencies = [ "arrayvec 0.7.4", "bincode", @@ -7510,9 +7510,9 @@ dependencies = [ [[package]] name = "zkevm_circuits" -version = "0.141.0" +version = "0.141.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25e0f6e554b88310ad3b086e5334fbebe27154674a91c91643241b64c3d05b3a" +checksum = "20f1a64d256cc5f5c58d19cf976cb45973df54e4e3010ca4a3e6fafe9f06075e" dependencies = [ "arrayvec 0.7.4", "bincode", @@ -7532,9 +7532,9 @@ dependencies = [ [[package]] name = "zkevm_circuits" -version = "0.150.0" +version = "0.150.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4691ca0faeb666120ad48fb1a45750c5bacc90118a851f4450f3e1e903f9b2e3" +checksum = "e8a85c1987a1e7e89f1f8c39ca19bffb61521e719050086372aaea8817f403fc" dependencies = [ "arrayvec 0.7.4", "boojum", @@ -7611,12 +7611,12 @@ dependencies = [ [[package]] name = "zkevm_test_harness" -version = "0.140.0-gpu-wrapper.0" +version = "0.140.0-gpu-wrapper.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba6c5aaadac549dbc474a5d590d897548cb3587a119d9e48b8014cd4b6dc0bcc" +checksum = "3dbcf39f7cdd57174c572f227ae46513d2111faed7dc754e300465200e9b791a" dependencies = [ "bincode", - "circuit_definitions 0.140.0-gpu-wrapper.0", + "circuit_definitions 0.140.0-gpu-wrapper.1", "codegen", "crossbeam 0.8.4", "derivative", @@ -7635,13 +7635,13 @@ dependencies = [ [[package]] name = "zkevm_test_harness" -version = "0.150.2-rc.1" +version = "0.150.2-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fdbf14a5793a23aec1b315680b152413a477c8243b7c23a9acf743471b313e4" +checksum = "ca2ca25fe64b0dee537ba226983a1f8ca7f8bd4ce82e5d58eb4522252fbe40a6" dependencies = [ "bincode", - "circuit_definitions 0.150.2-rc.1", - "circuit_sequencer_api 0.150.2-rc.1", + "circuit_definitions 0.150.2-rc.2", + "circuit_sequencer_api 0.150.2-rc.2", "codegen", "crossbeam 0.8.4", "derivative", @@ -7662,9 +7662,9 @@ dependencies = [ [[package]] name = "zksync-gpu-ffi" -version = "0.140.0-gpu-wrapper.0" +version = "0.140.0-gpu-wrapper.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7bff4168aca5a3b1ee07abf23f7af95c48b78c50e0c8dac3a383c834eb020300" +checksum = "cebf6d2f7102b2b4f3bf14d6dfd8c520f95621b180bc4bbfd07ee53093336205" dependencies = [ "bindgen 0.59.2", "crossbeam 0.8.4", @@ -7676,9 +7676,9 @@ dependencies = [ [[package]] name = "zksync-gpu-prover" -version = "0.140.0-gpu-wrapper.0" +version = "0.140.0-gpu-wrapper.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e2ee87fbdf2f52de4b22bd5f1004c6323f8a524eadc571a4d5d1a16cfd9c102" +checksum = "502acf81d04b5fad616e01ff7c913285da21ce88d17cd1a083a0d3f25cc27b27" dependencies = [ "bit-vec", "cfg-if 1.0.0", @@ -7693,12 +7693,12 @@ dependencies = [ [[package]] name = "zksync-wrapper-prover" -version = "0.140.0-gpu-wrapper.0" +version = "0.140.0-gpu-wrapper.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59606513a9d32195b62c775141483da0eda06181d0571e9bd537e679308156d2" +checksum = "99746d1164f60d788f9701b7146ad2878c92f1ffd463ea5b6d72f9979ac464b7" dependencies = [ - "circuit_definitions 0.140.0-gpu-wrapper.0", - "zkevm_test_harness 0.140.0-gpu-wrapper.0", + "circuit_definitions 0.140.0-gpu-wrapper.1", + "zkevm_test_harness 0.140.0-gpu-wrapper.1", "zksync-gpu-prover", ] @@ -7981,9 +7981,9 @@ dependencies = [ [[package]] name = "zksync_kzg" -version = "0.150.2-rc.1" +version = "0.150.2-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4672556b6bc06da9dcd38a607e139b8eb3083edfaabcd12981e8a62051ee1f81" +checksum = "c44edd3a3316dcab45aab7e190c96150f2586d4a92fa21f93dcc20178308313a" dependencies = [ "boojum", "derivative", @@ -7993,7 +7993,7 @@ dependencies = [ "serde", "serde_json", "serde_with", - "zkevm_circuits 0.150.0", + "zkevm_circuits 0.150.1", ] [[package]] @@ -8031,9 +8031,9 @@ dependencies = [ "anyhow", "circuit_sequencer_api 0.133.0", "circuit_sequencer_api 0.140.0", - "circuit_sequencer_api 0.141.0", + "circuit_sequencer_api 0.141.1", "circuit_sequencer_api 0.142.0", - "circuit_sequencer_api 0.150.2-rc.1", + "circuit_sequencer_api 0.150.2-rc.2", "hex", "itertools 0.10.5", "once_cell", @@ -8104,7 +8104,7 @@ dependencies = [ "anyhow", "async-trait", "bincode", - "circuit_sequencer_api 0.150.2-rc.1", + "circuit_sequencer_api 0.150.2-rc.2", "clap 4.5.4", "ctrlc", "futures 0.3.30", @@ -8116,7 +8116,7 @@ dependencies = [ "tracing", "vise", "vk_setup_data_generator_server_fri", - "zkevm_test_harness 0.150.2-rc.1", + "zkevm_test_harness 0.150.2-rc.2", "zksync-wrapper-prover", "zksync_config", "zksync_core_leftovers", @@ -8204,7 +8204,7 @@ version = "0.1.0" dependencies = [ "anyhow", "async-trait", - "circuit_definitions 0.150.2-rc.1", + "circuit_definitions 0.150.2-rc.2", "clap 4.5.4", "ctrlc", "futures 0.3.30", @@ -8217,7 +8217,7 @@ dependencies = [ "tracing", "vise", "vk_setup_data_generator_server_fri", - "zkevm_test_harness 0.150.2-rc.1", + "zkevm_test_harness 0.150.2-rc.2", "zksync_config", "zksync_core_leftovers", "zksync_env_config", @@ -8261,7 +8261,7 @@ dependencies = [ name = "zksync_prover_fri_types" version = "0.1.0" dependencies = [ - "circuit_definitions 0.150.2-rc.1", + "circuit_definitions 0.150.2-rc.2", "serde", "zksync_object_store", "zksync_types", @@ -8290,7 +8290,7 @@ name = "zksync_prover_interface" version = "0.1.0" dependencies = [ "chrono", - "circuit_sequencer_api 0.150.2-rc.1", + "circuit_sequencer_api 0.150.2-rc.2", "serde", "serde_with", "strum", @@ -8473,7 +8473,7 @@ dependencies = [ "anyhow", "async-trait", "bincode", - "circuit_definitions 0.150.2-rc.1", + "circuit_definitions 0.150.2-rc.2", "const-decoder", "ctrlc", "futures 0.3.30", @@ -8487,7 +8487,7 @@ dependencies = [ "tracing", "vise", "vk_setup_data_generator_server_fri", - "zkevm_test_harness 0.150.2-rc.1", + "zkevm_test_harness 0.150.2-rc.2", "zksync_config", "zksync_core_leftovers", "zksync_env_config", diff --git a/prover/Cargo.toml b/prover/Cargo.toml index 6c7919e20546..4dfc77432979 100644 --- a/prover/Cargo.toml +++ b/prover/Cargo.toml @@ -56,13 +56,13 @@ tracing-subscriber = { version = "0.3" } vise = "0.1.0" # Proving dependencies -circuit_definitions = "=0.150.2-rc.1" -circuit_sequencer_api = "=0.150.2-rc.1" -zkevm_test_harness = "=0.150.2-rc.1" +circuit_definitions = "=0.150.2-rc.2" +circuit_sequencer_api = "=0.150.2-rc.2" +zkevm_test_harness = "=0.150.2-rc.2" # GPU proving dependencies -wrapper_prover = { package = "zksync-wrapper-prover", version = "=0.140.0-gpu-wrapper.0" } -shivini = "=0.150.2-rc.1" +wrapper_prover = { package = "zksync-wrapper-prover", version = "=0.140.0-gpu-wrapper.1" } +shivini = "=0.150.2-rc.2" # Core workspace dependencies zksync_multivm = { path = "../core/lib/multivm", version = "0.1.0" } diff --git a/prover/crates/bin/witness_generator/src/leaf_aggregation.rs b/prover/crates/bin/witness_generator/src/leaf_aggregation.rs index b0eff0f100e1..00546a11407e 100644 --- a/prover/crates/bin/witness_generator/src/leaf_aggregation.rs +++ b/prover/crates/bin/witness_generator/src/leaf_aggregation.rs @@ -3,8 +3,11 @@ use std::{sync::Arc, time::Instant}; use anyhow::Context as _; use async_trait::async_trait; use circuit_definitions::circuit_definitions::recursion_layer::base_circuit_type_into_recursive_leaf_circuit_type; +use tokio::sync::Semaphore; use zkevm_test_harness::{ - witness::recursive_aggregation::{compute_leaf_params, create_leaf_witnesses}, + witness::recursive_aggregation::{ + compute_leaf_params, create_leaf_witness, split_recursion_queue, + }, zkevm_circuits::scheduler::aux::BaseLayerCircuitType, }; use zksync_config::configs::FriWitnessGeneratorConfig; @@ -13,12 +16,8 @@ use zksync_prover_dal::{ConnectionPool, Prover, ProverDal}; use zksync_prover_fri_types::{ circuit_definitions::{ boojum::field::goldilocks::GoldilocksField, - circuit_definitions::{ - base_layer::{ - ZkSyncBaseLayerClosedFormInput, ZkSyncBaseLayerProof, - ZkSyncBaseLayerVerificationKey, - }, - recursion_layer::ZkSyncRecursiveLayerCircuit, + circuit_definitions::base_layer::{ + ZkSyncBaseLayerClosedFormInput, ZkSyncBaseLayerVerificationKey, }, encodings::recursion_request::RecursionQueueSimulator, zkevm_circuits::recursion::leaf_layer::input::RecursionLeafParametersWitness, @@ -46,11 +45,8 @@ use crate::{ pub struct LeafAggregationArtifacts { circuit_id: u8, block_number: L1BatchNumber, - pub aggregations: Vec<( - u64, - RecursionQueueSimulator, - ZkSyncRecursiveLayerCircuit, - )>, + pub aggregations: Vec<(u64, RecursionQueueSimulator)>, + pub circuit_ids_and_urls: Vec<(u8, String)>, #[allow(dead_code)] closed_form_inputs: Vec>, } @@ -65,7 +61,7 @@ pub struct LeafAggregationWitnessGeneratorJob { pub(crate) circuit_id: u8, pub(crate) block_number: L1BatchNumber, pub(crate) closed_form_inputs: ClosedFormInputWrapper, - pub(crate) proofs: Vec, + pub(crate) proofs_ids: Vec, pub(crate) base_vk: ZkSyncBaseLayerVerificationKey, pub(crate) leaf_params: RecursionLeafParametersWitness, } @@ -97,9 +93,11 @@ impl LeafAggregationWitnessGenerator { skip_all, fields(l1_batch = %leaf_job.block_number, circuit_id = %leaf_job.circuit_id) )] - pub fn process_job_sync( + pub async fn process_job_impl( leaf_job: LeafAggregationWitnessGeneratorJob, started_at: Instant, + object_store: Arc, + max_circuits_in_flight: usize, ) -> LeafAggregationArtifacts { tracing::info!( "Starting witness generation of type {:?} for block {} with circuit {}", @@ -107,7 +105,8 @@ impl LeafAggregationWitnessGenerator { leaf_job.block_number.0, leaf_job.circuit_id, ); - process_leaf_aggregation_job(started_at, leaf_job) + process_leaf_aggregation_job(started_at, leaf_job, object_store, max_circuits_in_flight) + .await } } @@ -155,7 +154,11 @@ impl JobProcessor for LeafAggregationWitnessGenerator { job: LeafAggregationWitnessGeneratorJob, started_at: Instant, ) -> tokio::task::JoinHandle> { - tokio::task::spawn_blocking(move || Ok(Self::process_job_sync(job, started_at))) + let object_store = self.object_store.clone(); + let max_circuits_in_flight = self.config.max_circuits_in_flight; + tokio::spawn(async move { + Ok(Self::process_job_impl(job, started_at, object_store, max_circuits_in_flight).await) + }) } async fn save_result( @@ -219,7 +222,6 @@ pub async fn prepare_leaf_aggregation_job( ) -> anyhow::Result { let started_at = Instant::now(); let closed_form_input = get_artifacts(&metadata, object_store).await; - let proofs = load_proofs_for_job_ids(&metadata.prover_job_ids_for_proofs, object_store).await; WITNESS_GENERATOR_METRICS.blob_fetch_time[&AggregationRound::LeafAggregation.into()] .observe(started_at.elapsed()); @@ -237,15 +239,6 @@ pub async fn prepare_leaf_aggregation_job( let leaf_vk = keystore .load_recursive_layer_verification_key(leaf_circuit_id) .context("get_recursive_layer_vk_for_circuit_type()")?; - let mut base_proofs = vec![]; - for wrapper in proofs { - match wrapper { - FriProofWrapper::Base(base_proof) => base_proofs.push(base_proof), - FriProofWrapper::Recursive(_) => { - anyhow::bail!("Expected only base proofs for leaf agg {}", metadata.id); - } - } - } let leaf_params = compute_leaf_params(metadata.circuit_id, base_vk.clone(), leaf_vk); WITNESS_GENERATOR_METRICS.prepare_job_time[&AggregationRound::LeafAggregation.into()] @@ -255,7 +248,7 @@ pub async fn prepare_leaf_aggregation_job( circuit_id: metadata.circuit_id, block_number: metadata.block_number, closed_form_inputs: closed_form_input, - proofs: base_proofs, + proofs_ids: metadata.prover_job_ids_for_proofs, base_vk, leaf_params, }) @@ -265,19 +258,93 @@ pub async fn prepare_leaf_aggregation_job( skip_all, fields(l1_batch = %job.block_number, circuit_id = %job.circuit_id) )] -pub fn process_leaf_aggregation_job( +pub async fn process_leaf_aggregation_job( started_at: Instant, job: LeafAggregationWitnessGeneratorJob, + object_store: Arc, + max_circuits_in_flight: usize, ) -> LeafAggregationArtifacts { let circuit_id = job.circuit_id; - let subsets = ( - circuit_id as u64, - job.closed_form_inputs.1, - job.closed_form_inputs.0, - ); - let leaf_params = (circuit_id, job.leaf_params); - let (aggregations, closed_form_inputs) = - create_leaf_witnesses(subsets, job.proofs, job.base_vk, leaf_params); + let queues = split_recursion_queue(job.closed_form_inputs.1); + + let aggregations = queues + .iter() + .cloned() + .map(|queue| (circuit_id as u64, queue)) + .collect(); + + let mut proof_ids_iter = job.proofs_ids.into_iter(); + let mut proofs_ids = vec![]; + for queue in queues.iter() { + let proofs_ids_for_queue: Vec<_> = (&mut proof_ids_iter) + .take(queue.num_items as usize) + .collect(); + assert_eq!(queue.num_items as usize, proofs_ids_for_queue.len()); + proofs_ids.push(proofs_ids_for_queue); + } + + let semaphore = Arc::new(Semaphore::new(max_circuits_in_flight)); + + let mut handles = vec![]; + for (circuit_idx, (queue, proofs_ids_for_queue)) in + queues.into_iter().zip(proofs_ids).enumerate() + { + let semaphore = semaphore.clone(); + + let object_store = object_store.clone(); + let queue = queue.clone(); + let base_vk = job.base_vk.clone(); + let leaf_params = (circuit_id, job.leaf_params.clone()); + + let handle = tokio::task::spawn(async move { + let _permit = semaphore + .acquire() + .await + .expect("failed to get permit to process queues chunk"); + + let proofs = load_proofs_for_job_ids(&proofs_ids_for_queue, &*object_store).await; + let base_proofs = proofs + .into_iter() + .map(|wrapper| match wrapper { + FriProofWrapper::Base(base_proof) => base_proof, + FriProofWrapper::Recursive(_) => { + panic!( + "Expected only base proofs for leaf agg {} {}", + job.circuit_id, job.block_number + ); + } + }) + .collect(); + + let (_, circuit) = create_leaf_witness( + circuit_id.into(), + queue, + base_proofs, + &base_vk, + &leaf_params, + ); + + save_recursive_layer_prover_input_artifacts( + job.block_number, + circuit_idx, + vec![circuit], + AggregationRound::LeafAggregation, + 0, + &*object_store, + None, + ) + .await + }); + + handles.push(handle); + } + + let circuit_ids_and_urls_results = futures::future::join_all(handles).await; + let circuit_ids_and_urls = circuit_ids_and_urls_results + .into_iter() + .flat_map(|x| x.unwrap()) + .collect(); + WITNESS_GENERATOR_METRICS.witness_generation_time[&AggregationRound::LeafAggregation.into()] .observe(started_at.elapsed()); @@ -292,7 +359,8 @@ pub fn process_leaf_aggregation_job( circuit_id, block_number: job.block_number, aggregations, - closed_form_inputs, + circuit_ids_and_urls, + closed_form_inputs: job.closed_form_inputs.0, } } @@ -405,24 +473,15 @@ async fn save_artifacts( artifacts.block_number, get_recursive_layer_circuit_id_for_base_layer(artifacts.circuit_id), 0, - artifacts.aggregations.clone(), - object_store, - ) - .await; - let circuit_ids_and_urls = save_recursive_layer_prover_input_artifacts( - artifacts.block_number, artifacts.aggregations, - AggregationRound::LeafAggregation, - 0, object_store, - None, ) .await; WITNESS_GENERATOR_METRICS.blob_save_time[&AggregationRound::LeafAggregation.into()] .observe(started_at.elapsed()); BlobUrls { - circuit_ids_and_urls, + circuit_ids_and_urls: artifacts.circuit_ids_and_urls, aggregations_urls, } } diff --git a/prover/crates/bin/witness_generator/src/node_aggregation.rs b/prover/crates/bin/witness_generator/src/node_aggregation.rs index b49928d6d27b..ec6d011f8644 100644 --- a/prover/crates/bin/witness_generator/src/node_aggregation.rs +++ b/prover/crates/bin/witness_generator/src/node_aggregation.rs @@ -2,8 +2,10 @@ use std::{sync::Arc, time::Instant}; use anyhow::Context as _; use async_trait::async_trait; +use circuit_definitions::circuit_definitions::recursion_layer::RECURSION_ARITY; +use tokio::sync::Semaphore; use zkevm_test_harness::witness::recursive_aggregation::{ - compute_node_vk_commitment, create_node_witnesses, + compute_node_vk_commitment, create_node_witness, }; use zksync_config::configs::FriWitnessGeneratorConfig; use zksync_object_store::ObjectStore; @@ -12,8 +14,7 @@ use zksync_prover_fri_types::{ circuit_definitions::{ boojum::field::goldilocks::GoldilocksField, circuit_definitions::recursion_layer::{ - ZkSyncRecursionLayerProof, ZkSyncRecursionLayerStorageType, - ZkSyncRecursionLayerVerificationKey, ZkSyncRecursiveLayerCircuit, + ZkSyncRecursionLayerStorageType, ZkSyncRecursionLayerVerificationKey, }, encodings::recursion_request::RecursionQueueSimulator, zkevm_circuits::recursion::leaf_layer::input::RecursionLeafParametersWitness, @@ -41,11 +42,8 @@ pub struct NodeAggregationArtifacts { circuit_id: u8, block_number: L1BatchNumber, depth: u16, - pub next_aggregations: Vec<( - u64, - RecursionQueueSimulator, - ZkSyncRecursiveLayerCircuit, - )>, + pub next_aggregations: Vec<(u64, RecursionQueueSimulator)>, + pub recursive_circuit_ids_and_urls: Vec<(u8, String)>, } #[derive(Debug)] @@ -59,12 +57,8 @@ pub struct NodeAggregationWitnessGeneratorJob { circuit_id: u8, block_number: L1BatchNumber, depth: u16, - aggregations: Vec<( - u64, - RecursionQueueSimulator, - ZkSyncRecursiveLayerCircuit, - )>, - proofs: Vec, + aggregations: Vec<(u64, RecursionQueueSimulator)>, + proofs_ids: Vec, leaf_vk: ZkSyncRecursionLayerVerificationKey, node_vk: ZkSyncRecursionLayerVerificationKey, all_leafs_layer_params: Vec<(u8, RecursionLeafParametersWitness)>, @@ -97,9 +91,11 @@ impl NodeAggregationWitnessGenerator { skip_all, fields(l1_batch = %job.block_number, circuit_id = %job.circuit_id) )] - pub fn process_job_sync( + pub async fn process_job_impl( job: NodeAggregationWitnessGeneratorJob, started_at: Instant, + object_store: Arc, + max_circuits_in_flight: usize, ) -> NodeAggregationArtifacts { let node_vk_commitment = compute_node_vk_commitment(job.node_vk.clone()); tracing::info!( @@ -113,13 +109,103 @@ impl NodeAggregationWitnessGenerator { 0 => job.leaf_vk, _ => job.node_vk, }; - let next_aggregations = create_node_witnesses( - job.aggregations, - job.proofs, - vk, - node_vk_commitment, - &job.all_leafs_layer_params, + + let mut proof_ids_iter = job.proofs_ids.into_iter(); + let mut proofs_ids = vec![]; + for queues in job.aggregations.chunks(RECURSION_ARITY) { + let mut proofs_for_chunk = vec![]; + for (_, queue) in queues { + let proofs_ids_for_queue: Vec<_> = (&mut proof_ids_iter) + .take(queue.num_items as usize) + .collect(); + assert_eq!(queue.num_items as usize, proofs_ids_for_queue.len()); + proofs_for_chunk.extend(proofs_ids_for_queue); + } + proofs_ids.push(proofs_for_chunk); + } + + assert_eq!( + job.aggregations.chunks(RECURSION_ARITY).len(), + proofs_ids.len() ); + + let semaphore = Arc::new(Semaphore::new(max_circuits_in_flight)); + + let mut handles = vec![]; + for (circuit_idx, (chunk, proofs_ids_for_chunk)) in job + .aggregations + .chunks(RECURSION_ARITY) + .zip(proofs_ids) + .enumerate() + { + let semaphore = semaphore.clone(); + + let object_store = object_store.clone(); + let chunk = Vec::from(chunk); + let vk = vk.clone(); + let all_leafs_layer_params = job.all_leafs_layer_params.clone(); + + let handle = tokio::task::spawn(async move { + let _permit = semaphore + .acquire() + .await + .expect("failed to get permit to process queues chunk"); + + let proofs = load_proofs_for_job_ids(&proofs_ids_for_chunk, &*object_store).await; + let mut recursive_proofs = vec![]; + for wrapper in proofs { + match wrapper { + FriProofWrapper::Base(_) => { + panic!( + "Expected only recursive proofs for node agg {} {}", + job.circuit_id, job.block_number + ); + } + FriProofWrapper::Recursive(recursive_proof) => { + recursive_proofs.push(recursive_proof) + } + } + } + + let (result_circuit_id, recursive_circuit, input_queue) = create_node_witness( + &chunk, + recursive_proofs, + &vk, + node_vk_commitment, + &all_leafs_layer_params, + ); + + assert_eq!(job.circuit_id as u64, result_circuit_id); + + let recursive_circuit_id_and_url = save_recursive_layer_prover_input_artifacts( + job.block_number, + circuit_idx, + vec![recursive_circuit], + AggregationRound::NodeAggregation, + job.depth, + &*object_store, + Some(job.circuit_id), + ) + .await; + + ( + (result_circuit_id, input_queue), + recursive_circuit_id_and_url, + ) + }); + + handles.push(handle); + } + + let mut next_aggregations = vec![]; + let mut recursive_circuit_ids_and_urls = vec![]; + for handle in handles { + let (next_aggregation, recursive_circuit_id_and_url) = handle.await.unwrap(); + + next_aggregations.push(next_aggregation); + recursive_circuit_ids_and_urls.extend(recursive_circuit_id_and_url); + } + WITNESS_GENERATOR_METRICS.witness_generation_time [&AggregationRound::NodeAggregation.into()] .observe(started_at.elapsed()); @@ -138,6 +224,7 @@ impl NodeAggregationWitnessGenerator { block_number: job.block_number, depth: job.depth + 1, next_aggregations, + recursive_circuit_ids_and_urls, } } } @@ -186,7 +273,11 @@ impl JobProcessor for NodeAggregationWitnessGenerator { job: NodeAggregationWitnessGeneratorJob, started_at: Instant, ) -> tokio::task::JoinHandle> { - tokio::task::spawn_blocking(move || Ok(Self::process_job_sync(job, started_at))) + let object_store = self.object_store.clone(); + let max_circuits_in_flight = self.config.max_circuits_in_flight; + tokio::spawn(async move { + Ok(Self::process_job_impl(job, started_at, object_store, max_circuits_in_flight).await) + }) } #[tracing::instrument( @@ -247,7 +338,6 @@ pub async fn prepare_job( ) -> anyhow::Result { let started_at = Instant::now(); let artifacts = get_artifacts(&metadata, object_store).await; - let proofs = load_proofs_for_job_ids(&metadata.prover_job_ids_for_proofs, object_store).await; WITNESS_GENERATOR_METRICS.blob_fetch_time[&AggregationRound::NodeAggregation.into()] .observe(started_at.elapsed()); @@ -263,19 +353,6 @@ pub async fn prepare_job( ) .context("get_recursive_layer_vk_for_circuit_type()")?; - let mut recursive_proofs = vec![]; - for wrapper in proofs { - match wrapper { - FriProofWrapper::Base(_) => { - anyhow::bail!( - "Expected only recursive proofs for node agg {}", - metadata.id - ); - } - FriProofWrapper::Recursive(recursive_proof) => recursive_proofs.push(recursive_proof), - } - } - WITNESS_GENERATOR_METRICS.prepare_job_time[&AggregationRound::NodeAggregation.into()] .observe(started_at.elapsed()); @@ -284,7 +361,7 @@ pub async fn prepare_job( block_number: metadata.block_number, depth: metadata.depth, aggregations: artifacts.0, - proofs: recursive_proofs, + proofs_ids: metadata.prover_job_ids_for_proofs, leaf_vk, node_vk, all_leafs_layer_params: get_leaf_vk_params(&keystore).context("get_leaf_vk_params()")?, @@ -395,17 +472,8 @@ async fn save_artifacts( artifacts.block_number, artifacts.circuit_id, artifacts.depth, - artifacts.next_aggregations.clone(), - object_store, - ) - .await; - let circuit_ids_and_urls = save_recursive_layer_prover_input_artifacts( - artifacts.block_number, artifacts.next_aggregations, - AggregationRound::NodeAggregation, - artifacts.depth, object_store, - Some(artifacts.circuit_id), ) .await; @@ -414,6 +482,6 @@ async fn save_artifacts( BlobUrls { node_aggregations_url: aggregations_urls, - circuit_ids_and_urls, + circuit_ids_and_urls: artifacts.recursive_circuit_ids_and_urls, } } diff --git a/prover/crates/bin/witness_generator/src/utils.rs b/prover/crates/bin/witness_generator/src/utils.rs index 97991fbd4d04..c1fd5dd3b407 100644 --- a/prover/crates/bin/witness_generator/src/utils.rs +++ b/prover/crates/bin/witness_generator/src/utils.rs @@ -79,13 +79,7 @@ impl StoredObject for ClosedFormInputWrapper { } #[derive(serde::Serialize, serde::Deserialize)] -pub struct AggregationWrapper( - pub Vec<( - u64, - RecursionQueueSimulator, - ZkSyncRecursiveLayerCircuit, - )>, -); +pub struct AggregationWrapper(pub Vec<(u64, RecursionQueueSimulator)>); impl StoredObject for AggregationWrapper { const BUCKET: Bucket = Bucket::NodeAggregationWitnessJobsFri; @@ -154,22 +148,19 @@ pub async fn save_circuit( )] pub async fn save_recursive_layer_prover_input_artifacts( block_number: L1BatchNumber, - aggregations: Vec<( - u64, - RecursionQueueSimulator, - ZkSyncRecursiveLayerCircuit, - )>, + sequence_number_offset: usize, + recursive_circuits: Vec, aggregation_round: AggregationRound, depth: u16, object_store: &dyn ObjectStore, base_layer_circuit_id: Option, ) -> Vec<(u8, String)> { - let mut ids_and_urls = Vec::with_capacity(aggregations.len()); - for (sequence_number, (_, _, circuit)) in aggregations.into_iter().enumerate() { + let mut ids_and_urls = Vec::with_capacity(recursive_circuits.len()); + for (sequence_number, circuit) in recursive_circuits.into_iter().enumerate() { let circuit_id = base_layer_circuit_id.unwrap_or_else(|| circuit.numeric_circuit_type()); let circuit_key = FriCircuitKey { block_number, - sequence_number, + sequence_number: sequence_number_offset + sequence_number, circuit_id, aggregation_round, depth, @@ -191,11 +182,7 @@ pub async fn save_node_aggregations_artifacts( block_number: L1BatchNumber, circuit_id: u8, depth: u16, - aggregations: Vec<( - u64, - RecursionQueueSimulator, - ZkSyncRecursiveLayerCircuit, - )>, + aggregations: Vec<(u64, RecursionQueueSimulator)>, object_store: &dyn ObjectStore, ) -> String { let key = AggregationsKey { @@ -215,8 +202,8 @@ pub async fn load_proofs_for_job_ids( object_store: &dyn ObjectStore, ) -> Vec { let mut proofs = Vec::with_capacity(job_ids.len()); - for &job_id in job_ids { - proofs.push(object_store.get(job_id).await.unwrap()); + for job_id in job_ids { + proofs.push(object_store.get(*job_id).await.unwrap()); } proofs } diff --git a/prover/crates/bin/witness_generator/tests/basic_test.rs b/prover/crates/bin/witness_generator/tests/basic_test.rs index 7f5356858902..d9ac679ab647 100644 --- a/prover/crates/bin/witness_generator/tests/basic_test.rs +++ b/prover/crates/bin/witness_generator/tests/basic_test.rs @@ -3,9 +3,13 @@ use std::time::Instant; use serde::Serialize; use zksync_config::{configs::object_store::ObjectStoreMode, ObjectStoreConfig}; use zksync_object_store::ObjectStoreFactory; -use zksync_prover_fri_types::keys::AggregationsKey; +use zksync_prover_fri_types::{ + keys::{AggregationsKey, FriCircuitKey}, + CircuitWrapper, +}; use zksync_prover_fri_utils::get_recursive_layer_circuit_id_for_base_layer; use zksync_types::{ + basic_fri_types::AggregationRound, prover_dal::{LeafAggregationJobMetadata, NodeAggregationJobMetadata}, L1BatchNumber, }; @@ -25,6 +29,16 @@ fn compare_serialized(expected: &T, actual: &T) { #[tokio::test] #[ignore] // re-enable with new artifacts async fn test_leaf_witness_gen() { + let circuit_id = 4; + let block_number = L1BatchNumber(125010); + + let leaf_aggregation_job_metadata = LeafAggregationJobMetadata { + id: 1, + block_number, + circuit_id, + prover_job_ids_for_proofs: vec![4639043, 4639044, 4639045], + }; + let object_store_config = ObjectStoreConfig { mode: ObjectStoreMode::FileBacked { file_backed_base_path: "./tests/data/leaf/".to_owned(), @@ -37,30 +51,66 @@ async fn test_leaf_witness_gen() { .await .unwrap(); - let circuit_id = 4; - let block_number = L1BatchNumber(125010); - let key = AggregationsKey { + let job = prepare_leaf_aggregation_job(leaf_aggregation_job_metadata, &*object_store) + .await + .unwrap(); + + let artifacts = LeafAggregationWitnessGenerator::process_job_impl( + job, + Instant::now(), + object_store.clone(), + 500, + ) + .await; + + let aggregations = AggregationWrapper(artifacts.aggregations); + + let expected_results_object_store_config = ObjectStoreConfig { + mode: ObjectStoreMode::FileBacked { + file_backed_base_path: "./tests/expected_data/leaf/".to_owned(), + }, + max_retries: 5, + local_mirror_path: None, + }; + let expected_object_store = ObjectStoreFactory::new(expected_results_object_store_config) + .create_store() + .await + .unwrap(); + + for (idx, circuit_metadata) in artifacts.circuit_ids_and_urls.into_iter().enumerate() { + assert_eq!(circuit_id, circuit_metadata.0); + + let circuit_key = FriCircuitKey { + block_number, + sequence_number: idx, + circuit_id, + aggregation_round: AggregationRound::LeafAggregation, + depth: 0, + }; + + let result = object_store + .get::(circuit_key) + .await + .unwrap_or_else(|_| panic!("result circuit missing: {}", idx)); + + let expected_result = expected_object_store + .get::(circuit_key) + .await + .unwrap_or_else(|_| panic!("expected circuit missing: {}", idx)); + + compare_serialized(&expected_result, &result); + } + + let agg_key = AggregationsKey { block_number, circuit_id: get_recursive_layer_circuit_id_for_base_layer(circuit_id), depth: 0, }; - let expected_aggregation = object_store - .get::(key) + let expected_aggregation = expected_object_store + .get::(agg_key) .await .expect("expected aggregation missing"); - let leaf_aggregation_job_metadata = LeafAggregationJobMetadata { - id: 1, - block_number, - circuit_id, - prover_job_ids_for_proofs: vec![4639043, 4639044, 4639045], - }; - - let job = prepare_leaf_aggregation_job(leaf_aggregation_job_metadata, &*object_store) - .await - .unwrap(); - let artifacts = LeafAggregationWitnessGenerator::process_job_sync(job, Instant::now()); - let aggregations = AggregationWrapper(artifacts.aggregations); compare_serialized(&expected_aggregation, &aggregations); } @@ -81,15 +131,7 @@ async fn test_node_witness_gen() { let circuit_id = 8; let block_number = L1BatchNumber(127856); - let key = AggregationsKey { - block_number, - circuit_id, - depth: 1, - }; - let expected_aggregation = object_store - .get::(key) - .await - .expect("expected aggregation missing"); + let node_aggregation_job_metadata = NodeAggregationJobMetadata { id: 1, block_number, @@ -102,7 +144,64 @@ async fn test_node_witness_gen() { .await .unwrap(); - let artifacts = NodeAggregationWitnessGenerator::process_job_sync(job, Instant::now()); + let artifacts = NodeAggregationWitnessGenerator::process_job_impl( + job, + Instant::now(), + object_store.clone(), + 500, + ) + .await; let aggregations = AggregationWrapper(artifacts.next_aggregations); + + let expected_results_object_store_config = ObjectStoreConfig { + mode: ObjectStoreMode::FileBacked { + file_backed_base_path: "./tests/expected_data/leaf/".to_owned(), + }, + max_retries: 5, + local_mirror_path: None, + }; + let expected_object_store = ObjectStoreFactory::new(expected_results_object_store_config) + .create_store() + .await + .unwrap(); + + for (idx, circuit_metadata) in artifacts + .recursive_circuit_ids_and_urls + .into_iter() + .enumerate() + { + assert_eq!(circuit_id, circuit_metadata.0); + + let circuit_key = FriCircuitKey { + block_number, + sequence_number: idx, + circuit_id, + aggregation_round: AggregationRound::NodeAggregation, + depth: 0, + }; + + let result = object_store + .get::(circuit_key) + .await + .unwrap_or_else(|_| panic!("result circuit missing: {}", idx)); + + let expected_result = expected_object_store + .get::(circuit_key) + .await + .unwrap_or_else(|_| panic!("expected circuit missing: {}", idx)); + + compare_serialized(&expected_result, &result); + } + + let agg_key = AggregationsKey { + block_number, + circuit_id: get_recursive_layer_circuit_id_for_base_layer(circuit_id), + depth: 1, + }; + let expected_aggregation = expected_object_store + .get::(agg_key) + .await + .expect("expected aggregation missing"); + compare_serialized(&expected_aggregation, &aggregations); } From 75db9e626f1f2dce0715d038d45b291d2a72fe42 Mon Sep 17 00:00:00 2001 From: Danil Date: Fri, 2 Aug 2024 13:57:24 +0200 Subject: [PATCH 2/2] chore(release-plesae): add releases for zk toolbox (#2572) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## What ❔ ## Why ❔ ## Checklist - [ ] PR title corresponds to the body of PR (we generate changelog entries from PRs). - [ ] Tests for the changes have been added / updated. - [ ] Documentation comments have been added / updated. - [ ] Code has been formatted via `zk fmt` and `zk lint`. Signed-off-by: Danil --- .github/release-please/config.json | 35 +++++++++++++++++----------- .github/release-please/manifest.json | 3 ++- 2 files changed, 23 insertions(+), 15 deletions(-) diff --git a/.github/release-please/config.json b/.github/release-please/config.json index ec6df305d0e1..9f51e66c41ca 100644 --- a/.github/release-please/config.json +++ b/.github/release-please/config.json @@ -5,20 +5,27 @@ "bump-minor-pre-major": true, "bump-patch-for-minor-pre-major": true, "include-component-in-tag": true, + "plugins": [ + "cargo-workspace" + ], "packages": { - "core": { - "release-type": "simple", - "component": "core", - "extra-files": [ - { - "type": "generic", - "path": "bin/external_node/Cargo.toml" - } - ] - }, - "prover": { - "release-type": "simple", - "component": "prover" - } + "core": { + "release-type": "simple", + "component": "core", + "extra-files": [ + { + "type": "generic", + "path": "bin/external_node/Cargo.toml" + } + ] + }, + "prover": { + "release-type": "simple", + "component": "prover" + }, + "zk_toolbox": { + "release-type": "cargo-workspace", + "component": "zk_toolbox" + } } } diff --git a/.github/release-please/manifest.json b/.github/release-please/manifest.json index 74e984a0aaea..f36ff5681010 100644 --- a/.github/release-please/manifest.json +++ b/.github/release-please/manifest.json @@ -1,4 +1,5 @@ { "core": "24.14.0", - "prover": "16.1.0" + "prover": "16.1.0", + "zk_toolbox": "0.1.0" }