From 60ca6c56e8a109e41e94391b8ff9272cfea60095 Mon Sep 17 00:00:00 2001 From: BGluth Date: Tue, 26 Mar 2024 10:18:05 -0600 Subject: [PATCH 01/29] Updated `.gitignore` to ignore generated plonky2 state --- .gitignore | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitignore b/.gitignore index 82b38c19..42acc248 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,7 @@ circuits/ # Folders containing logs from the utility scripts in tools/ debug/ proofs/ + +# Serialized generated prover & verifier state used by plonky2 +prover_state_* +verifier_state_* From 60f258d49106c2356536a90588820d9719cd24ea Mon Sep 17 00:00:00 2001 From: Robin Salen <30937548+Nashtare@users.noreply.github.com> Date: Thu, 28 Mar 2024 21:41:12 +0900 Subject: [PATCH 02/29] Update prover default features (#46) * Update Cargo.toml Remove test-only from default features. * Fix Literal(proof) * Fix Clippy --------- Co-authored-by: Linda Guiga --- prover/Cargo.toml | 2 +- prover/src/lib.rs | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/prover/Cargo.toml b/prover/Cargo.toml index ca0cb86c..fc7fd24e 100644 --- a/prover/Cargo.toml +++ b/prover/Cargo.toml @@ -22,5 +22,5 @@ futures = { workspace = true } ops = { path = "../ops" } [features] -default = ["test_only"] +default = [] test_only = ["ops/test_only"] \ No newline at end of file diff --git a/prover/src/lib.rs b/prover/src/lib.rs index 0789423e..abf424a9 100644 --- a/prover/src/lib.rs +++ b/prover/src/lib.rs @@ -1,5 +1,6 @@ use anyhow::Result; use ethereum_types::U256; +#[cfg(feature = "test_only")] use futures::stream::TryStreamExt; use ops::TxProof; use paladin::{ @@ -56,7 +57,7 @@ impl ProverInput { intern: p, }); - let block_proof = paladin::Literal(proof) + let block_proof = paladin::directive::Literal(proof) .map(&ops::BlockProof { prev }) .run(runtime) .await?; From 34de9d89a6e9af5d9142e4672fd7d6978c26d4d1 Mon Sep 17 00:00:00 2001 From: Vladimir Trifonov Date: Tue, 2 Apr 2024 14:44:47 +0300 Subject: [PATCH 03/29] feat: add circuit version consistency check --- Cargo.lock | 60 +++++++++++++++++++++++--- common/src/prover_state/persistence.rs | 13 ++++-- leader/Cargo.toml | 1 + leader/src/main.rs | 13 ++++++ leader/src/utils.rs | 34 +++++++++++++++ 5 files changed, 110 insertions(+), 11 deletions(-) create mode 100644 leader/src/utils.rs diff --git a/Cargo.lock b/Cargo.lock index a74908cb..f0790de9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1833,6 +1833,7 @@ dependencies = [ "serde_json", "serde_path_to_error", "tokio", + "toml", "tracing", "tracing-subscriber", ] @@ -2480,12 +2481,11 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "2.0.2" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b00f26d3400549137f92511a46ac1cd8ce37cb5598a96d382381458b992a5d24" +checksum = "7e8366a6159044a37876a2b9817124296703c586a5c92e2c53751fa06d8d43e8" dependencies = [ - "toml_datetime", - "toml_edit", + "toml_edit 0.20.2", ] [[package]] @@ -2976,6 +2976,15 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_spanned" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1" +dependencies = [ + "serde", +] + [[package]] name = "serde_urlencoded" version = "0.7.1" @@ -3400,11 +3409,26 @@ dependencies = [ "tracing", ] +[[package]] +name = "toml" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9dd1545e8208b4a5af1aa9bbd0b4cf7e9ea08fabc5d0a5c67fcaafa17433aa3" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit 0.22.9", +] + [[package]] name = "toml_datetime" -version = "0.6.3" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" +checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" +dependencies = [ + "serde", +] [[package]] name = "toml_edit" @@ -3414,7 +3438,20 @@ checksum = "396e4d48bbb2b7554c944bde63101b5ae446cff6ec4a24227428f15eb72ef338" dependencies = [ "indexmap 2.2.5", "toml_datetime", - "winnow", + "winnow 0.5.40", +] + +[[package]] +name = "toml_edit" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e40bb779c5187258fd7aad0eb68cb8706a0a81fa712fbea808ab43c4b8374c4" +dependencies = [ + "indexmap 2.2.5", + "serde", + "serde_spanned", + "toml_datetime", + "winnow 0.6.5", ] [[package]] @@ -3948,6 +3985,15 @@ dependencies = [ "memchr", ] +[[package]] +name = "winnow" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dffa400e67ed5a4dd237983829e66475f0a4a26938c4b04c21baede6262215b8" +dependencies = [ + "memchr", +] + [[package]] name = "winreg" version = "0.50.0" diff --git a/common/src/prover_state/persistence.rs b/common/src/prover_state/persistence.rs index 94c6fc92..cd33b04e 100644 --- a/common/src/prover_state/persistence.rs +++ b/common/src/prover_state/persistence.rs @@ -1,3 +1,4 @@ +use std::env; use std::{ fmt::{Debug, Display}, fs::{self, OpenOptions}, @@ -102,9 +103,10 @@ impl DiskResource for BaseProverResource { fn path(p: &Self::PathConstrutor) -> impl AsRef { format!( - "{}/{}_base_{}", + "{}/{}_base_{}_{}", CIRCUITS_FOLDER, PROVER_STATE_FILE_PREFIX, + env::var("EVM_ARITHMETIZATION_PKG_VER").unwrap_or("NA".to_string()), p.get_configuration_digest() ) } @@ -137,9 +139,10 @@ impl DiskResource for MonolithicProverResource { fn path(p: &Self::PathConstrutor) -> impl AsRef { format!( - "{}/{}_monolithic_{}", + "{}/{}_monolithic_{}_{}", CIRCUITS_FOLDER, PROVER_STATE_FILE_PREFIX, + env::var("EVM_ARITHMETIZATION_PKG_VER").unwrap_or("NA".to_string()), p.get_configuration_digest() ) } @@ -171,9 +174,10 @@ impl DiskResource for RecursiveCircuitResource { fn path((circuit_type, size): &Self::PathConstrutor) -> impl AsRef { format!( - "{}/{}_{}_{}", + "{}/{}_{}_{}_{}", CIRCUITS_FOLDER, PROVER_STATE_FILE_PREFIX, + env::var("EVM_ARITHMETIZATION_PKG_VER").unwrap_or("NA".to_string()), circuit_type.as_short_str(), size ) @@ -214,9 +218,10 @@ impl DiskResource for VerifierResource { fn path(p: &Self::PathConstrutor) -> impl AsRef { format!( - "{}/{}_{}", + "{}/{}_{}_{}", CIRCUITS_FOLDER, VERIFIER_STATE_FILE_PREFIX, + env::var("EVM_ARITHMETIZATION_PKG_VER").unwrap_or("NA".to_string()), p.get_configuration_digest() ) } diff --git a/leader/Cargo.toml b/leader/Cargo.toml index 5c7bcc92..de39328a 100644 --- a/leader/Cargo.toml +++ b/leader/Cargo.toml @@ -22,6 +22,7 @@ serde_json = { workspace = true } serde_path_to_error = { workspace = true } ethereum-types = { workspace = true } axum = "0.7.4" +toml = "0.8.12" # Local dependencies ops = { path = "../ops" } diff --git a/leader/src/main.rs b/leader/src/main.rs index 36d2f1e3..7cc9db8c 100644 --- a/leader/src/main.rs +++ b/leader/src/main.rs @@ -1,3 +1,4 @@ +use std::env; use std::{fs::File, path::PathBuf}; use anyhow::Result; @@ -9,11 +10,14 @@ use ops::register; use paladin::runtime::Runtime; use proof_gen::types::PlonkyProofIntern; +use crate::utils::get_package_version; + mod cli; mod http; mod init; mod jerigon; mod stdio; +mod utils; fn get_previous_proof(path: Option) -> Result> { if path.is_none() { @@ -32,6 +36,15 @@ async fn main() -> Result<()> { dotenv().ok(); init::tracing(); + if env::var("EVM_ARITHMETIZATION_PKG_VER").is_err() { + let pkg_ver = get_package_version("evm_arithmetization")?; + // Set the environment variable for the evm_arithmetization package version + env::set_var( + "EVM_ARITHMETIZATION_PKG_VER", + pkg_ver.unwrap_or("NA".to_string()), + ); + } + let args = cli::Cli::parse(); if let paladin::config::Runtime::InMemory = args.paladin.runtime { // If running in emulation mode, we'll need to initialize the prover diff --git a/leader/src/utils.rs b/leader/src/utils.rs new file mode 100644 index 00000000..3a9a1ef3 --- /dev/null +++ b/leader/src/utils.rs @@ -0,0 +1,34 @@ +use std::fs::File; +use std::io::{BufReader, Read}; +use std::path::Path; + +use anyhow::Result; + +pub(crate) fn get_package_version(package_name: &str) -> Result> { + let manifest_dir = env!("CARGO_MANIFEST_DIR"); + let zero_bin_path = Path::new(manifest_dir) + .join("../") // Adjust the path according to your workspace structure + .canonicalize()?; + + let cargo_lock_path = zero_bin_path.join("Cargo.lock"); + let cargo_lock_file = File::open(cargo_lock_path); + if cargo_lock_file.is_err() { + return Ok(None); + } + + let mut cargo_lock_contents = String::new(); + BufReader::new(cargo_lock_file?).read_to_string(&mut cargo_lock_contents)?; + + let lockfile: toml::Value = toml::from_str(&cargo_lock_contents)?; + if let Some(package) = lockfile["package"] + .as_array() + .unwrap() + .iter() + .find(|&p| p["name"].as_str() == Some(package_name)) + { + let version = package["version"].as_str().unwrap(); + return Ok(Some(version.to_string())); + } + + Ok(None) +} From 995f706c05f7ce87f5a7d7ca6064db53c507fa6a Mon Sep 17 00:00:00 2001 From: Vladimir Trifonov Date: Wed, 3 Apr 2024 16:30:28 +0300 Subject: [PATCH 04/29] fix: use circuits code digests instead of evm_arithmetization pkg version for circuits consistency check --- Cargo.lock | 90 +++++++------------------- Cargo.toml | 6 +- common/Cargo.toml | 1 + common/src/prover_state/mod.rs | 29 +++++++-- common/src/prover_state/persistence.rs | 15 ++--- common/src/prover_state/utils.rs | 86 ++++++++++++++++++++++++ leader/Cargo.toml | 1 - leader/src/main.rs | 13 ---- leader/src/utils.rs | 34 ---------- 9 files changed, 142 insertions(+), 133 deletions(-) create mode 100644 common/src/prover_state/utils.rs delete mode 100644 leader/src/utils.rs diff --git a/Cargo.lock b/Cargo.lock index f0790de9..d0c1ac3f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -640,6 +640,7 @@ dependencies = [ "evm_arithmetization", "plonky2", "proof_gen", + "seahash", "thiserror", "trace_decoder", "tracing", @@ -1033,9 +1034,8 @@ dependencies = [ [[package]] name = "evm_arithmetization" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8460fed1dc1b098aab4dd9f5b7a2281423f2cd078393284ce1edbf13d49b55c" +version = "0.1.3" +source = "git+https://github.com/0xPolygonZero/zk_evm.git?tag=v0.3.0#423e2614d31d323e950b4a461a27ef565a820b75" dependencies = [ "anyhow", "bytes", @@ -1833,7 +1833,6 @@ dependencies = [ "serde_json", "serde_path_to_error", "tokio", - "toml", "tracing", "tracing-subscriber", ] @@ -1948,9 +1947,8 @@ dependencies = [ [[package]] name = "mpt_trie" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "276984ee63f94fab7907336095c1ff0d6a9117d8c42291564f79101ac275037b" +version = "0.2.1" +source = "git+https://github.com/0xPolygonZero/zk_evm.git?tag=v0.3.0#423e2614d31d323e950b4a461a27ef565a820b75" dependencies = [ "bytes", "enum-as-inner", @@ -2348,9 +2346,9 @@ dependencies = [ [[package]] name = "plonky2" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b25deb9a4b9c2014c2f99cd36078f30e453d188d0ca8dd4c5ffd1d494b661ac1" +checksum = "d04c7dfa293cd62a8e1e3f21157dba8508ab2de6078b0e5fae202a4fc98ef224" dependencies = [ "ahash", "anyhow", @@ -2373,9 +2371,9 @@ dependencies = [ [[package]] name = "plonky2_field" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "465a741ba134485af571152aab5086457a470aa8893391186cf78dd389694440" +checksum = "e27aab0723672905a49e4771232d7fcf71b97dd0e57634f1dfb5492635f765fc" dependencies = [ "anyhow", "itertools", @@ -2485,7 +2483,7 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7e8366a6159044a37876a2b9817124296703c586a5c92e2c53751fa06d8d43e8" dependencies = [ - "toml_edit 0.20.2", + "toml_edit", ] [[package]] @@ -2499,9 +2497,8 @@ dependencies = [ [[package]] name = "proof_gen" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b632ae384e13ad12ed9556e544650bfd79a54b3574fe3da4a749083ea6125440" +version = "0.1.3" +source = "git+https://github.com/0xPolygonZero/zk_evm.git?tag=v0.3.0#423e2614d31d323e950b4a461a27ef565a820b75" dependencies = [ "ethereum-types", "evm_arithmetization", @@ -2906,6 +2903,12 @@ dependencies = [ "untrusted", ] +[[package]] +name = "seahash" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" + [[package]] name = "security-framework" version = "2.9.2" @@ -2976,15 +2979,6 @@ dependencies = [ "serde", ] -[[package]] -name = "serde_spanned" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1" -dependencies = [ - "serde", -] - [[package]] name = "serde_urlencoded" version = "0.7.1" @@ -3119,9 +3113,9 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] name = "starky" -version = "0.2.1" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24e0a1eec739c7a67cb1c6f916c0b7bf2d281cf2edb35d3db5caa6989090133e" +checksum = "acf2fe03f53197fbd5e2f2e5fbb809f8e953881cc729261b55f71134323bbfd6" dependencies = [ "ahash", "anyhow", @@ -3409,26 +3403,11 @@ dependencies = [ "tracing", ] -[[package]] -name = "toml" -version = "0.8.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9dd1545e8208b4a5af1aa9bbd0b4cf7e9ea08fabc5d0a5c67fcaafa17433aa3" -dependencies = [ - "serde", - "serde_spanned", - "toml_datetime", - "toml_edit 0.22.9", -] - [[package]] name = "toml_datetime" version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" -dependencies = [ - "serde", -] [[package]] name = "toml_edit" @@ -3438,20 +3417,7 @@ checksum = "396e4d48bbb2b7554c944bde63101b5ae446cff6ec4a24227428f15eb72ef338" dependencies = [ "indexmap 2.2.5", "toml_datetime", - "winnow 0.5.40", -] - -[[package]] -name = "toml_edit" -version = "0.22.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e40bb779c5187258fd7aad0eb68cb8706a0a81fa712fbea808ab43c4b8374c4" -dependencies = [ - "indexmap 2.2.5", - "serde", - "serde_spanned", - "toml_datetime", - "winnow 0.6.5", + "winnow", ] [[package]] @@ -3484,9 +3450,8 @@ checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" [[package]] name = "trace_decoder" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69c42e0c922b0a7eafaad55ca960f8bc9a8fa95eed4b8ec1beb3749d6543d789" +version = "0.3.0" +source = "git+https://github.com/0xPolygonZero/zk_evm.git?tag=v0.3.0#423e2614d31d323e950b4a461a27ef565a820b75" dependencies = [ "bytes", "ciborium", @@ -3985,15 +3950,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "winnow" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dffa400e67ed5a4dd237983829e66475f0a4a26938c4b04c21baede6262215b8" -dependencies = [ - "memchr", -] - [[package]] name = "winreg" version = "0.50.0" diff --git a/Cargo.toml b/Cargo.toml index 131f3c88..07c6f207 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,9 +19,9 @@ futures = "0.3.29" # zk-evm dependencies plonky2 = "0.2.0" -evm_arithmetization = "0.1.2" -trace_decoder = "0.2.0" -proof_gen = "0.1.2" +evm_arithmetization = { git = "https://github.com/0xPolygonZero/zk_evm.git", tag = "v0.3.0" } +trace_decoder = { git = "https://github.com/0xPolygonZero/zk_evm.git", tag = "v0.3.0" } +proof_gen = { git = "https://github.com/0xPolygonZero/zk_evm.git", tag = "v0.3.0" } [workspace.package] edition = "2021" diff --git a/common/Cargo.toml b/common/Cargo.toml index 8dc464d5..2eab391d 100644 --- a/common/Cargo.toml +++ b/common/Cargo.toml @@ -17,3 +17,4 @@ evm_arithmetization = { workspace = true } clap = { workspace = true } anyhow = { workspace = true } trace_decoder = { workspace = true } +seahash = "4.1.0" diff --git a/common/src/prover_state/mod.rs b/common/src/prover_state/mod.rs index 090201f1..6753ad6c 100644 --- a/common/src/prover_state/mod.rs +++ b/common/src/prover_state/mod.rs @@ -14,9 +14,12 @@ use std::{fmt::Display, sync::OnceLock}; use clap::ValueEnum; -use evm_arithmetization::{proof::AllProof, prover::prove, AllStark, StarkConfig}; +use evm_arithmetization::{ + cpu::kernel::aggregator::KERNEL, proof::AllProof, prover::prove, AllStark, StarkConfig, +}; use plonky2::{ - field::goldilocks_field::GoldilocksField, plonk::config::PoseidonGoldilocksConfig, + field::goldilocks_field::GoldilocksField, + plonk::config::{GenericHashOut, PoseidonGoldilocksConfig}, util::timing::TimingTree, }; use proof_gen::{proof_types::GeneratedTxnProof, prover_state::ProverState, VerifierState}; @@ -24,14 +27,18 @@ use trace_decoder::types::TxnProofGenIR; use tracing::info; use self::circuit::{CircuitConfig, NUM_TABLES}; -use crate::prover_state::persistence::{ - BaseProverResource, DiskResource, MonolithicProverResource, RecursiveCircuitResource, - VerifierResource, +use crate::prover_state::{ + persistence::{ + BaseProverResource, DiskResource, MonolithicProverResource, RecursiveCircuitResource, + VerifierResource, + }, + utils::pkg_consistency_check, }; pub mod circuit; pub mod cli; pub mod persistence; +mod utils; pub(crate) type Config = PoseidonGoldilocksConfig; pub(crate) type Field = GoldilocksField; @@ -252,6 +259,18 @@ impl ProverStateManager { CircuitPersistence::Disk(strategy) => { info!("attempting to load preprocessed circuits from disk..."); + // Check the package consistency before loading the circuits. + pkg_consistency_check(&[ + self.circuit_config + .as_all_recursive_circuits() + .block + .circuit + .verifier_only + .circuit_digest + .to_bytes(), + KERNEL.hash().to_fixed_bytes().to_vec(), + ]); + let disk_state = match strategy { TableLoadStrategy::OnDemand => BaseProverResource::get(&self.circuit_config), TableLoadStrategy::Monolithic => { diff --git a/common/src/prover_state/persistence.rs b/common/src/prover_state/persistence.rs index cd33b04e..dae26e64 100644 --- a/common/src/prover_state/persistence.rs +++ b/common/src/prover_state/persistence.rs @@ -1,4 +1,3 @@ -use std::env; use std::{ fmt::{Debug, Display}, fs::{self, OpenOptions}, @@ -17,7 +16,7 @@ use super::{ Config, RecursiveCircuitsForTableSize, SIZE, }; -const CIRCUITS_FOLDER: &str = "./circuits"; +pub(crate) const CIRCUITS_FOLDER: &str = "./circuits"; const PROVER_STATE_FILE_PREFIX: &str = "prover_state"; const VERIFIER_STATE_FILE_PREFIX: &str = "verifier_state"; @@ -103,10 +102,9 @@ impl DiskResource for BaseProverResource { fn path(p: &Self::PathConstrutor) -> impl AsRef { format!( - "{}/{}_base_{}_{}", + "{}/{}_base_{}", CIRCUITS_FOLDER, PROVER_STATE_FILE_PREFIX, - env::var("EVM_ARITHMETIZATION_PKG_VER").unwrap_or("NA".to_string()), p.get_configuration_digest() ) } @@ -139,10 +137,9 @@ impl DiskResource for MonolithicProverResource { fn path(p: &Self::PathConstrutor) -> impl AsRef { format!( - "{}/{}_monolithic_{}_{}", + "{}/{}_monolithic_{}", CIRCUITS_FOLDER, PROVER_STATE_FILE_PREFIX, - env::var("EVM_ARITHMETIZATION_PKG_VER").unwrap_or("NA".to_string()), p.get_configuration_digest() ) } @@ -174,10 +171,9 @@ impl DiskResource for RecursiveCircuitResource { fn path((circuit_type, size): &Self::PathConstrutor) -> impl AsRef { format!( - "{}/{}_{}_{}_{}", + "{}/{}_{}_{}", CIRCUITS_FOLDER, PROVER_STATE_FILE_PREFIX, - env::var("EVM_ARITHMETIZATION_PKG_VER").unwrap_or("NA".to_string()), circuit_type.as_short_str(), size ) @@ -218,10 +214,9 @@ impl DiskResource for VerifierResource { fn path(p: &Self::PathConstrutor) -> impl AsRef { format!( - "{}/{}_{}_{}", + "{}/{}_{}", CIRCUITS_FOLDER, VERIFIER_STATE_FILE_PREFIX, - env::var("EVM_ARITHMETIZATION_PKG_VER").unwrap_or("NA".to_string()), p.get_configuration_digest() ) } diff --git a/common/src/prover_state/utils.rs b/common/src/prover_state/utils.rs new file mode 100644 index 00000000..83024a13 --- /dev/null +++ b/common/src/prover_state/utils.rs @@ -0,0 +1,86 @@ +use std::fs::{self, File}; +use std::hash::Hasher; +use std::io::{Read, Write}; +use std::path::Path; + +use seahash::SeaHasher; +use tracing::info; + +use super::persistence::CIRCUITS_FOLDER; + +/// Checks the consistency of circuits code by comparing a computed hash +/// derived from the provided array of circuit code hashes against a reference +/// hash stored in a designated file within the circuits folder. This function +/// performs several actions based on this comparison: +/// +/// - If the computed aggregate hash differs from the stored hash, or if the +/// hash file does not exist, the function will delete the existing circuits +/// folder (if it exists), recreate it, and then write the new computed hash +/// into the hash file. +/// +/// - If the computed hash matches the stored hash, indicating no changes in the +/// circuits code, the function takes no action. +/// +/// This process ensures that the stored hash always reflects the current state +/// of the circuits code, providing a mechanism for detecting changes and +/// maintaining consistency. +/// +/// # Parameters +/// +/// * `circuits_hashes` - A dynamic number of `Vec` arguments representing +/// circuit code hashes. +/// +/// # Side Effects +/// +/// - May delete and recreate the circuits folder. +/// - May modify or create a file within the circuits folder to store the latest +/// hash. +pub(crate) fn pkg_consistency_check(circuits_hashes: I) +where + I: IntoIterator, + T: AsRef<[u8]>, +{ + let mut hasher = SeaHasher::new(); + for hash in circuits_hashes { + hasher.write(hash.as_ref()); + } + let hash = hasher.finish(); + + let hash_file_path = Path::new(CIRCUITS_FOLDER).join("circuits_consistency_hash"); + + // Check if the circuits folder exists + match fs::metadata(CIRCUITS_FOLDER) { + Ok(_) => { + // Circuits folder exists, check the hash file + let mut existing_hash = String::new(); + if let Ok(mut hash_file) = File::open(&hash_file_path) { + // If the hash file exists and can be read, compare the hash + if hash_file.read_to_string(&mut existing_hash).is_ok() + && existing_hash == hash.to_string() + { + // Hashes are the same, do nothing + return; + } + } + + // Hashes differ or hash file cannot be read, delete the folder + if fs::remove_dir_all(CIRCUITS_FOLDER).is_err() { + return; // Early return if unable to delete + } + } + Err(_) => { + info!( + "Initializing circuits storage folder with new consistency hash: {}", + hash + ); + } + } + + // Recreate the circuits folder and write the new hash + if fs::create_dir(CIRCUITS_FOLDER).is_ok() { + if let Ok(mut hash_file) = File::create(&hash_file_path) { + // Ignore errors in writing the hash + let _ = hash_file.write_all(hash.to_string().as_bytes()); + } + } +} diff --git a/leader/Cargo.toml b/leader/Cargo.toml index de39328a..5c7bcc92 100644 --- a/leader/Cargo.toml +++ b/leader/Cargo.toml @@ -22,7 +22,6 @@ serde_json = { workspace = true } serde_path_to_error = { workspace = true } ethereum-types = { workspace = true } axum = "0.7.4" -toml = "0.8.12" # Local dependencies ops = { path = "../ops" } diff --git a/leader/src/main.rs b/leader/src/main.rs index 7cc9db8c..36d2f1e3 100644 --- a/leader/src/main.rs +++ b/leader/src/main.rs @@ -1,4 +1,3 @@ -use std::env; use std::{fs::File, path::PathBuf}; use anyhow::Result; @@ -10,14 +9,11 @@ use ops::register; use paladin::runtime::Runtime; use proof_gen::types::PlonkyProofIntern; -use crate::utils::get_package_version; - mod cli; mod http; mod init; mod jerigon; mod stdio; -mod utils; fn get_previous_proof(path: Option) -> Result> { if path.is_none() { @@ -36,15 +32,6 @@ async fn main() -> Result<()> { dotenv().ok(); init::tracing(); - if env::var("EVM_ARITHMETIZATION_PKG_VER").is_err() { - let pkg_ver = get_package_version("evm_arithmetization")?; - // Set the environment variable for the evm_arithmetization package version - env::set_var( - "EVM_ARITHMETIZATION_PKG_VER", - pkg_ver.unwrap_or("NA".to_string()), - ); - } - let args = cli::Cli::parse(); if let paladin::config::Runtime::InMemory = args.paladin.runtime { // If running in emulation mode, we'll need to initialize the prover diff --git a/leader/src/utils.rs b/leader/src/utils.rs deleted file mode 100644 index 3a9a1ef3..00000000 --- a/leader/src/utils.rs +++ /dev/null @@ -1,34 +0,0 @@ -use std::fs::File; -use std::io::{BufReader, Read}; -use std::path::Path; - -use anyhow::Result; - -pub(crate) fn get_package_version(package_name: &str) -> Result> { - let manifest_dir = env!("CARGO_MANIFEST_DIR"); - let zero_bin_path = Path::new(manifest_dir) - .join("../") // Adjust the path according to your workspace structure - .canonicalize()?; - - let cargo_lock_path = zero_bin_path.join("Cargo.lock"); - let cargo_lock_file = File::open(cargo_lock_path); - if cargo_lock_file.is_err() { - return Ok(None); - } - - let mut cargo_lock_contents = String::new(); - BufReader::new(cargo_lock_file?).read_to_string(&mut cargo_lock_contents)?; - - let lockfile: toml::Value = toml::from_str(&cargo_lock_contents)?; - if let Some(package) = lockfile["package"] - .as_array() - .unwrap() - .iter() - .find(|&p| p["name"].as_str() == Some(package_name)) - { - let version = package["version"].as_str().unwrap(); - return Ok(Some(version.to_string())); - } - - Ok(None) -} From 952d2cbad5722c90df2bfb0398b3883466aff12a Mon Sep 17 00:00:00 2001 From: Vladimir Trifonov Date: Wed, 3 Apr 2024 16:40:04 +0300 Subject: [PATCH 05/29] fix: fix clippy issue --- common/src/prover_state/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/src/prover_state/mod.rs b/common/src/prover_state/mod.rs index 6753ad6c..1c0e2142 100644 --- a/common/src/prover_state/mod.rs +++ b/common/src/prover_state/mod.rs @@ -260,7 +260,7 @@ impl ProverStateManager { info!("attempting to load preprocessed circuits from disk..."); // Check the package consistency before loading the circuits. - pkg_consistency_check(&[ + pkg_consistency_check([ self.circuit_config .as_all_recursive_circuits() .block From 864635b843665dd0b34ffe44ccac154d2da73dfe Mon Sep 17 00:00:00 2001 From: Robin Salen Date: Mon, 8 Apr 2024 09:36:11 +0900 Subject: [PATCH 06/29] Reduce verbosity in logs --- leader/src/init.rs | 6 +++--- rpc/src/init.rs | 6 +++--- verifier/src/init.rs | 6 +++--- worker/src/init.rs | 6 +++--- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/leader/src/init.rs b/leader/src/init.rs index 28c00d48..f9391489 100644 --- a/leader/src/init.rs +++ b/leader/src/init.rs @@ -1,10 +1,10 @@ -use tracing_subscriber::{fmt::format::FmtSpan, prelude::*, util::SubscriberInitExt, EnvFilter}; +use tracing_subscriber::{prelude::*, util::SubscriberInitExt, EnvFilter}; pub(crate) fn tracing() { tracing_subscriber::Registry::default() .with( tracing_subscriber::fmt::layer() - .pretty() - .with_span_events(FmtSpan::CLOSE) + .with_ansi(false) + .compact() .with_filter(EnvFilter::from_default_env()), ) .init(); diff --git a/rpc/src/init.rs b/rpc/src/init.rs index 28c00d48..f9391489 100644 --- a/rpc/src/init.rs +++ b/rpc/src/init.rs @@ -1,10 +1,10 @@ -use tracing_subscriber::{fmt::format::FmtSpan, prelude::*, util::SubscriberInitExt, EnvFilter}; +use tracing_subscriber::{prelude::*, util::SubscriberInitExt, EnvFilter}; pub(crate) fn tracing() { tracing_subscriber::Registry::default() .with( tracing_subscriber::fmt::layer() - .pretty() - .with_span_events(FmtSpan::CLOSE) + .with_ansi(false) + .compact() .with_filter(EnvFilter::from_default_env()), ) .init(); diff --git a/verifier/src/init.rs b/verifier/src/init.rs index 28c00d48..f9391489 100644 --- a/verifier/src/init.rs +++ b/verifier/src/init.rs @@ -1,10 +1,10 @@ -use tracing_subscriber::{fmt::format::FmtSpan, prelude::*, util::SubscriberInitExt, EnvFilter}; +use tracing_subscriber::{prelude::*, util::SubscriberInitExt, EnvFilter}; pub(crate) fn tracing() { tracing_subscriber::Registry::default() .with( tracing_subscriber::fmt::layer() - .pretty() - .with_span_events(FmtSpan::CLOSE) + .with_ansi(false) + .compact() .with_filter(EnvFilter::from_default_env()), ) .init(); diff --git a/worker/src/init.rs b/worker/src/init.rs index 28c00d48..f9391489 100644 --- a/worker/src/init.rs +++ b/worker/src/init.rs @@ -1,10 +1,10 @@ -use tracing_subscriber::{fmt::format::FmtSpan, prelude::*, util::SubscriberInitExt, EnvFilter}; +use tracing_subscriber::{prelude::*, util::SubscriberInitExt, EnvFilter}; pub(crate) fn tracing() { tracing_subscriber::Registry::default() .with( tracing_subscriber::fmt::layer() - .pretty() - .with_span_events(FmtSpan::CLOSE) + .with_ansi(false) + .compact() .with_filter(EnvFilter::from_default_env()), ) .init(); From 5e221d80e054ae3b2afe3b652282306c9878ac41 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Apr 2024 01:15:09 +0000 Subject: [PATCH 07/29] Bump h2 from 0.3.25 to 0.3.26 Bumps [h2](https://github.com/hyperium/h2) from 0.3.25 to 0.3.26. - [Release notes](https://github.com/hyperium/h2/releases) - [Changelog](https://github.com/hyperium/h2/blob/v0.3.26/CHANGELOG.md) - [Commits](https://github.com/hyperium/h2/compare/v0.3.25...v0.3.26) --- updated-dependencies: - dependency-name: h2 dependency-type: indirect ... Signed-off-by: dependabot[bot] --- Cargo.lock | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a74908cb..c45e8c15 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1302,9 +1302,9 @@ checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" [[package]] name = "h2" -version = "0.3.25" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fbd2820c5e49886948654ab546d0688ff24530286bdcf8fca3cefb16d4618eb" +checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" dependencies = [ "bytes", "fnv", @@ -1512,14 +1512,14 @@ dependencies = [ "futures-channel", "futures-core", "futures-util", - "h2 0.3.25", + "h2 0.3.26", "http 0.2.12", "http-body 0.4.6", "httparse", "httpdate", "itoa", "pin-project-lite", - "socket2 0.5.6", + "socket2 0.4.10", "tokio", "tower-service", "tracing", @@ -2676,7 +2676,7 @@ dependencies = [ "encoding_rs", "futures-core", "futures-util", - "h2 0.3.25", + "h2 0.3.26", "http 0.2.12", "http-body 0.4.6", "hyper 0.14.28", From 2de2237ea5602cb183ea5474c1d992e0197d27a1 Mon Sep 17 00:00:00 2001 From: Vladimir Trifonov Date: Tue, 9 Apr 2024 09:13:46 +0300 Subject: [PATCH 08/29] fix: add pr comments fixes --- common/src/prover_state/utils.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/common/src/prover_state/utils.rs b/common/src/prover_state/utils.rs index 83024a13..21d042aa 100644 --- a/common/src/prover_state/utils.rs +++ b/common/src/prover_state/utils.rs @@ -4,7 +4,7 @@ use std::io::{Read, Write}; use std::path::Path; use seahash::SeaHasher; -use tracing::info; +use tracing::{info, warn}; use super::persistence::CIRCUITS_FOLDER; @@ -61,11 +61,13 @@ where // Hashes are the same, do nothing return; } + } else { + warn!("Unable to read circuits consistency hash file"); } // Hashes differ or hash file cannot be read, delete the folder if fs::remove_dir_all(CIRCUITS_FOLDER).is_err() { - return; // Early return if unable to delete + panic!("Failed to delete circuits storage folder"); } } Err(_) => { @@ -82,5 +84,7 @@ where // Ignore errors in writing the hash let _ = hash_file.write_all(hash.to_string().as_bytes()); } + } else { + panic!("Failed to create circuits storage folder"); } } From 80f8da2dae3080cf93b0a9a3ce990255c117fd0c Mon Sep 17 00:00:00 2001 From: BGluth Date: Wed, 10 Apr 2024 13:53:10 -0600 Subject: [PATCH 09/29] Debug & proving scripts now use indentical logging - Previously they were both different, and both were missing important modules. --- tools/debug_block.sh | 2 +- tools/prove_blocks.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/debug_block.sh b/tools/debug_block.sh index df1a9c68..0b639ffa 100755 --- a/tools/debug_block.sh +++ b/tools/debug_block.sh @@ -6,7 +6,7 @@ export RUST_BACKTRACE=1 export RUST_MIN_STACK=8388608 -export RUST_LOG=mpt_trie=info,trace_decoder=info,plonky2=info,evm_arithmetization=trace +export RUST_LOG=mpt_trie=info,trace_decoder=info,plonky2=info,evm_arithmetization=trace,leader=info # Speciying smallest ranges, as we won't need them anyway. export ARITHMETIC_CIRCUIT_SIZE="16..17" diff --git a/tools/prove_blocks.sh b/tools/prove_blocks.sh index a6f4e4bb..f1d62a32 100755 --- a/tools/prove_blocks.sh +++ b/tools/prove_blocks.sh @@ -7,7 +7,7 @@ # 4 --> Ignore previous proofs (boolean) export RUST_BACKTRACE=1 -export RUST_LOG=plonky2=trace,evm_arithmetization=trace +export RUST_LOG=mpt_trie=info,trace_decoder=info,plonky2=info,evm_arithmetization=trace,leader=info export ARITHMETIC_CIRCUIT_SIZE="16..23" export BYTE_PACKING_CIRCUIT_SIZE="9..21" From 10080f0a4d85c950e27ed600552d688a16b9621f Mon Sep 17 00:00:00 2001 From: Robin Salen Date: Thu, 11 Apr 2024 09:25:40 +0900 Subject: [PATCH 10/29] Add flag to scripts --- tools/debug_block.sh | 1 + tools/prove_blocks.sh | 1 + 2 files changed, 2 insertions(+) diff --git a/tools/debug_block.sh b/tools/debug_block.sh index 0b639ffa..74323e20 100755 --- a/tools/debug_block.sh +++ b/tools/debug_block.sh @@ -7,6 +7,7 @@ export RUST_BACKTRACE=1 export RUST_MIN_STACK=8388608 export RUST_LOG=mpt_trie=info,trace_decoder=info,plonky2=info,evm_arithmetization=trace,leader=info +export RUSTFLAGS='-Ctarget-cpu=native' # Speciying smallest ranges, as we won't need them anyway. export ARITHMETIC_CIRCUIT_SIZE="16..17" diff --git a/tools/prove_blocks.sh b/tools/prove_blocks.sh index f1d62a32..c27317ef 100755 --- a/tools/prove_blocks.sh +++ b/tools/prove_blocks.sh @@ -8,6 +8,7 @@ export RUST_BACKTRACE=1 export RUST_LOG=mpt_trie=info,trace_decoder=info,plonky2=info,evm_arithmetization=trace,leader=info +export RUSTFLAGS='-Ctarget-cpu=native' export ARITHMETIC_CIRCUIT_SIZE="16..23" export BYTE_PACKING_CIRCUIT_SIZE="9..21" From 26d352674c5a33e9e62e0889911078214d628ea9 Mon Sep 17 00:00:00 2001 From: Robin Salen Date: Fri, 12 Apr 2024 18:45:21 -0400 Subject: [PATCH 11/29] Allow verifier to load .env file --- Cargo.lock | 1 + verifier/Cargo.toml | 1 + verifier/src/main.rs | 2 ++ 3 files changed, 4 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index c45e8c15..a62582da 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3640,6 +3640,7 @@ dependencies = [ "anyhow", "clap", "common", + "dotenvy", "proof_gen", "serde", "serde_json", diff --git a/verifier/Cargo.toml b/verifier/Cargo.toml index 482ec783..cbd76b15 100644 --- a/verifier/Cargo.toml +++ b/verifier/Cargo.toml @@ -7,6 +7,7 @@ edition = "2021" clap = { workspace = true } tracing = { workspace = true } tracing-subscriber = { workspace = true } +dotenvy = { workspace = true } anyhow = { workspace = true } serde = { workspace = true } serde_json = { workspace = true } diff --git a/verifier/src/main.rs b/verifier/src/main.rs index 60ba1d52..4ef86692 100644 --- a/verifier/src/main.rs +++ b/verifier/src/main.rs @@ -2,6 +2,7 @@ use std::fs::File; use anyhow::Result; use clap::Parser; +use dotenvy::dotenv; use proof_gen::types::PlonkyProofIntern; use serde_json::Deserializer; @@ -9,6 +10,7 @@ mod cli; mod init; fn main() -> Result<()> { + dotenv().ok(); init::tracing(); let args = cli::Cli::parse(); From b81956b0a1dd0cd9f5c2cf215665217381f9ab17 Mon Sep 17 00:00:00 2001 From: Robin Salen Date: Fri, 12 Apr 2024 18:47:57 -0400 Subject: [PATCH 12/29] Add logging info from verifier side --- verifier/src/main.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/verifier/src/main.rs b/verifier/src/main.rs index 4ef86692..271a1346 100644 --- a/verifier/src/main.rs +++ b/verifier/src/main.rs @@ -5,6 +5,7 @@ use clap::Parser; use dotenvy::dotenv; use proof_gen::types::PlonkyProofIntern; use serde_json::Deserializer; +use tracing::info; mod cli; mod init; @@ -23,7 +24,10 @@ fn main() -> Result<()> { .into_prover_state_manager() .verifier()?; - verifer.verify(&input)?; + match verifer.verify(&input) { + Ok(_) => info!("Proof verified successfully!"), + Err(e) => info!("Proof verification failed with error: {:?}", e), + }; Ok(()) } From b54b670b41d504500bc32786a6368bb3f4256752 Mon Sep 17 00:00:00 2001 From: BGluth Date: Wed, 17 Apr 2024 10:25:12 -0600 Subject: [PATCH 13/29] Updated docs for new parameter in `prove_blocks.sh` - Was not mentioned in the readme at all, and people would always run into this if they followed the old docs. --- README.md | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index ef266a38..e5761181 100644 --- a/README.md +++ b/README.md @@ -357,21 +357,30 @@ There are three branches that are used for development: For testing proof generation for blocks, the `testing` branch should be used. +### Proving Blocks + If you want to generate a full block proof, you can use `tools/prove_blocks.sh`: ```sh -./prove_blocks.sh +./prove_blocks.sh ``` Which may look like this: ```sh -./prove_blocks.sh 17 18 http://127.0.0.1:8545 +./prove_blocks.sh 17 18 http://127.0.0.1:8545 false ``` -Which will attempt to generate blocks `17` & `18` consecutively. +Which will attempt to generate blocks `17` & `18` consecutively and incorporate the previous block proof during generation. + +A few other notes: + +- Proving blocks is very resource intensive in terms of both CPU and memory. You can also only generate the witness for a block instead (see [Generating Witnesses Only](#generating-witnesses-only)) to significantly reduce the CPU and memory requirements. +- Because incorporating the previous block proof requires a chain of proofs back to the last checkpoint height, you can also disable this requirement by passing `true` for `` (which internally just sets the current checkpoint height to the current block height). + +### Generating Witnesses Only -However, proving blocks is very resource intensive in both CPU and memory. You can also only generate the witness for a block instead to significantly reduce the CPU and memory requirements: +If you want to test a block without the high CPU & memory requirements that come with creating a full proof, you can instead generate only the witness using `tools/debug_block.sh`: ```sh ./debug_block.sh From 61b2cd686162763a8bd7c5201297402527f0461f Mon Sep 17 00:00:00 2001 From: BGluth Date: Wed, 17 Apr 2024 10:57:38 -0600 Subject: [PATCH 14/29] Apply suggestions from code review (Nashtare) Co-authored-by: Robin Salen <30937548+Nashtare@users.noreply.github.com> --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e5761181..6b410242 100644 --- a/README.md +++ b/README.md @@ -371,12 +371,12 @@ Which may look like this: ./prove_blocks.sh 17 18 http://127.0.0.1:8545 false ``` -Which will attempt to generate blocks `17` & `18` consecutively and incorporate the previous block proof during generation. +Which will attempt to generate proofs for blocks `17` & `18` consecutively and incorporate the previous block proof during generation. A few other notes: - Proving blocks is very resource intensive in terms of both CPU and memory. You can also only generate the witness for a block instead (see [Generating Witnesses Only](#generating-witnesses-only)) to significantly reduce the CPU and memory requirements. -- Because incorporating the previous block proof requires a chain of proofs back to the last checkpoint height, you can also disable this requirement by passing `true` for `` (which internally just sets the current checkpoint height to the current block height). +- Because incorporating the previous block proof requires a chain of proofs back to the last checkpoint height, you can also disable this requirement by passing `true` for `` (which internally just sets the current checkpoint height to the previous block height). ### Generating Witnesses Only From 27bdf410cf871e3caf9f802f175dd12bb9c735e7 Mon Sep 17 00:00:00 2001 From: BGluth Date: Thu, 18 Apr 2024 18:51:27 -0600 Subject: [PATCH 15/29] Now logs time to generate proofs --- Cargo.lock | 4 ++ Cargo.toml | 2 + ops/Cargo.toml | 4 ++ ops/src/lib.rs | 128 +++++++++++++++++++++++++++++++++++++++++++++---- 4 files changed, 128 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5e901dc6..53a3d970 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2104,11 +2104,15 @@ name = "ops" version = "0.1.0" dependencies = [ "common", + "ethereum-types", "evm_arithmetization", + "keccak-hash 0.10.0", "paladin-core", "proof_gen", + "rlp", "serde", "trace_decoder", + "tracing", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 07c6f207..eeca6b8a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,6 +16,8 @@ serde_json = "1.0.107" ethereum-types = "0.14.1" thiserror = "1.0.50" futures = "0.3.29" +rlp = "0.5.2" +keccak-hash = "0.10.0" # zk-evm dependencies plonky2 = "0.2.0" diff --git a/ops/Cargo.toml b/ops/Cargo.toml index 48235c64..3072cdb0 100644 --- a/ops/Cargo.toml +++ b/ops/Cargo.toml @@ -14,6 +14,10 @@ serde = { workspace = true } evm_arithmetization = { workspace = true, optional = true} proof_gen = { workspace = true } trace_decoder = { workspace = true } +tracing = { workspace = true } +rlp = { workspace = true } +ethereum-types = "0.14.1" +keccak-hash = { workspace = true } common = { path = "../common" } diff --git a/ops/src/lib.rs b/ops/src/lib.rs index c1b56e06..34fe6156 100644 --- a/ops/src/lib.rs +++ b/ops/src/lib.rs @@ -1,4 +1,7 @@ +use std::{ops::RangeInclusive, time::Instant}; + use common::prover_state::p_state; +use keccak_hash::keccak; use paladin::{ operation::{FatalError, FatalStrategy, Monoid, Operation, Result}, registry, RemoteExecute, @@ -8,22 +11,43 @@ use proof_gen::{ proof_types::{AggregatableProof, GeneratedAggProof, GeneratedBlockProof}, }; use serde::{Deserialize, Serialize}; -use trace_decoder::types::TxnProofGenIR; +use trace_decoder::types::{BlockHeight, TxnProofGenIR}; +use tracing::{event, info_span, Level}; registry!(); #[derive(Deserialize, Serialize, RemoteExecute)] pub struct TxProof; +fn run_and_wrap_closure_in_elapsed_span(f: F, ident: String) -> Result +where + F: Fn() -> Result, +{ + let _span = info_span!("proof generation", ident).entered(); + let start = Instant::now(); + + let proof = f()?; + + event!(Level::INFO, "Proof {:.4} took {:?}", ident, start.elapsed()); + Ok(proof) +} + #[cfg(not(feature = "test_only"))] impl Operation for TxProof { type Input = TxnProofGenIR; type Output = proof_gen::proof_types::AggregatableProof; fn execute(&self, input: Self::Input) -> Result { - let proof = common::prover_state::p_manager() - .generate_txn_proof(input) - .map_err(|err| FatalError::from_anyhow(err, FatalStrategy::Terminate))?; + let txn_ident = Self::txn_ident(&input); + + let proof = run_and_wrap_closure_in_elapsed_span( + || { + common::prover_state::p_manager() + .generate_txn_proof(input.clone()) + .map_err(|err| FatalError::from_anyhow(err, FatalStrategy::Terminate).into()) + }, + txn_ident, + )?; Ok(proof.into()) } @@ -35,13 +59,37 @@ impl Operation for TxProof { type Output = (); fn execute(&self, input: Self::Input) -> Result { - evm_arithmetization::prover::testing::simulate_execution::(input) - .map_err(|err| FatalError::from_anyhow(err, FatalStrategy::Terminate))?; + let txn_ident = Self::txn_ident(&input); + + run_and_wrap_closure_in_elapsed_span( + || { + evm_arithmetization::prover::testing::simulate_execution::( + input.clone(), + ) + .map_err(|err| FatalError::from_anyhow(err, FatalStrategy::Terminate).into()) + }, + txn_ident, + )?; Ok(()) } } +impl TxProof { + fn txn_ident(ir: &TxnProofGenIR) -> String { + let txn_hash_str = ir + .signed_txn + .as_ref() + .map(|txn| format!("{:x}", keccak(txn))) + .unwrap_or_else(|| "Dummy".to_string()); + + format!( + "Txn b{} - {} ({})", + ir.block_metadata.block_number, ir.txn_number_before, txn_hash_str + ) + } +} + #[derive(Deserialize, Serialize, RemoteExecute)] pub struct AggProof; @@ -49,7 +97,11 @@ impl Monoid for AggProof { type Elem = AggregatableProof; fn combine(&self, a: Self::Elem, b: Self::Elem) -> Result { - let result = generate_agg_proof(p_state(), &a, &b).map_err(FatalError::from)?; + let ident = Self::agg_ident(&a, &b); + let result = run_and_wrap_closure_in_elapsed_span( + || generate_agg_proof(p_state(), &a, &b).map_err(|e| FatalError::from(e).into()), + ident, + )?; Ok(result.into()) } @@ -60,6 +112,21 @@ impl Monoid for AggProof { } } +impl AggProof { + fn agg_ident(a: &AggregatableProof, b: &AggregatableProof) -> String { + let b_height = b_height_from_aggregatable_proof(a); + let a_range = proof_range_from_aggregatable_proof(a); + let b_range = proof_range_from_aggregatable_proof(b); + + format!( + "Agg b{} - {}..={}", + b_height, + *a_range.start(), + *b_range.end() + ) + } +} + #[derive(Deserialize, Serialize, RemoteExecute)] pub struct BlockProof { pub prev: Option, @@ -70,9 +137,50 @@ impl Operation for BlockProof { type Output = GeneratedBlockProof; fn execute(&self, input: Self::Input) -> Result { - Ok( - generate_block_proof(p_state(), self.prev.as_ref(), &input) - .map_err(FatalError::from)?, + let ident = Self::block_ident(&input); + + run_and_wrap_closure_in_elapsed_span( + || { + generate_block_proof(p_state(), self.prev.as_ref(), &input) + .map_err(|e| FatalError::from(e).into()) + }, + ident, ) } } + +impl BlockProof { + fn block_ident(p: &GeneratedAggProof) -> String { + let b_height = p.p_vals.block_metadata.block_number; + let b_range = aggregated_proof_range(p); + + format!( + "Block b{} ({}..={})", + b_height, + *b_range.start(), + *b_range.end() + ) + } +} + +fn proof_range_from_aggregatable_proof(p: &AggregatableProof) -> RangeInclusive { + match p { + AggregatableProof::Txn(info) => { + let txn_idx = info.p_vals.extra_block_data.txn_number_before.as_usize(); + txn_idx..=txn_idx + } + AggregatableProof::Agg(info) => aggregated_proof_range(info), + } +} + +fn aggregated_proof_range(p: &GeneratedAggProof) -> RangeInclusive { + p.p_vals.extra_block_data.txn_number_before.as_usize() + ..=p.p_vals.extra_block_data.txn_number_after.as_usize() +} + +fn b_height_from_aggregatable_proof(p: &AggregatableProof) -> BlockHeight { + match p { + AggregatableProof::Txn(info) => info.p_vals.block_metadata.block_number.as_u64(), + AggregatableProof::Agg(info) => info.p_vals.block_metadata.block_number.as_u64(), + } +} From b3b01e57f25b094f0d041dde376ee6fba31a4d78 Mon Sep 17 00:00:00 2001 From: BGluth Date: Fri, 19 Apr 2024 09:07:23 -0600 Subject: [PATCH 16/29] Removed agg & block proof timing logic --- ops/Cargo.toml | 2 +- ops/src/lib.rs | 87 ++++++++++---------------------------------------- 2 files changed, 17 insertions(+), 72 deletions(-) diff --git a/ops/Cargo.toml b/ops/Cargo.toml index 3072cdb0..9ca1ea27 100644 --- a/ops/Cargo.toml +++ b/ops/Cargo.toml @@ -16,7 +16,7 @@ proof_gen = { workspace = true } trace_decoder = { workspace = true } tracing = { workspace = true } rlp = { workspace = true } -ethereum-types = "0.14.1" +ethereum-types = { workspace = true } keccak-hash = { workspace = true } common = { path = "../common" } diff --git a/ops/src/lib.rs b/ops/src/lib.rs index 34fe6156..0c0b4ca2 100644 --- a/ops/src/lib.rs +++ b/ops/src/lib.rs @@ -1,4 +1,4 @@ -use std::{ops::RangeInclusive, time::Instant}; +use std::time::Instant; use common::prover_state::p_state; use keccak_hash::keccak; @@ -11,7 +11,7 @@ use proof_gen::{ proof_types::{AggregatableProof, GeneratedAggProof, GeneratedBlockProof}, }; use serde::{Deserialize, Serialize}; -use trace_decoder::types::{BlockHeight, TxnProofGenIR}; +use trace_decoder::types::TxnProofGenIR; use tracing::{event, info_span, Level}; registry!(); @@ -19,7 +19,7 @@ registry!(); #[derive(Deserialize, Serialize, RemoteExecute)] pub struct TxProof; -fn run_and_wrap_closure_in_elapsed_span(f: F, ident: String) -> Result +fn run_and_wrap_txn_proof_in_elapsed_span(f: F, ident: String) -> Result where F: Fn() -> Result, { @@ -28,7 +28,12 @@ where let proof = f()?; - event!(Level::INFO, "Proof {:.4} took {:?}", ident, start.elapsed()); + event!( + Level::INFO, + "txn proof {:.4} took {:?}", + ident, + start.elapsed() + ); Ok(proof) } @@ -40,7 +45,7 @@ impl Operation for TxProof { fn execute(&self, input: Self::Input) -> Result { let txn_ident = Self::txn_ident(&input); - let proof = run_and_wrap_closure_in_elapsed_span( + let proof = run_and_wrap_txn_proof_in_elapsed_span( || { common::prover_state::p_manager() .generate_txn_proof(input.clone()) @@ -61,7 +66,7 @@ impl Operation for TxProof { fn execute(&self, input: Self::Input) -> Result { let txn_ident = Self::txn_ident(&input); - run_and_wrap_closure_in_elapsed_span( + run_and_wrap_txn_proof_in_elapsed_span( || { evm_arithmetization::prover::testing::simulate_execution::( input.clone(), @@ -84,7 +89,7 @@ impl TxProof { .unwrap_or_else(|| "Dummy".to_string()); format!( - "Txn b{} - {} ({})", + "b{} - {} ({})", ir.block_metadata.block_number, ir.txn_number_before, txn_hash_str ) } @@ -97,11 +102,7 @@ impl Monoid for AggProof { type Elem = AggregatableProof; fn combine(&self, a: Self::Elem, b: Self::Elem) -> Result { - let ident = Self::agg_ident(&a, &b); - let result = run_and_wrap_closure_in_elapsed_span( - || generate_agg_proof(p_state(), &a, &b).map_err(|e| FatalError::from(e).into()), - ident, - )?; + let result = generate_agg_proof(p_state(), &a, &b).map_err(FatalError::from)?; Ok(result.into()) } @@ -112,21 +113,6 @@ impl Monoid for AggProof { } } -impl AggProof { - fn agg_ident(a: &AggregatableProof, b: &AggregatableProof) -> String { - let b_height = b_height_from_aggregatable_proof(a); - let a_range = proof_range_from_aggregatable_proof(a); - let b_range = proof_range_from_aggregatable_proof(b); - - format!( - "Agg b{} - {}..={}", - b_height, - *a_range.start(), - *b_range.end() - ) - } -} - #[derive(Deserialize, Serialize, RemoteExecute)] pub struct BlockProof { pub prev: Option, @@ -137,50 +123,9 @@ impl Operation for BlockProof { type Output = GeneratedBlockProof; fn execute(&self, input: Self::Input) -> Result { - let ident = Self::block_ident(&input); - - run_and_wrap_closure_in_elapsed_span( - || { - generate_block_proof(p_state(), self.prev.as_ref(), &input) - .map_err(|e| FatalError::from(e).into()) - }, - ident, - ) - } -} - -impl BlockProof { - fn block_ident(p: &GeneratedAggProof) -> String { - let b_height = p.p_vals.block_metadata.block_number; - let b_range = aggregated_proof_range(p); - - format!( - "Block b{} ({}..={})", - b_height, - *b_range.start(), - *b_range.end() + Ok( + generate_block_proof(p_state(), self.prev.as_ref(), &input) + .map_err(FatalError::from)?, ) } } - -fn proof_range_from_aggregatable_proof(p: &AggregatableProof) -> RangeInclusive { - match p { - AggregatableProof::Txn(info) => { - let txn_idx = info.p_vals.extra_block_data.txn_number_before.as_usize(); - txn_idx..=txn_idx - } - AggregatableProof::Agg(info) => aggregated_proof_range(info), - } -} - -fn aggregated_proof_range(p: &GeneratedAggProof) -> RangeInclusive { - p.p_vals.extra_block_data.txn_number_before.as_usize() - ..=p.p_vals.extra_block_data.txn_number_after.as_usize() -} - -fn b_height_from_aggregatable_proof(p: &AggregatableProof) -> BlockHeight { - match p { - AggregatableProof::Txn(info) => info.p_vals.block_metadata.block_number.as_u64(), - AggregatableProof::Agg(info) => info.p_vals.block_metadata.block_number.as_u64(), - } -} From 37207d80a424a906930c4815134c312a2408c038 Mon Sep 17 00:00:00 2001 From: BGluth Date: Fri, 19 Apr 2024 12:51:14 -0600 Subject: [PATCH 17/29] Fixed txn proof logs not rendering correctly - Txn ident was being printed twice. - Only the first `4` chars of the ident were being printed. --- ops/src/lib.rs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/ops/src/lib.rs b/ops/src/lib.rs index 0c0b4ca2..a72edf4b 100644 --- a/ops/src/lib.rs +++ b/ops/src/lib.rs @@ -28,12 +28,7 @@ where let proof = f()?; - event!( - Level::INFO, - "txn proof {:.4} took {:?}", - ident, - start.elapsed() - ); + event!(Level::INFO, "txn proof took {:?}", start.elapsed()); Ok(proof) } From 7bfa083e30ff8c18e16351bb933cba45f6717ee9 Mon Sep 17 00:00:00 2001 From: BGluth Date: Fri, 19 Apr 2024 15:12:10 -0600 Subject: [PATCH 18/29] Cleaned up txn proof timing output even more --- ops/Cargo.toml | 4 ++-- ops/src/lib.rs | 52 +++++++++++++++++++++++++------------------------- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/ops/Cargo.toml b/ops/Cargo.toml index 9ca1ea27..f22ad6ad 100644 --- a/ops/Cargo.toml +++ b/ops/Cargo.toml @@ -11,7 +11,7 @@ categories.workspace = true [dependencies] paladin-core = { workspace = true } serde = { workspace = true } -evm_arithmetization = { workspace = true, optional = true} +evm_arithmetization = { workspace = true } proof_gen = { workspace = true } trace_decoder = { workspace = true } tracing = { workspace = true } @@ -23,4 +23,4 @@ common = { path = "../common" } [features] default = [] -test_only = ["evm_arithmetization"] +test_only = [] diff --git a/ops/src/lib.rs b/ops/src/lib.rs index a72edf4b..1bfd8404 100644 --- a/ops/src/lib.rs +++ b/ops/src/lib.rs @@ -1,6 +1,7 @@ use std::time::Instant; use common::prover_state::p_state; +use evm_arithmetization::GenerationInputs; use keccak_hash::keccak; use paladin::{ operation::{FatalError, FatalStrategy, Monoid, Operation, Result}, @@ -19,34 +20,19 @@ registry!(); #[derive(Deserialize, Serialize, RemoteExecute)] pub struct TxProof; -fn run_and_wrap_txn_proof_in_elapsed_span(f: F, ident: String) -> Result -where - F: Fn() -> Result, -{ - let _span = info_span!("proof generation", ident).entered(); - let start = Instant::now(); - - let proof = f()?; - - event!(Level::INFO, "txn proof took {:?}", start.elapsed()); - Ok(proof) -} - #[cfg(not(feature = "test_only"))] impl Operation for TxProof { type Input = TxnProofGenIR; type Output = proof_gen::proof_types::AggregatableProof; fn execute(&self, input: Self::Input) -> Result { - let txn_ident = Self::txn_ident(&input); - - let proof = run_and_wrap_txn_proof_in_elapsed_span( + let proof = Self::run_and_wrap_txn_proof_in_elapsed_span( || { common::prover_state::p_manager() .generate_txn_proof(input.clone()) .map_err(|err| FatalError::from_anyhow(err, FatalStrategy::Terminate).into()) }, - txn_ident, + &input, )?; Ok(proof.into()) @@ -59,16 +45,14 @@ impl Operation for TxProof { type Output = (); fn execute(&self, input: Self::Input) -> Result { - let txn_ident = Self::txn_ident(&input); - - run_and_wrap_txn_proof_in_elapsed_span( + Self::run_and_wrap_txn_proof_in_elapsed_span( || { evm_arithmetization::prover::testing::simulate_execution::( input.clone(), ) .map_err(|err| FatalError::from_anyhow(err, FatalStrategy::Terminate).into()) }, - txn_ident, + &input, )?; Ok(()) @@ -76,17 +60,33 @@ impl Operation for TxProof { } impl TxProof { - fn txn_ident(ir: &TxnProofGenIR) -> String { + fn run_and_wrap_txn_proof_in_elapsed_span(f: F, ir: &GenerationInputs) -> Result + where + F: Fn() -> Result, + { + let id = format!( + "b{} - {}", + ir.block_metadata.block_number, ir.txn_number_before + ); + + let _span = info_span!("p_gen", id).entered(); + let start = Instant::now(); + + let proof = f()?; + let txn_hash_str = ir .signed_txn .as_ref() .map(|txn| format!("{:x}", keccak(txn))) .unwrap_or_else(|| "Dummy".to_string()); - format!( - "b{} - {} ({})", - ir.block_metadata.block_number, ir.txn_number_before, txn_hash_str - ) + event!( + Level::INFO, + "txn proof ({}) took {:?}", + txn_hash_str, + start.elapsed() + ); + Ok(proof) } } From b05d60a99529edad988fea9494117b49f248c202 Mon Sep 17 00:00:00 2001 From: John Hilliard Date: Mon, 22 Apr 2024 09:07:57 -0400 Subject: [PATCH 19/29] feat: adding block proof ci --- .github/workflows/ci.yml | 14 ++++++++ tools/simple_test.sh | 69 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+) create mode 100755 tools/simple_test.sh diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c4ffc8e1..77fc47d0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -5,6 +5,7 @@ on: branches: - main pull_request: + types: [opened, synchronize, reopened, ready_for_review] branches: - "**" workflow_dispatch: @@ -63,3 +64,16 @@ jobs: - name: Run cargo clippy run: cargo clippy --all-targets -- -D warnings + + simple_proof: + name: Execute bash script to generate and verify a proof from a small block + runs-on: zero-ci + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Run the script + run: | + pushd tools + ./simple_test.sh diff --git a/tools/simple_test.sh b/tools/simple_test.sh new file mode 100755 index 00000000..bf5e17ad --- /dev/null +++ b/tools/simple_test.sh @@ -0,0 +1,69 @@ +#!/bin/bash +# ------------------------------------------------------------------------------ +# This is meant to be a somewhat self contained script for quickly +# proving an Ethereum mainnet block with the type 1 prover. The goal +# is to use this for benchmarking and CI. This is the block in +# question: https://etherscan.io/block/19240705 + +# We're going to set the paralellism in line with the total cpu count +num_procs=$(nproc) + +2>&1 echo "Pulling sample witness" +witness_cid_hash="QmbwnLGuZ2qxZDqETAFb5DnyjZry8Sv3UFwYnsgKmsE3of" +curl -s -L "https://cf-ipfs.com/ipfs/$witness_cid_hash" > witness.json.bz2 +bunzip2 -f witness.json.bz2 + +# Configured Rayon and Tokio with rough defaults +export RAYON_NUM_THREADS=$num_procs +export TOKIO_WORKER_THREADS=$num_procs + +export RUST_MIN_STACK=33554432 +export RUST_BACKTRACE=full +export RUST_LOG=info +export RUSTFLAGS='-C target-cpu=native' + +# This sizes are configured specifically for this witness. Don't use this in other scenarios +export ARITHMETIC_CIRCUIT_SIZE="15..19" +export BYTE_PACKING_CIRCUIT_SIZE="9..19" +export CPU_CIRCUIT_SIZE="12..21" +export KECCAK_CIRCUIT_SIZE="14..18" +export KECCAK_SPONGE_CIRCUIT_SIZE="9..13" +export LOGIC_CIRCUIT_SIZE="12..17" +export MEMORY_CIRCUIT_SIZE="17..23" + +# If we run ./simple_test test_only, we'll generate a dummy +# proof. This is useful for quickly testing decoding and all of the +# other non-proving code. +if [[ $1 == "test_only" ]]; then + cargo run --release --features test_only --bin leader -- --runtime in-memory stdio < witness.json | tee test.out + if grep 'Successfully generated witness for block' test.out; then + echo "Success - Note this was just a test, not a proof" + exit + else + echo "Failed to create a witness" + exit 1 + fi +fi + +cargo build --release --jobs "$num_procs" + +start_time=$(date +%s%N) +../target/release/leader --runtime in-memory stdio < witness.json | tee leader.out +end_time=$(date +%s%N) + +tail -n 1 leader.out > proof.json + +../target/release/verifier -f proof.json | tee verify.out + +if grep 'Proof verified successfully!' verify.out; then + duration_ns=$((end_time - start_time)) + duration_sec=$(echo "$duration_ns / 1000000000" | bc -l) + echo "Success!" + printf "Duration: %.3f seconds\n" $duration_sec + echo "Note, this duration is inclusive of circuit handling and overall process initialization"; +else + echo "there was an issue with proof verification"; + exit 1 +fi + + From da404100a676deed4bdf19326eae1690c289f4df Mon Sep 17 00:00:00 2001 From: John Hilliard Date: Mon, 22 Apr 2024 10:39:35 -0400 Subject: [PATCH 20/29] Update tools/simple_test.sh Co-authored-by: Robin Salen <30937548+Nashtare@users.noreply.github.com> --- tools/simple_test.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/simple_test.sh b/tools/simple_test.sh index bf5e17ad..89f1900b 100755 --- a/tools/simple_test.sh +++ b/tools/simple_test.sh @@ -23,7 +23,7 @@ export RUST_LOG=info export RUSTFLAGS='-C target-cpu=native' # This sizes are configured specifically for this witness. Don't use this in other scenarios -export ARITHMETIC_CIRCUIT_SIZE="15..19" +export ARITHMETIC_CIRCUIT_SIZE="16..19" export BYTE_PACKING_CIRCUIT_SIZE="9..19" export CPU_CIRCUIT_SIZE="12..21" export KECCAK_CIRCUIT_SIZE="14..18" From ea5d63efda11508c43fff49a7dd0628a04d20ede Mon Sep 17 00:00:00 2001 From: Ben Date: Tue, 23 Apr 2024 16:51:09 +0100 Subject: [PATCH 21/29] Cargo audit updates (#66) * cargo audit update * update plony2/evm * fmt --- Cargo.lock | 59 +++++++++++++++++++++++----------- Cargo.toml | 8 ++--- common/src/prover_state/mod.rs | 10 +++--- ops/src/lib.rs | 5 ++- 4 files changed, 52 insertions(+), 30 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 53a3d970..d9777c37 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1035,7 +1035,7 @@ dependencies = [ [[package]] name = "evm_arithmetization" version = "0.1.3" -source = "git+https://github.com/0xPolygonZero/zk_evm.git?tag=v0.3.0#423e2614d31d323e950b4a461a27ef565a820b75" +source = "git+https://github.com/0xPolygonZero/zk_evm.git?tag=v0.3.1#c55f9e05f571b1b8658315e6de83427fe1d4efa3" dependencies = [ "anyhow", "bytes", @@ -1321,9 +1321,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51ee2dd2e4f378392eeff5d51618cd9a63166a2513846bbc55f21cfacd9199d4" +checksum = "816ec7294445779408f36fe57bc5b7fc1cf59664059096c65f905c1c61f58069" dependencies = [ "bytes", "fnv", @@ -1519,7 +1519,7 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", - "socket2 0.4.10", + "socket2 0.5.6", "tokio", "tower-service", "tracing", @@ -1535,7 +1535,7 @@ dependencies = [ "bytes", "futures-channel", "futures-util", - "h2 0.4.3", + "h2 0.4.4", "http 1.1.0", "http-body 1.0.0", "httparse", @@ -1624,6 +1624,17 @@ dependencies = [ "parity-scale-codec", ] +[[package]] +name = "impl-num-traits" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "951641f13f873bff03d4bf19ae8bec531935ac0ac2cc775f84d7edfdcfed3f17" +dependencies = [ + "integer-sqrt", + "num-traits", + "uint", +] + [[package]] name = "impl-rlp" version = "0.3.0" @@ -1694,6 +1705,15 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "integer-sqrt" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "276ec31bcb4a9ee45f58bec6f9ec700ae4cf4f4f8f2fa7e06cb406bd5ffdd770" +dependencies = [ + "num-traits", +] + [[package]] name = "io-lifetimes" version = "1.0.11" @@ -1948,12 +1968,16 @@ dependencies = [ [[package]] name = "mpt_trie" version = "0.2.1" -source = "git+https://github.com/0xPolygonZero/zk_evm.git?tag=v0.3.0#423e2614d31d323e950b4a461a27ef565a820b75" +source = "git+https://github.com/0xPolygonZero/zk_evm.git?tag=v0.3.1#c55f9e05f571b1b8658315e6de83427fe1d4efa3" dependencies = [ "bytes", "enum-as-inner", "ethereum-types", "hex", + "impl-codec", + "impl-num-traits", + "impl-rlp", + "impl-serde", "keccak-hash 0.10.0", "log", "num", @@ -2350,9 +2374,9 @@ dependencies = [ [[package]] name = "plonky2" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d04c7dfa293cd62a8e1e3f21157dba8508ab2de6078b0e5fae202a4fc98ef224" +checksum = "85f26b090b989aebdeaf6a4eed748c1fbcabf67e7273a22e4e0c877b63846d0f" dependencies = [ "ahash", "anyhow", @@ -2375,9 +2399,9 @@ dependencies = [ [[package]] name = "plonky2_field" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e27aab0723672905a49e4771232d7fcf71b97dd0e57634f1dfb5492635f765fc" +checksum = "3a1dca60ad900d81b1fe2df3d0b88d43345988e2935e6709176e96573f4bcf5d" dependencies = [ "anyhow", "itertools", @@ -2502,7 +2526,7 @@ dependencies = [ [[package]] name = "proof_gen" version = "0.1.3" -source = "git+https://github.com/0xPolygonZero/zk_evm.git?tag=v0.3.0#423e2614d31d323e950b4a461a27ef565a820b75" +source = "git+https://github.com/0xPolygonZero/zk_evm.git?tag=v0.3.1#c55f9e05f571b1b8658315e6de83427fe1d4efa3" dependencies = [ "ethereum-types", "evm_arithmetization", @@ -2510,7 +2534,6 @@ dependencies = [ "paste", "plonky2", "serde", - "trace_decoder", ] [[package]] @@ -2817,9 +2840,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.21.10" +version = "0.21.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" +checksum = "7fecbfb7b1444f477b345853b1fce097a2c6fb637b2bfb87e6bc5db0f043fae4" dependencies = [ "log", "ring", @@ -3117,9 +3140,9 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] name = "starky" -version = "0.3.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acf2fe03f53197fbd5e2f2e5fbb809f8e953881cc729261b55f71134323bbfd6" +checksum = "8a8480ca5b8eedf83ad070a780783b4e21a56c6ef66b4c0d1b7520b72bdfda1b" dependencies = [ "ahash", "anyhow", @@ -3454,8 +3477,8 @@ checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" [[package]] name = "trace_decoder" -version = "0.3.0" -source = "git+https://github.com/0xPolygonZero/zk_evm.git?tag=v0.3.0#423e2614d31d323e950b4a461a27ef565a820b75" +version = "0.3.1" +source = "git+https://github.com/0xPolygonZero/zk_evm.git?tag=v0.3.1#c55f9e05f571b1b8658315e6de83427fe1d4efa3" dependencies = [ "bytes", "ciborium", diff --git a/Cargo.toml b/Cargo.toml index eeca6b8a..3979d7f4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,10 +20,10 @@ rlp = "0.5.2" keccak-hash = "0.10.0" # zk-evm dependencies -plonky2 = "0.2.0" -evm_arithmetization = { git = "https://github.com/0xPolygonZero/zk_evm.git", tag = "v0.3.0" } -trace_decoder = { git = "https://github.com/0xPolygonZero/zk_evm.git", tag = "v0.3.0" } -proof_gen = { git = "https://github.com/0xPolygonZero/zk_evm.git", tag = "v0.3.0" } +plonky2 = "0.2.2" +evm_arithmetization = { git = "https://github.com/0xPolygonZero/zk_evm.git", tag = "v0.3.1" } +trace_decoder = { git = "https://github.com/0xPolygonZero/zk_evm.git", tag = "v0.3.1" } +proof_gen = { git = "https://github.com/0xPolygonZero/zk_evm.git", tag = "v0.3.1" } [workspace.package] edition = "2021" diff --git a/common/src/prover_state/mod.rs b/common/src/prover_state/mod.rs index 1c0e2142..b2c18e39 100644 --- a/common/src/prover_state/mod.rs +++ b/common/src/prover_state/mod.rs @@ -15,7 +15,8 @@ use std::{fmt::Display, sync::OnceLock}; use clap::ValueEnum; use evm_arithmetization::{ - cpu::kernel::aggregator::KERNEL, proof::AllProof, prover::prove, AllStark, StarkConfig, + cpu::kernel::aggregator::KERNEL, proof::AllProof, prover::prove, AllStark, GenerationInputs, + StarkConfig, }; use plonky2::{ field::goldilocks_field::GoldilocksField, @@ -23,7 +24,6 @@ use plonky2::{ util::timing::TimingTree, }; use proof_gen::{proof_types::GeneratedTxnProof, prover_state::ProverState, VerifierState}; -use trace_decoder::types::TxnProofGenIR; use tracing::info; use self::circuit::{CircuitConfig, NUM_TABLES}; @@ -194,7 +194,7 @@ impl ProverStateManager { /// Generate a transaction proof using the specified input, loading the /// circuit tables as needed to shrink the individual STARK proofs, and /// finally aggregating them to a final transaction proof. - fn txn_proof_on_demand(&self, input: TxnProofGenIR) -> anyhow::Result { + fn txn_proof_on_demand(&self, input: GenerationInputs) -> anyhow::Result { let config = StarkConfig::standard_fast_config(); let all_stark = AllStark::default(); let all_proof = prove(&all_stark, &config, input, &mut TimingTree::default(), None)?; @@ -211,7 +211,7 @@ impl ProverStateManager { /// Generate a transaction proof using the specified input on the monolithic /// circuit. - fn txn_proof_monolithic(&self, input: TxnProofGenIR) -> anyhow::Result { + fn txn_proof_monolithic(&self, input: GenerationInputs) -> anyhow::Result { let (intern, p_vals) = p_state().state.prove_root( &AllStark::default(), &StarkConfig::standard_fast_config(), @@ -232,7 +232,7 @@ impl ProverStateManager { /// - If the persistence strategy is [`CircuitPersistence::Disk`] with /// [`TableLoadStrategy::OnDemand`], the table circuits are loaded as /// needed. - pub fn generate_txn_proof(&self, input: TxnProofGenIR) -> anyhow::Result { + pub fn generate_txn_proof(&self, input: GenerationInputs) -> anyhow::Result { match self.persistence { CircuitPersistence::None | CircuitPersistence::Disk(TableLoadStrategy::Monolithic) => { info!("using monolithic circuit {:?}", self); diff --git a/ops/src/lib.rs b/ops/src/lib.rs index 1bfd8404..04faa1c7 100644 --- a/ops/src/lib.rs +++ b/ops/src/lib.rs @@ -12,7 +12,6 @@ use proof_gen::{ proof_types::{AggregatableProof, GeneratedAggProof, GeneratedBlockProof}, }; use serde::{Deserialize, Serialize}; -use trace_decoder::types::TxnProofGenIR; use tracing::{event, info_span, Level}; registry!(); @@ -22,7 +21,7 @@ pub struct TxProof; #[cfg(not(feature = "test_only"))] impl Operation for TxProof { - type Input = TxnProofGenIR; + type Input = GenerationInputs; type Output = proof_gen::proof_types::AggregatableProof; fn execute(&self, input: Self::Input) -> Result { @@ -41,7 +40,7 @@ impl Operation for TxProof { #[cfg(feature = "test_only")] impl Operation for TxProof { - type Input = TxnProofGenIR; + type Input = GenerationInputs; type Output = (); fn execute(&self, input: Self::Input) -> Result { From 361edbf788fced449b7ff996dccd71880f1c480e Mon Sep 17 00:00:00 2001 From: Zach Brown Date: Tue, 23 Apr 2024 14:22:27 -0600 Subject: [PATCH 22/29] Implement RAII span for transaction timing to avoid cloning input (#67) --- ops/src/lib.rs | 86 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 51 insertions(+), 35 deletions(-) diff --git a/ops/src/lib.rs b/ops/src/lib.rs index 04faa1c7..1200047c 100644 --- a/ops/src/lib.rs +++ b/ops/src/lib.rs @@ -25,14 +25,10 @@ impl Operation for TxProof { type Output = proof_gen::proof_types::AggregatableProof; fn execute(&self, input: Self::Input) -> Result { - let proof = Self::run_and_wrap_txn_proof_in_elapsed_span( - || { - common::prover_state::p_manager() - .generate_txn_proof(input.clone()) - .map_err(|err| FatalError::from_anyhow(err, FatalStrategy::Terminate).into()) - }, - &input, - )?; + let _span = TxProofSpan::new(&input); + let proof = common::prover_state::p_manager() + .generate_txn_proof(input) + .map_err(|err| FatalError::from_anyhow(err, FatalStrategy::Terminate))?; Ok(proof.into()) } @@ -44,48 +40,68 @@ impl Operation for TxProof { type Output = (); fn execute(&self, input: Self::Input) -> Result { - Self::run_and_wrap_txn_proof_in_elapsed_span( - || { - evm_arithmetization::prover::testing::simulate_execution::( - input.clone(), - ) - .map_err(|err| FatalError::from_anyhow(err, FatalStrategy::Terminate).into()) - }, - &input, - )?; + let _span = TxProofSpan::new(&input); + evm_arithmetization::prover::testing::simulate_execution::(input) + .map_err(|err| FatalError::from_anyhow(err, FatalStrategy::Terminate))?; Ok(()) } } -impl TxProof { - fn run_and_wrap_txn_proof_in_elapsed_span(f: F, ir: &GenerationInputs) -> Result - where - F: Fn() -> Result, - { - let id = format!( +/// RAII struct to measure the time taken by a transaction proof. +/// +/// - When created, it starts a span with the transaction proof id. +/// - When dropped, it logs the time taken by the transaction proof. +struct TxProofSpan { + _span: tracing::span::EnteredSpan, + start: Instant, + descriptor: String, +} + +impl TxProofSpan { + /// Get a unique id for the transaction proof. + fn get_id(ir: &GenerationInputs) -> String { + format!( "b{} - {}", ir.block_metadata.block_number, ir.txn_number_before - ); - - let _span = info_span!("p_gen", id).entered(); - let start = Instant::now(); - - let proof = f()?; + ) + } - let txn_hash_str = ir - .signed_txn + /// Get a textual descriptor for the transaction proof. + /// + /// Either the hex-encoded hash of the transaction or "Dummy" if the + /// transaction is not present. + fn get_descriptor(ir: &GenerationInputs) -> String { + ir.signed_txn .as_ref() .map(|txn| format!("{:x}", keccak(txn))) - .unwrap_or_else(|| "Dummy".to_string()); + .unwrap_or_else(|| "Dummy".to_string()) + } + + /// Create a new transaction proof span. + /// + /// When dropped, it logs the time taken by the transaction proof. + fn new(ir: &GenerationInputs) -> Self { + let id = Self::get_id(ir); + let span = info_span!("p_gen", id).entered(); + let start = Instant::now(); + let descriptor = Self::get_descriptor(ir); + Self { + _span: span, + start, + descriptor, + } + } +} +impl Drop for TxProofSpan { + fn drop(&mut self) { event!( Level::INFO, "txn proof ({}) took {:?}", - txn_hash_str, - start.elapsed() + self.descriptor, + self.start.elapsed() ); - Ok(proof) } } From e18dbd5ed702395917d2e83f26221cbdfde34fcb Mon Sep 17 00:00:00 2001 From: Vladimir Trifonov Date: Wed, 24 Apr 2024 20:07:23 +0300 Subject: [PATCH 23/29] feat: provide IR for debugging upon failure (#48) * feat: provide IR for debugging upon failure * fix: fix clippy issues * fix: fix pr comments * fix: make evm_arithmetization non optional for ops * fix: fix pr comments * fix: fix clippy issues * fix: fix clippy issue * fix: fix pr comment * fix: fix clippy issue * fix: fix cargo lock * fix: fix pr comments * fix: fix format issues * fix: fix save input on error for test-only * fix: fix pr comments * fix: fix * fix: fix clippy issue * fix: fmt fix --------- Co-authored-by: Vladimir Trifonov --- Cargo.lock | 2 + README.md | 5 ++ common/Cargo.toml | 2 + common/src/debug_utils.rs | 102 ++++++++++++++++++++++++++++++++++++ common/src/lib.rs | 1 + leader/src/cli.rs | 9 ++++ leader/src/http.rs | 16 ++++-- leader/src/jerigon.rs | 5 +- leader/src/main.rs | 17 ++++-- leader/src/stdio.rs | 3 +- ops/src/lib.rs | 107 +++++++++++++++++++++++++++++++++----- prover/src/lib.rs | 19 +++++-- 12 files changed, 263 insertions(+), 25 deletions(-) create mode 100644 common/src/debug_utils.rs diff --git a/Cargo.lock b/Cargo.lock index d9777c37..ba777c30 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -641,6 +641,8 @@ dependencies = [ "plonky2", "proof_gen", "seahash", + "serde", + "serde_json", "thiserror", "trace_decoder", "tracing", diff --git a/README.md b/README.md index 6b410242..d826ab96 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,9 @@ A composition of [`paladin`](https://github.com/0xPolygonZero/paladin) and [`plo - [RPC Usage](#rpc-usage) - [Docker](#docker) - [Development Branches](#development-branches) + - [Testing Blocks](#testing-blocks) + - [Proving Blocks](#proving-blocks) + - [Generating Witnesses Only](#generating-witnesses-only) - [License](#license) - [Contribution](#contribution) @@ -217,6 +220,8 @@ Options: If provided, write the generated proof to this file instead of stdout -h, --help Print help + -s, --save-inputs-on-error + If provided, save the public inputs to disk on error ``` Prove a block. diff --git a/common/Cargo.toml b/common/Cargo.toml index 2eab391d..9a08bbd1 100644 --- a/common/Cargo.toml +++ b/common/Cargo.toml @@ -17,4 +17,6 @@ evm_arithmetization = { workspace = true } clap = { workspace = true } anyhow = { workspace = true } trace_decoder = { workspace = true } +serde = { workspace = true } +serde_json = { workspace = true } seahash = "4.1.0" diff --git a/common/src/debug_utils.rs b/common/src/debug_utils.rs new file mode 100644 index 00000000..f8cb53dd --- /dev/null +++ b/common/src/debug_utils.rs @@ -0,0 +1,102 @@ +use std::fs::{self, File}; +use std::io::{self, Write}; +use std::path::{Path, PathBuf}; + +use serde::Serialize; +use serde_json::Error as SerdeError; +use thiserror::Error; + +const DEBUG_FOLDER: &str = "./debug"; + +/// Ensures that the specified directory exists on the filesystem. +/// +/// This function checks if the directory at `folder_path` exists. If not, it +/// attempts to create the directory. It returns an error if the path is not a +/// directory or if there are issues accessing or creating the directory. +/// +/// # Parameters +/// * `folder_path` - A reference to a `Path` that specifies the directory to +/// check or create. +/// +/// # Returns +/// * `Ok(())` - The directory exists or was successfully created. +/// * `Err(io::Error)` - The path is not a directory, or there was a problem +/// accessing or creating the directory. +fn ensure_directory_exists(folder_path: &Path) -> io::Result<()> { + match fs::metadata(folder_path) { + Ok(metadata) => { + if metadata.is_dir() { + Ok(()) // The directory already exists + } else { + Err(io::Error::new( + io::ErrorKind::AlreadyExists, + "The path exists but is not a directory", + )) + } + } + Err(e) => { + if e.kind() == io::ErrorKind::NotFound { + // Directory does not exist, try to create it + fs::create_dir(folder_path) + } else { + // Re-throw the error if it's not a 'NotFound' error + Err(e) + } + } + } +} + +/// An error type for save debug input information. +#[derive(Error, Debug)] +pub enum SaveInputError { + #[error("failed to create directory '{0}'")] + CreateDirectoryError(PathBuf, #[source] io::Error), + + #[error("failed to create file '{0}'")] + CreateFileError(PathBuf, #[source] io::Error), + + #[error("failed to serialize inputs")] + SerializationError(#[source] SerdeError), + + #[error("failed to write to file '{0}'")] + WriteToFileError(PathBuf, #[source] io::Error), +} + +/// Serializes a collection of inputs to a pretty-printed JSON format and saves +/// them to a file. +/// +/// # Arguments +/// +/// * `file_name` - The name of the file (including the extension) where the +/// serialized data will be saved. +/// * `inputs` - A collection of items to be serialized. Each item in the +/// collection must implement the `Serialize` trait. +/// +/// # Returns +/// +/// This function returns a `Result<(), std::io::Error>` indicating the +/// operation's success or failure. +pub fn save_inputs_to_disk( + file_name: String, + inputs: T, +) -> Result<(), SaveInputError> { + let debug_folder = Path::new(DEBUG_FOLDER); + let input_file_path = debug_folder.join(file_name); + + // Ensure the DEBUG_FOLDER exists + ensure_directory_exists(debug_folder) + .map_err(|e| SaveInputError::CreateDirectoryError(debug_folder.to_path_buf(), e))?; + + let mut file = File::create(&input_file_path) + .map_err(|e| SaveInputError::CreateFileError(input_file_path.clone(), e))?; + + // Serialize the entire collection to a pretty JSON string + let all_inputs_str = + serde_json::to_string_pretty(&inputs).map_err(SaveInputError::SerializationError)?; + + // Write the serialized data to the file + file.write_all(all_inputs_str.as_bytes()) + .map_err(|e| SaveInputError::WriteToFileError(input_file_path, e))?; + + Ok(()) +} diff --git a/common/src/lib.rs b/common/src/lib.rs index 234099cf..e9e7b504 100644 --- a/common/src/lib.rs +++ b/common/src/lib.rs @@ -1,2 +1,3 @@ +pub mod debug_utils; pub mod parsing; pub mod prover_state; diff --git a/leader/src/cli.rs b/leader/src/cli.rs index 6ab9d8fb..10316f6a 100644 --- a/leader/src/cli.rs +++ b/leader/src/cli.rs @@ -25,6 +25,9 @@ pub(crate) enum Command { /// The previous proof output. #[arg(long, short = 'f', value_hint = ValueHint::FilePath)] previous_proof: Option, + /// If true, save the public inputs to disk on error. + #[arg(short, long, default_value_t = false)] + save_inputs_on_error: bool, }, /// Reads input from a Jerigon node and writes output to stdout. Jerigon { @@ -44,6 +47,9 @@ pub(crate) enum Command { /// stdout. #[arg(long, short = 'o', value_hint = ValueHint::FilePath)] proof_output_path: Option, + /// If true, save the public inputs to disk on error. + #[arg(short, long, default_value_t = false)] + save_inputs_on_error: bool, }, /// Reads input from HTTP and writes output to a directory. Http { @@ -53,5 +59,8 @@ pub(crate) enum Command { /// The directory to which output should be written. #[arg(short, long, value_hint = ValueHint::DirPath)] output_dir: PathBuf, + /// If true, save the public inputs to disk on error. + #[arg(short, long, default_value_t = false)] + save_inputs_on_error: bool, }, } diff --git a/leader/src/http.rs b/leader/src/http.rs index 84187794..80111ce4 100644 --- a/leader/src/http.rs +++ b/leader/src/http.rs @@ -11,7 +11,12 @@ use serde_json::to_writer; use tracing::{debug, error, info}; /// The main function for the HTTP mode. -pub(crate) async fn http_main(runtime: Runtime, port: u16, output_dir: PathBuf) -> Result<()> { +pub(crate) async fn http_main( + runtime: Runtime, + port: u16, + output_dir: PathBuf, + save_inputs_on_error: bool, +) -> Result<()> { let addr = SocketAddr::from(([0, 0, 0, 0], port)); debug!("listening on {}", addr); @@ -20,7 +25,7 @@ pub(crate) async fn http_main(runtime: Runtime, port: u16, output_dir: PathBuf) "/prove", post({ let runtime = runtime.clone(); - move |body| prove(body, runtime, output_dir.clone()) + move |body| prove(body, runtime, output_dir.clone(), save_inputs_on_error) }), ); let listener = tokio::net::TcpListener::bind(&addr).await?; @@ -60,12 +65,17 @@ async fn prove( Json(payload): Json, runtime: Arc, output_dir: PathBuf, + save_inputs_on_error: bool, ) -> StatusCode { debug!("Received payload: {:#?}", payload); let block_number = payload.prover_input.get_block_number(); - match payload.prover_input.prove(&runtime, payload.previous).await { + match payload + .prover_input + .prove(&runtime, payload.previous, save_inputs_on_error) + .await + { Ok(b_proof) => match write_to_file(output_dir, block_number, &b_proof) { Ok(file) => { info!("Successfully wrote proof to {}", file.display()); diff --git a/leader/src/jerigon.rs b/leader/src/jerigon.rs index 899ea20e..6719112a 100644 --- a/leader/src/jerigon.rs +++ b/leader/src/jerigon.rs @@ -16,6 +16,7 @@ pub(crate) async fn jerigon_main( checkpoint_block_number: u64, previous: Option, proof_output_path_opt: Option, + save_inputs_on_error: bool, ) -> Result<()> { let prover_input = rpc::fetch_prover_input(rpc::FetchProverInputRequest { rpc_url, @@ -24,7 +25,9 @@ pub(crate) async fn jerigon_main( }) .await?; - let proof = prover_input.prove(&runtime, previous).await; + let proof = prover_input + .prove(&runtime, previous, save_inputs_on_error) + .await; runtime.close().await?; let proof = serde_json::to_vec(&proof?.intern)?; diff --git a/leader/src/main.rs b/leader/src/main.rs index 36d2f1e3..8c054ea4 100644 --- a/leader/src/main.rs +++ b/leader/src/main.rs @@ -47,11 +47,18 @@ async fn main() -> Result<()> { let runtime = Runtime::from_config(&args.paladin, register()).await?; match args.command { - Command::Stdio { previous_proof } => { + Command::Stdio { + previous_proof, + save_inputs_on_error, + } => { let previous_proof = get_previous_proof(previous_proof)?; - stdio::stdio_main(runtime, previous_proof).await?; + stdio::stdio_main(runtime, previous_proof, save_inputs_on_error).await?; } - Command::Http { port, output_dir } => { + Command::Http { + port, + output_dir, + save_inputs_on_error, + } => { // check if output_dir exists, is a directory, and is writable let output_dir_metadata = std::fs::metadata(&output_dir); if output_dir_metadata.is_err() { @@ -61,7 +68,7 @@ async fn main() -> Result<()> { panic!("output-dir is not a writable directory"); } - http::http_main(runtime, port, output_dir).await?; + http::http_main(runtime, port, output_dir, save_inputs_on_error).await?; } Command::Jerigon { rpc_url, @@ -69,6 +76,7 @@ async fn main() -> Result<()> { checkpoint_block_number, previous_proof, proof_output_path, + save_inputs_on_error, } => { let previous_proof = get_previous_proof(previous_proof)?; @@ -79,6 +87,7 @@ async fn main() -> Result<()> { checkpoint_block_number, previous_proof, proof_output_path, + save_inputs_on_error, ) .await?; } diff --git a/leader/src/stdio.rs b/leader/src/stdio.rs index e3b6ec5a..7f1e6e3f 100644 --- a/leader/src/stdio.rs +++ b/leader/src/stdio.rs @@ -9,13 +9,14 @@ use prover::ProverInput; pub(crate) async fn stdio_main( runtime: Runtime, previous: Option, + save_inputs_on_error: bool, ) -> Result<()> { let mut buffer = String::new(); std::io::stdin().read_to_string(&mut buffer)?; let des = &mut serde_json::Deserializer::from_str(&buffer); let input: ProverInput = serde_path_to_error::deserialize(des)?; - let proof = input.prove(&runtime, previous).await; + let proof = input.prove(&runtime, previous, save_inputs_on_error).await; runtime.close().await?; let proof = proof?; diff --git a/ops/src/lib.rs b/ops/src/lib.rs index 1200047c..5b6caf69 100644 --- a/ops/src/lib.rs +++ b/ops/src/lib.rs @@ -1,7 +1,7 @@ use std::time::Instant; -use common::prover_state::p_state; -use evm_arithmetization::GenerationInputs; +use common::{debug_utils::save_inputs_to_disk, prover_state::p_state}; +use evm_arithmetization::{proof::PublicValues, GenerationInputs}; use keccak_hash::keccak; use paladin::{ operation::{FatalError, FatalStrategy, Monoid, Operation, Result}, @@ -12,12 +12,14 @@ use proof_gen::{ proof_types::{AggregatableProof, GeneratedAggProof, GeneratedBlockProof}, }; use serde::{Deserialize, Serialize}; -use tracing::{event, info_span, Level}; +use tracing::{error, event, info_span, Level}; registry!(); #[derive(Deserialize, Serialize, RemoteExecute)] -pub struct TxProof; +pub struct TxProof { + pub save_inputs_on_error: bool, +} #[cfg(not(feature = "test_only"))] impl Operation for TxProof { @@ -26,9 +28,27 @@ impl Operation for TxProof { fn execute(&self, input: Self::Input) -> Result { let _span = TxProofSpan::new(&input); - let proof = common::prover_state::p_manager() - .generate_txn_proof(input) - .map_err(|err| FatalError::from_anyhow(err, FatalStrategy::Terminate))?; + let proof = if self.save_inputs_on_error { + common::prover_state::p_manager() + .generate_txn_proof(input.clone()) + .map_err(|err| { + if let Err(write_err) = save_inputs_to_disk( + format!( + "b{}_txn_{}_input.log", + input.block_metadata.block_number, input.txn_number_before + ), + input, + ) { + error!("Failed to save txn proof input to disk: {:?}", write_err); + } + + FatalError::from_anyhow(err, FatalStrategy::Terminate) + })? + } else { + common::prover_state::p_manager() + .generate_txn_proof(input) + .map_err(|err| FatalError::from_anyhow(err, FatalStrategy::Terminate))? + }; Ok(proof.into()) } @@ -41,8 +61,30 @@ impl Operation for TxProof { fn execute(&self, input: Self::Input) -> Result { let _span = TxProofSpan::new(&input); - evm_arithmetization::prover::testing::simulate_execution::(input) + + if self.save_inputs_on_error { + evm_arithmetization::prover::testing::simulate_execution::( + input.clone(), + ) + .map_err(|err| { + if let Err(write_err) = save_inputs_to_disk( + format!( + "b{}_txn_{}_input.log", + input.block_metadata.block_number, input.txn_number_before + ), + input, + ) { + error!("Failed to save txn proof input to disk: {:?}", write_err); + } + + FatalError::from_anyhow(err, FatalStrategy::Terminate) + })?; + } else { + evm_arithmetization::prover::testing::simulate_execution::( + input, + ) .map_err(|err| FatalError::from_anyhow(err, FatalStrategy::Terminate))?; + } Ok(()) } @@ -106,13 +148,40 @@ impl Drop for TxProofSpan { } #[derive(Deserialize, Serialize, RemoteExecute)] -pub struct AggProof; +pub struct AggProof { + pub save_inputs_on_error: bool, +} + +fn get_agg_proof_public_values(elem: AggregatableProof) -> PublicValues { + match elem { + AggregatableProof::Txn(info) => info.p_vals, + AggregatableProof::Agg(info) => info.p_vals, + } +} impl Monoid for AggProof { type Elem = AggregatableProof; fn combine(&self, a: Self::Elem, b: Self::Elem) -> Result { - let result = generate_agg_proof(p_state(), &a, &b).map_err(FatalError::from)?; + let result = generate_agg_proof(p_state(), &a, &b).map_err(|e| { + if self.save_inputs_on_error { + let pv = vec![ + get_agg_proof_public_values(a), + get_agg_proof_public_values(b), + ]; + if let Err(write_err) = save_inputs_to_disk( + format!( + "b{}_agg_lhs_rhs_inputs.log", + pv[0].block_metadata.block_number + ), + pv, + ) { + error!("Failed to save agg proof inputs to disk: {:?}", write_err); + } + } + + FatalError::from(e) + })?; Ok(result.into()) } @@ -126,6 +195,7 @@ impl Monoid for AggProof { #[derive(Deserialize, Serialize, RemoteExecute)] pub struct BlockProof { pub prev: Option, + pub save_inputs_on_error: bool, } impl Operation for BlockProof { @@ -134,8 +204,21 @@ impl Operation for BlockProof { fn execute(&self, input: Self::Input) -> Result { Ok( - generate_block_proof(p_state(), self.prev.as_ref(), &input) - .map_err(FatalError::from)?, + generate_block_proof(p_state(), self.prev.as_ref(), &input).map_err(|e| { + if self.save_inputs_on_error { + if let Err(write_err) = save_inputs_to_disk( + format!( + "b{}_block_input.log", + input.p_vals.block_metadata.block_number + ), + input.p_vals, + ) { + error!("Failed to save block proof input to disk: {:?}", write_err); + } + } + + FatalError::from(e) + })?, ) } } diff --git a/prover/src/lib.rs b/prover/src/lib.rs index abf424a9..8cef4303 100644 --- a/prover/src/lib.rs +++ b/prover/src/lib.rs @@ -35,6 +35,7 @@ impl ProverInput { self, runtime: &Runtime, previous: Option, + save_inputs_on_error: bool, ) -> Result { let block_number = self.get_block_number(); info!("Proving block {block_number}"); @@ -46,8 +47,12 @@ impl ProverInput { )?; let agg_proof = IndexedStream::from(txs) - .map(&TxProof) - .fold(&ops::AggProof) + .map(&TxProof { + save_inputs_on_error, + }) + .fold(&ops::AggProof { + save_inputs_on_error, + }) .run(runtime) .await?; @@ -58,7 +63,10 @@ impl ProverInput { }); let block_proof = paladin::directive::Literal(proof) - .map(&ops::BlockProof { prev }) + .map(&ops::BlockProof { + prev, + save_inputs_on_error, + }) .run(runtime) .await?; @@ -74,6 +82,7 @@ impl ProverInput { self, runtime: &Runtime, _previous: Option, + save_inputs_on_error: bool, ) -> Result { let block_number = self.get_block_number(); info!("Testing witness generation for block {block_number}."); @@ -85,7 +94,9 @@ impl ProverInput { )?; IndexedStream::from(txs) - .map(&TxProof) + .map(&TxProof { + save_inputs_on_error, + }) .run(runtime) .await? .try_collect::>() From b25c1129611c32458d19c345e743e3393748c058 Mon Sep 17 00:00:00 2001 From: Vladimir Trifonov Date: Wed, 24 Apr 2024 20:41:36 +0300 Subject: [PATCH 24/29] fix: fix circuit version consistency check (#58) * fix: fix circuit version consistency check * fix: fix clippy issues * fix: update deps --------- Co-authored-by: Vladimir Trifonov Co-authored-by: Robin Salen --- Cargo.lock | 51 ++++++++++++++- common/src/prover_state/mod.rs | 28 ++------ common/src/prover_state/persistence.rs | 15 +++-- common/src/prover_state/utils.rs | 90 -------------------------- leader/Cargo.toml | 1 + leader/src/main.rs | 17 +++++ leader/src/utils.rs | 72 +++++++++++++++++++++ 7 files changed, 154 insertions(+), 120 deletions(-) delete mode 100644 common/src/prover_state/utils.rs create mode 100644 leader/src/utils.rs diff --git a/Cargo.lock b/Cargo.lock index ba777c30..d09d1d71 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1855,6 +1855,7 @@ dependencies = [ "serde_json", "serde_path_to_error", "tokio", + "toml", "tracing", "tracing-subscriber", ] @@ -2513,7 +2514,7 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7e8366a6159044a37876a2b9817124296703c586a5c92e2c53751fa06d8d43e8" dependencies = [ - "toml_edit", + "toml_edit 0.20.2", ] [[package]] @@ -3008,6 +3009,15 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_spanned" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1" +dependencies = [ + "serde", +] + [[package]] name = "serde_urlencoded" version = "0.7.1" @@ -3432,11 +3442,26 @@ dependencies = [ "tracing", ] +[[package]] +name = "toml" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9dd1545e8208b4a5af1aa9bbd0b4cf7e9ea08fabc5d0a5c67fcaafa17433aa3" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit 0.22.9", +] + [[package]] name = "toml_datetime" version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" +dependencies = [ + "serde", +] [[package]] name = "toml_edit" @@ -3446,7 +3471,20 @@ checksum = "396e4d48bbb2b7554c944bde63101b5ae446cff6ec4a24227428f15eb72ef338" dependencies = [ "indexmap 2.2.5", "toml_datetime", - "winnow", + "winnow 0.5.40", +] + +[[package]] +name = "toml_edit" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e40bb779c5187258fd7aad0eb68cb8706a0a81fa712fbea808ab43c4b8374c4" +dependencies = [ + "indexmap 2.2.5", + "serde", + "serde_spanned", + "toml_datetime", + "winnow 0.6.6", ] [[package]] @@ -3980,6 +4018,15 @@ dependencies = [ "memchr", ] +[[package]] +name = "winnow" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0c976aaaa0e1f90dbb21e9587cdaf1d9679a1cde8875c0d6bd83ab96a208352" +dependencies = [ + "memchr", +] + [[package]] name = "winreg" version = "0.50.0" diff --git a/common/src/prover_state/mod.rs b/common/src/prover_state/mod.rs index b2c18e39..44463b53 100644 --- a/common/src/prover_state/mod.rs +++ b/common/src/prover_state/mod.rs @@ -15,30 +15,24 @@ use std::{fmt::Display, sync::OnceLock}; use clap::ValueEnum; use evm_arithmetization::{ - cpu::kernel::aggregator::KERNEL, proof::AllProof, prover::prove, AllStark, GenerationInputs, - StarkConfig, + proof::AllProof, prover::prove, AllStark, GenerationInputs, StarkConfig, }; use plonky2::{ - field::goldilocks_field::GoldilocksField, - plonk::config::{GenericHashOut, PoseidonGoldilocksConfig}, + field::goldilocks_field::GoldilocksField, plonk::config::PoseidonGoldilocksConfig, util::timing::TimingTree, }; use proof_gen::{proof_types::GeneratedTxnProof, prover_state::ProverState, VerifierState}; use tracing::info; use self::circuit::{CircuitConfig, NUM_TABLES}; -use crate::prover_state::{ - persistence::{ - BaseProverResource, DiskResource, MonolithicProverResource, RecursiveCircuitResource, - VerifierResource, - }, - utils::pkg_consistency_check, +use crate::prover_state::persistence::{ + BaseProverResource, DiskResource, MonolithicProverResource, RecursiveCircuitResource, + VerifierResource, }; pub mod circuit; pub mod cli; pub mod persistence; -mod utils; pub(crate) type Config = PoseidonGoldilocksConfig; pub(crate) type Field = GoldilocksField; @@ -259,18 +253,6 @@ impl ProverStateManager { CircuitPersistence::Disk(strategy) => { info!("attempting to load preprocessed circuits from disk..."); - // Check the package consistency before loading the circuits. - pkg_consistency_check([ - self.circuit_config - .as_all_recursive_circuits() - .block - .circuit - .verifier_only - .circuit_digest - .to_bytes(), - KERNEL.hash().to_fixed_bytes().to_vec(), - ]); - let disk_state = match strategy { TableLoadStrategy::OnDemand => BaseProverResource::get(&self.circuit_config), TableLoadStrategy::Monolithic => { diff --git a/common/src/prover_state/persistence.rs b/common/src/prover_state/persistence.rs index dae26e64..cd33b04e 100644 --- a/common/src/prover_state/persistence.rs +++ b/common/src/prover_state/persistence.rs @@ -1,3 +1,4 @@ +use std::env; use std::{ fmt::{Debug, Display}, fs::{self, OpenOptions}, @@ -16,7 +17,7 @@ use super::{ Config, RecursiveCircuitsForTableSize, SIZE, }; -pub(crate) const CIRCUITS_FOLDER: &str = "./circuits"; +const CIRCUITS_FOLDER: &str = "./circuits"; const PROVER_STATE_FILE_PREFIX: &str = "prover_state"; const VERIFIER_STATE_FILE_PREFIX: &str = "verifier_state"; @@ -102,9 +103,10 @@ impl DiskResource for BaseProverResource { fn path(p: &Self::PathConstrutor) -> impl AsRef { format!( - "{}/{}_base_{}", + "{}/{}_base_{}_{}", CIRCUITS_FOLDER, PROVER_STATE_FILE_PREFIX, + env::var("EVM_ARITHMETIZATION_PKG_VER").unwrap_or("NA".to_string()), p.get_configuration_digest() ) } @@ -137,9 +139,10 @@ impl DiskResource for MonolithicProverResource { fn path(p: &Self::PathConstrutor) -> impl AsRef { format!( - "{}/{}_monolithic_{}", + "{}/{}_monolithic_{}_{}", CIRCUITS_FOLDER, PROVER_STATE_FILE_PREFIX, + env::var("EVM_ARITHMETIZATION_PKG_VER").unwrap_or("NA".to_string()), p.get_configuration_digest() ) } @@ -171,9 +174,10 @@ impl DiskResource for RecursiveCircuitResource { fn path((circuit_type, size): &Self::PathConstrutor) -> impl AsRef { format!( - "{}/{}_{}_{}", + "{}/{}_{}_{}_{}", CIRCUITS_FOLDER, PROVER_STATE_FILE_PREFIX, + env::var("EVM_ARITHMETIZATION_PKG_VER").unwrap_or("NA".to_string()), circuit_type.as_short_str(), size ) @@ -214,9 +218,10 @@ impl DiskResource for VerifierResource { fn path(p: &Self::PathConstrutor) -> impl AsRef { format!( - "{}/{}_{}", + "{}/{}_{}_{}", CIRCUITS_FOLDER, VERIFIER_STATE_FILE_PREFIX, + env::var("EVM_ARITHMETIZATION_PKG_VER").unwrap_or("NA".to_string()), p.get_configuration_digest() ) } diff --git a/common/src/prover_state/utils.rs b/common/src/prover_state/utils.rs deleted file mode 100644 index 21d042aa..00000000 --- a/common/src/prover_state/utils.rs +++ /dev/null @@ -1,90 +0,0 @@ -use std::fs::{self, File}; -use std::hash::Hasher; -use std::io::{Read, Write}; -use std::path::Path; - -use seahash::SeaHasher; -use tracing::{info, warn}; - -use super::persistence::CIRCUITS_FOLDER; - -/// Checks the consistency of circuits code by comparing a computed hash -/// derived from the provided array of circuit code hashes against a reference -/// hash stored in a designated file within the circuits folder. This function -/// performs several actions based on this comparison: -/// -/// - If the computed aggregate hash differs from the stored hash, or if the -/// hash file does not exist, the function will delete the existing circuits -/// folder (if it exists), recreate it, and then write the new computed hash -/// into the hash file. -/// -/// - If the computed hash matches the stored hash, indicating no changes in the -/// circuits code, the function takes no action. -/// -/// This process ensures that the stored hash always reflects the current state -/// of the circuits code, providing a mechanism for detecting changes and -/// maintaining consistency. -/// -/// # Parameters -/// -/// * `circuits_hashes` - A dynamic number of `Vec` arguments representing -/// circuit code hashes. -/// -/// # Side Effects -/// -/// - May delete and recreate the circuits folder. -/// - May modify or create a file within the circuits folder to store the latest -/// hash. -pub(crate) fn pkg_consistency_check(circuits_hashes: I) -where - I: IntoIterator, - T: AsRef<[u8]>, -{ - let mut hasher = SeaHasher::new(); - for hash in circuits_hashes { - hasher.write(hash.as_ref()); - } - let hash = hasher.finish(); - - let hash_file_path = Path::new(CIRCUITS_FOLDER).join("circuits_consistency_hash"); - - // Check if the circuits folder exists - match fs::metadata(CIRCUITS_FOLDER) { - Ok(_) => { - // Circuits folder exists, check the hash file - let mut existing_hash = String::new(); - if let Ok(mut hash_file) = File::open(&hash_file_path) { - // If the hash file exists and can be read, compare the hash - if hash_file.read_to_string(&mut existing_hash).is_ok() - && existing_hash == hash.to_string() - { - // Hashes are the same, do nothing - return; - } - } else { - warn!("Unable to read circuits consistency hash file"); - } - - // Hashes differ or hash file cannot be read, delete the folder - if fs::remove_dir_all(CIRCUITS_FOLDER).is_err() { - panic!("Failed to delete circuits storage folder"); - } - } - Err(_) => { - info!( - "Initializing circuits storage folder with new consistency hash: {}", - hash - ); - } - } - - // Recreate the circuits folder and write the new hash - if fs::create_dir(CIRCUITS_FOLDER).is_ok() { - if let Ok(mut hash_file) = File::create(&hash_file_path) { - // Ignore errors in writing the hash - let _ = hash_file.write_all(hash.to_string().as_bytes()); - } - } else { - panic!("Failed to create circuits storage folder"); - } -} diff --git a/leader/Cargo.toml b/leader/Cargo.toml index 5c7bcc92..de39328a 100644 --- a/leader/Cargo.toml +++ b/leader/Cargo.toml @@ -22,6 +22,7 @@ serde_json = { workspace = true } serde_path_to_error = { workspace = true } ethereum-types = { workspace = true } axum = "0.7.4" +toml = "0.8.12" # Local dependencies ops = { path = "../ops" } diff --git a/leader/src/main.rs b/leader/src/main.rs index 8c054ea4..5fc4d767 100644 --- a/leader/src/main.rs +++ b/leader/src/main.rs @@ -1,3 +1,4 @@ +use std::env; use std::{fs::File, path::PathBuf}; use anyhow::Result; @@ -9,11 +10,14 @@ use ops::register; use paladin::runtime::Runtime; use proof_gen::types::PlonkyProofIntern; +use crate::utils::get_package_version; + mod cli; mod http; mod init; mod jerigon; mod stdio; +mod utils; fn get_previous_proof(path: Option) -> Result> { if path.is_none() { @@ -32,6 +36,19 @@ async fn main() -> Result<()> { dotenv().ok(); init::tracing(); + if env::var("EVM_ARITHMETIZATION_PKG_VER").is_err() { + let pkg_ver = get_package_version("evm_arithmetization")?; + // Extract the major and minor version parts and append 'x' as the patch version + if let Some((major_minor, _)) = pkg_ver.as_ref().and_then(|s| s.rsplit_once('.')) { + let circuits_version = format!("{}.x", major_minor); + // Set the environment variable for the evm_arithmetization package version + env::set_var("EVM_ARITHMETIZATION_PKG_VER", circuits_version); + } else { + // Set to "NA" if version extraction fails + env::set_var("EVM_ARITHMETIZATION_PKG_VER", "NA"); + } + } + let args = cli::Cli::parse(); if let paladin::config::Runtime::InMemory = args.paladin.runtime { // If running in emulation mode, we'll need to initialize the prover diff --git a/leader/src/utils.rs b/leader/src/utils.rs new file mode 100644 index 00000000..e2c7d5f1 --- /dev/null +++ b/leader/src/utils.rs @@ -0,0 +1,72 @@ +use std::fs::File; +use std::io::{BufReader, Read}; +use std::path::Path; + +use anyhow::Result; + +/// Retrieves the version of a specified package from the `Cargo.lock` file. +/// +/// This function attempts to find the version of a package specified by +/// `package_name` by reading and parsing the `Cargo.lock` file. The +/// `Cargo.lock` file is expected to be located one directory level up from the +/// directory specified by the `CARGO_MANIFEST_DIR` environment variable. The +/// path may need adjustment depending on the structure of the project. +/// +/// # Parameters +/// - `package_name`: The name of the package for which the version is being +/// retrieved. +/// +/// # Returns +/// - `Ok(Some(String))`: If the package is found in the `Cargo.lock` file, +/// returns the version of the package. +/// - `Ok(None)`: If the package is not found in the `Cargo.lock` file, or if +/// the `Cargo.lock` file does not exist. +/// - `Err(_)`: If any error occurs during the execution, such as issues with +/// file paths, file access, reading, or parsing the `Cargo.lock` file. +/// +/// # Examples +/// ```no_run +/// let version = get_package_version("my_package"); +/// match version { +/// Ok(Some(ver)) => println!("Found version: {}", ver), +/// Ok(None) => println!("Package not found."), +/// Err(e) => println!("Error occurred: {}", e), +/// } +/// ``` +/// +/// # Errors +/// This function can return an `Err` result if: +/// - There is a problem finding, opening, or reading the `Cargo.lock` file. +/// - There is a failure in parsing the `Cargo.lock` file as TOML. +/// +/// The function uses `?` to propagate errors upwards, so the exact nature of +/// the error will be indicated by the error value returned in the `Err` variant +/// of the `Result`. +pub(crate) fn get_package_version(package_name: &str) -> Result> { + let manifest_dir = env!("CARGO_MANIFEST_DIR"); + let zero_bin_path = Path::new(manifest_dir) + .join("../") // Adjust the path according to your workspace structure + .canonicalize()?; + + let cargo_lock_path = zero_bin_path.join("Cargo.lock"); + let cargo_lock_file = File::open(cargo_lock_path); + if cargo_lock_file.is_err() { + return Ok(None); + } + + let mut cargo_lock_contents = String::new(); + BufReader::new(cargo_lock_file?).read_to_string(&mut cargo_lock_contents)?; + + let lockfile: toml::Value = toml::from_str(&cargo_lock_contents)?; + if let Some(package) = lockfile["package"] + .as_array() + .unwrap() + .iter() + .find(|&p| p["name"].as_str() == Some(package_name)) + { + let version = package["version"].as_str().unwrap(); + return Ok(Some(version.to_string())); + } + + Ok(None) +} From d913fad47631509ab94439eee9398c804835e7ef Mon Sep 17 00:00:00 2001 From: Robin Salen <30937548+Nashtare@users.noreply.github.com> Date: Thu, 25 Apr 2024 03:35:51 +0900 Subject: [PATCH 25/29] Reduce sizes and add distinction with test_only mode (#69) --- tools/simple_test.sh | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/tools/simple_test.sh b/tools/simple_test.sh index 89f1900b..f00e34ce 100755 --- a/tools/simple_test.sh +++ b/tools/simple_test.sh @@ -22,14 +22,26 @@ export RUST_BACKTRACE=full export RUST_LOG=info export RUSTFLAGS='-C target-cpu=native' -# This sizes are configured specifically for this witness. Don't use this in other scenarios -export ARITHMETIC_CIRCUIT_SIZE="16..19" -export BYTE_PACKING_CIRCUIT_SIZE="9..19" -export CPU_CIRCUIT_SIZE="12..21" -export KECCAK_CIRCUIT_SIZE="14..18" -export KECCAK_SPONGE_CIRCUIT_SIZE="9..13" -export LOGIC_CIRCUIT_SIZE="12..17" -export MEMORY_CIRCUIT_SIZE="17..23" +if [[ $1 == "test_only" ]]; then + # Circuit sizes don't matter in test_only mode, so we keep them minimal. + export ARITHMETIC_CIRCUIT_SIZE="16..17" + export BYTE_PACKING_CIRCUIT_SIZE="9..10" + export CPU_CIRCUIT_SIZE="12..13" + export KECCAK_CIRCUIT_SIZE="14..15" + export KECCAK_SPONGE_CIRCUIT_SIZE="9..10" + export LOGIC_CIRCUIT_SIZE="12..13" + export MEMORY_CIRCUIT_SIZE="17..18" +else + # These sizes are configured specifically for this witness. Don't use this in other scenarios + export ARITHMETIC_CIRCUIT_SIZE="16..19" + export BYTE_PACKING_CIRCUIT_SIZE="16..19" + export CPU_CIRCUIT_SIZE="18..21" + export KECCAK_CIRCUIT_SIZE="15..18" + export KECCAK_SPONGE_CIRCUIT_SIZE="10..13" + export LOGIC_CIRCUIT_SIZE="13..17" + export MEMORY_CIRCUIT_SIZE="20..23" +fi + # If we run ./simple_test test_only, we'll generate a dummy # proof. This is useful for quickly testing decoding and all of the From d008579dbf13262ab5cfc22d5a20d96e79c9bc38 Mon Sep 17 00:00:00 2001 From: StephenMal Date: Wed, 15 May 2024 22:37:07 -0400 Subject: [PATCH 26/29] Merged, formatted, and updated coordinator --- coordinator/README.md | 1 - coordinator/benchmark_out/test.csv | 17 ++++------------- coordinator/src/benchmarking.rs | 2 +- coordinator/src/fetch.rs | 2 +- coordinator/src/main.rs | 16 +++++++++------- coordinator/src/manyprover.rs | 2 +- coordinator/src/proofout.rs | 4 ++-- leader/src/http.rs | 2 +- leader/src/init.rs | 2 +- leader/src/main.rs | 4 +--- leader/src/stdio.rs | 2 +- prover/src/lib.rs | 2 -- 12 files changed, 22 insertions(+), 34 deletions(-) diff --git a/coordinator/README.md b/coordinator/README.md index 8b2c37c0..2c7f8990 100644 --- a/coordinator/README.md +++ b/coordinator/README.md @@ -117,7 +117,6 @@ The example below proves blocks [1,10] using the RPC function listed in ZeroBin, "LocalCsv": {"file_name": "test.csv"} } } - ``` An example not recording the proofs, and posting the results to a google cloud storage bucket. diff --git a/coordinator/benchmark_out/test.csv b/coordinator/benchmark_out/test.csv index 94ab5dee..f580a989 100644 --- a/coordinator/benchmark_out/test.csv +++ b/coordinator/benchmark_out/test.csv @@ -1,13 +1,4 @@ -block_number, number_txs, cumulative_number_txs, fetch_duration, proof_duration, start_time, end_time, overall_elapsed_time, gas_used, cumulative_gas_used, difficulty -1, 0, 0, 0.227381933, 39.766265738, 22-04-2024 20:45:08, 22-04-2024 20:45:48, 39, , 0, 0, 0 -2, 0, 0, 0.194498042, 38.174294584, 22-04-2024 20:45:48, 22-04-2024 20:46:26, 78, , 0, 0, 0 -3, 0, 0, 0.197080469, 38.187381102, 22-04-2024 20:46:26, 22-04-2024 20:47:04, 116, , 0, 0, 0 -4, 0, 0, 0.217940745, 39.290464606, 22-04-2024 20:47:04, 22-04-2024 20:47:44, 156, , 0, 0, 0 -5, 0, 0, 0.261670667, 38.434026174, 22-04-2024 20:47:44, 22-04-2024 20:48:22, 194, , 0, 0, 0 -6, 2, 2, 0.233287003, 49.359168004, 22-04-2024 20:48:23, 22-04-2024 20:49:12, 244, , 42000, 42000, 0 -7, 12, 14, 0.23193661, 298.087307262, 22-04-2024 20:49:12, 22-04-2024 20:54:10, 542, , 252000, 294000, 0 -8, 12, 26, 0.237749989, 297.708125794, 22-04-2024 20:54:11, 22-04-2024 20:59:08, 840, , 252000, 546000, 0 -9, 12, 38, 0.237137239, 291.595695813, 22-04-2024 20:59:09, 22-04-2024 21:04:00, 1132, , 252000, 798000, 0 -10, 12, 50, 0.259230894, 301.417539331, 22-04-2024 21:04:00, 22-04-2024 21:09:02, 1434, , 252000, 1050000, 0 -11, 12, 62, 0.292225091, 296.567452628, 22-04-2024 21:09:02, 22-04-2024 21:13:59, 1731, , 252000, 1302000, 0 -12, 12, 74, 0.271883967, 299.935117167, 22-04-2024 21:13:59, 22-04-2024 21:18:59, 2031, , 252000, 1554000, 0 \ No newline at end of file +block_number, number_txs, cumulative_number_txs, fetch_duration, proof_duration, start_time, end_time, overall_elapsed_time, proof_out_duration, gas_used, gas_used_per_tx, cumulative_gas_used, difficulty +19, 0, 0, 0.416245218, 39.113425192, 16-05-2024 01:46:20, 16-05-2024 01:46:59, 39, , 0, "", 0, 0 +20, 0, 0, 0.365843929, 39.78131432, 16-05-2024 01:46:59, 16-05-2024 01:47:39, 79, , 0, "", 0, 0 +21, 0, 0, 0.371192162, 40.249504184, 16-05-2024 01:47:39, 16-05-2024 01:48:20, 120, , 0, "", 0, 0 \ No newline at end of file diff --git a/coordinator/src/benchmarking.rs b/coordinator/src/benchmarking.rs index 9489809f..3e60e963 100644 --- a/coordinator/src/benchmarking.rs +++ b/coordinator/src/benchmarking.rs @@ -8,8 +8,8 @@ use google_cloud_storage::{ client::{Client, ClientConfig}, http::objects::upload::{Media, UploadObjectRequest, UploadType}, }; -use tracing::{debug, error, info, warn}; use serde::{Deserialize, Serialize}; +use tracing::{debug, error, info, warn}; //================================================================================== // Benchmarking Statistics diff --git a/coordinator/src/fetch.rs b/coordinator/src/fetch.rs index 60981577..e7452389 100644 --- a/coordinator/src/fetch.rs +++ b/coordinator/src/fetch.rs @@ -1,8 +1,8 @@ //! This is useful for fetching [ProverInput] per block use anyhow::Error; -use tracing::{error, info}; use prover::ProverInput; use rpc::{fetch_prover_input, FetchProverInputRequest}; +use tracing::{error, info}; use super::input::BlockSource; diff --git a/coordinator/src/main.rs b/coordinator/src/main.rs index 2a66e498..fa6434db 100644 --- a/coordinator/src/main.rs +++ b/coordinator/src/main.rs @@ -10,13 +10,13 @@ use actix_web::{web, App, HttpResponse, HttpServer, Responder}; use anyhow::Result; use common::prover_state; use dotenvy::dotenv; -// use leader::init; -use log::{debug, error, info, warn}; use ops::register; use paladin::{ config::{Config, Serializer}, runtime::Runtime, }; +// use leader::init; +use tracing::{debug, error, info, warn}; pub mod benchmarking; pub mod fetch; @@ -39,12 +39,14 @@ async fn main() -> Result<()> { debug!("Loading dotenv"); dotenv().ok(); + leader::init::tracing(); + // Loading the logger - debug!("Loading env_logger"); - let mut builder = env_logger::Builder::from_default_env(); - builder.target(env_logger::Target::Stdout); // Redirect logs to stdout - builder.init(); - debug!("EnvLogger setup"); + // debug!("Loading env_logger"); + // let mut builder = env_logger::Builder::from_default_env(); + // builder.target(env_logger::Target::Stdout); // Redirect logs to stdout + // builder.init(); + // debug!("EnvLogger setup"); // Initialize the tracing (stolen from Leader Crate's init function) // This will initialize a lot of the internal logging, however diff --git a/coordinator/src/manyprover.rs b/coordinator/src/manyprover.rs index a864572c..15ca17e4 100644 --- a/coordinator/src/manyprover.rs +++ b/coordinator/src/manyprover.rs @@ -9,11 +9,11 @@ use std::time::{Instant, SystemTime}; use async_channel; use chrono::{DateTime, Utc}; -use tracing::{debug, error, info, warn}; use paladin::runtime::Runtime; use proof_gen::proof_types::GeneratedBlockProof; use proof_gen::types::PlonkyProofIntern; use tokio::task::JoinError; +use tracing::{debug, error, info, warn}; use crate::benchmarking::{ BenchmarkingOutput, BenchmarkingOutputBuildError, BenchmarkingOutputError, BenchmarkingStats, diff --git a/coordinator/src/proofout.rs b/coordinator/src/proofout.rs index 98120846..664836f8 100644 --- a/coordinator/src/proofout.rs +++ b/coordinator/src/proofout.rs @@ -2,10 +2,10 @@ // std imports use std::{env::VarError, fs::create_dir_all, path::PathBuf}; -// 3rd party imports -use tracing::{debug, error, info, warn}; use proof_gen::proof_types::GeneratedBlockProof; use serde_json::to_writer; +// 3rd party imports +use tracing::{debug, error, info, warn}; #[derive(Debug)] pub enum ProofOutputError { diff --git a/leader/src/http.rs b/leader/src/http.rs index 80111ce4..1b950f3b 100644 --- a/leader/src/http.rs +++ b/leader/src/http.rs @@ -11,7 +11,7 @@ use serde_json::to_writer; use tracing::{debug, error, info}; /// The main function for the HTTP mode. -pub(crate) async fn http_main( +pub async fn http_main( runtime: Runtime, port: u16, output_dir: PathBuf, diff --git a/leader/src/init.rs b/leader/src/init.rs index f9391489..74453f9b 100644 --- a/leader/src/init.rs +++ b/leader/src/init.rs @@ -1,5 +1,5 @@ use tracing_subscriber::{prelude::*, util::SubscriberInitExt, EnvFilter}; -pub(crate) fn tracing() { +pub fn tracing() { tracing_subscriber::Registry::default() .with( tracing_subscriber::fmt::layer() diff --git a/leader/src/main.rs b/leader/src/main.rs index c4ed8631..5fc4d767 100644 --- a/leader/src/main.rs +++ b/leader/src/main.rs @@ -34,9 +34,7 @@ fn get_previous_proof(path: Option) -> Result #[tokio::main] async fn main() -> Result<()> { dotenv().ok(); - #[cfg(feature = "extra_log")] - env_logger::init(); - // init::tracing(); + init::tracing(); if env::var("EVM_ARITHMETIZATION_PKG_VER").is_err() { let pkg_ver = get_package_version("evm_arithmetization")?; diff --git a/leader/src/stdio.rs b/leader/src/stdio.rs index 7f1e6e3f..b747419d 100644 --- a/leader/src/stdio.rs +++ b/leader/src/stdio.rs @@ -6,7 +6,7 @@ use proof_gen::types::PlonkyProofIntern; use prover::ProverInput; /// The main function for the stdio mode. -pub(crate) async fn stdio_main( +pub async fn stdio_main( runtime: Runtime, previous: Option, save_inputs_on_error: bool, diff --git a/prover/src/lib.rs b/prover/src/lib.rs index 5cc58a82..710a75ab 100644 --- a/prover/src/lib.rs +++ b/prover/src/lib.rs @@ -3,8 +3,6 @@ use ethereum_types::U256; #[cfg(feature = "test_only")] use futures::stream::TryStreamExt; use ops::TxProof; -#[cfg(not(feature = "test_only"))] -use paladin::directive::Literal; use paladin::{ directive::{Directive, IndexedStream}, runtime::Runtime, From 6f8283b58a1ebb7a3176ac0b356698db535b0c66 Mon Sep 17 00:00:00 2001 From: StephenMal Date: Wed, 15 May 2024 22:41:12 -0400 Subject: [PATCH 27/29] ran fmt --- ops/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ops/src/lib.rs b/ops/src/lib.rs index 9f9fbfaf..5b6caf69 100644 --- a/ops/src/lib.rs +++ b/ops/src/lib.rs @@ -23,7 +23,7 @@ pub struct TxProof { #[cfg(not(feature = "test_only"))] impl Operation for TxProof { - type Input = GenerationInputs; + type Input = GenerationInputs; type Output = proof_gen::proof_types::AggregatableProof; fn execute(&self, input: Self::Input) -> Result { From b35dcc604b3aecf3da60c1083f78f802820646b6 Mon Sep 17 00:00:00 2001 From: StephenMal Date: Wed, 15 May 2024 22:52:13 -0400 Subject: [PATCH 28/29] uncommented tracing --- worker/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worker/src/main.rs b/worker/src/main.rs index 33b4eaef..86ce0744 100644 --- a/worker/src/main.rs +++ b/worker/src/main.rs @@ -19,7 +19,7 @@ struct Cli { #[tokio::main] async fn main() -> Result<()> { dotenv().ok(); - // init::tracing(); + init::tracing(); let args = Cli::parse(); From 43e5cb6ff8c652747cc43da5424d69d4ea954517 Mon Sep 17 00:00:00 2001 From: Julian Braha <103399117+julian-bcw@users.noreply.github.com> Date: Mon, 20 May 2024 13:21:49 +0100 Subject: [PATCH 29/29] Update Cargo.toml --- Cargo.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Cargo.toml b/Cargo.toml index cb62eebd..9d2ad1a0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -43,3 +43,6 @@ opt-level = 3 incremental = true lto = "fat" codegen-units = 1 + +[build] +rustflags = ["-C", "target-cpu=native"]