diff --git a/Cargo.lock b/Cargo.lock index 3975818f0..1f8ecd2db 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1043,6 +1043,7 @@ dependencies = [ "digest 0.10.7", "fnv", "merlin", + "rayon", "sha2 0.10.9", ] @@ -1075,6 +1076,7 @@ dependencies = [ "num-bigint 0.4.6", "num-integer", "num-traits", + "rayon", "zeroize", ] @@ -1133,6 +1135,7 @@ dependencies = [ "num-bigint 0.4.6", "num-traits", "paste", + "rayon", "zeroize", ] @@ -1217,6 +1220,7 @@ dependencies = [ "ark-relations", "ark-serialize 0.5.0", "ark-std 0.5.0", + "rayon", ] [[package]] @@ -1232,6 +1236,7 @@ dependencies = [ "educe", "fnv", "hashbrown 0.15.4", + "rayon", ] [[package]] @@ -1295,6 +1300,7 @@ dependencies = [ "arrayvec", "digest 0.10.7", "num-bigint 0.4.6", + "rayon", ] [[package]] @@ -1348,6 +1354,7 @@ checksum = "246a225cc6131e9ee4f24619af0f19d67761fff15d7ccc22e42b80846e69449a" dependencies = [ "num-traits", "rand 0.8.5", + "rayon", ] [[package]] @@ -2410,6 +2417,19 @@ dependencies = [ "digest 0.10.7", ] +[[package]] +name = "blake3" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3888aaa89e4b2a40fca9848e400f6a658a5a3978de7be858e209cafa8be9a4a0" +dependencies = [ + "arrayref", + "arrayvec", + "cc", + "cfg-if", + "constant_time_eq", +] + [[package]] name = "block" version = "0.1.6" @@ -2465,11 +2485,23 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0bce8d6acc5286a16e94c29e9c885d1869358885e08a6feeb6bc54e36fe20055" dependencies = [ - "duplicate", + "duplicate 1.0.0", "maybe-async", "reqwest", "serde", "thiserror 1.0.69", +] + +[[package]] +name = "bonsai-sdk" +version = "1.4.1" +source = "git+https://github.com/risc0/risc0?branch=flaub%2Fshrink-bitvm2#6ed3f0321638ae7eb9c097b8aa8becba3f4b1350" +dependencies = [ + "duplicate 2.0.0", + "maybe-async", + "reqwest", + "serde", + "thiserror 2.0.12", "tokio", ] @@ -2549,7 +2581,7 @@ dependencies = [ "alloy", "anyhow", "bincode", - "bonsai-sdk", + "bonsai-sdk 1.4.1", "boundless-assessor", "boundless-market", "boundless-market-test-utils", @@ -2569,8 +2601,10 @@ dependencies = [ "serde_json", "serde_yaml 0.9.34+deprecated", "shadow-rs", + "shrink_bitvm2", "sqlx", "tempfile", + "test-log", "tokio", "tracing", "tracing-subscriber 0.3.19", @@ -2680,6 +2714,7 @@ dependencies = [ "guest-assessor", "guest-set-builder", "guest-util", + "hex", "risc0-aggregation", "risc0-circuit-recursion", "risc0-ethereum-contracts", @@ -2737,13 +2772,19 @@ dependencies = [ "alloy", "alloy-chains", "anyhow", + "ark-bn254", + "ark-ec", + "ark-ff 0.5.0", + "ark-groth16", + "ark-serialize 0.5.0", "async-channel 2.5.0", "async-trait", "aws-config", "aws-sdk-s3", "aws-smithy-http-client", "bincode", - "bonsai-sdk", + "blake3", + "bonsai-sdk 1.4.1", "boundless-assessor", "boundless-market", "boundless-market-test-utils", @@ -2759,6 +2800,8 @@ dependencies = [ "httpmock", "moka", "notify", + "num-bigint 0.4.6", + "num-traits", "proptest", "proptest-derive", "rand 0.9.1", @@ -2767,14 +2810,17 @@ dependencies = [ "reqwest-retry", "risc0-aggregation", "risc0-ethereum-contracts", + "risc0-groth16", "risc0-zkvm", "serde", "serde_json", "serial_test", "sha2 0.10.9", + "shrink_bitvm2", "sqlx", "temp-env", "tempfile", + "test-log", "thiserror 2.0.12", "tokio", "tokio-util", @@ -3179,6 +3225,12 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "constant_time_eq" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" + [[package]] name = "convert_case" version = "0.4.0" @@ -3797,6 +3849,17 @@ dependencies = [ "proc-macro-error", ] +[[package]] +name = "duplicate" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97af9b5f014e228b33e77d75ee0e6e87960124f0f4b16337b586a6bec91867b1" +dependencies = [ + "heck 0.5.0", + "proc-macro2", + "proc-macro2-diagnostics", +] + [[package]] name = "dyn-clone" version = "1.0.19" @@ -7123,6 +7186,19 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "proc-macro2-diagnostics" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", + "version_check", + "yansi", +] + [[package]] name = "proptest" version = "1.7.0" @@ -8059,8 +8135,6 @@ dependencies = [ [[package]] name = "risc0-ethereum-contracts" version = "2.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d3a6978f67c13fcf3e9123d28882368a3a3d686f881a35bb0caaebc585f93d6" dependencies = [ "alloy", "alloy-primitives 1.2.1", @@ -8192,7 +8266,7 @@ dependencies = [ "addr2line 0.22.0", "anyhow", "bincode", - "bonsai-sdk", + "bonsai-sdk 1.4.0", "borsh", "bytemuck", "bytes", @@ -9056,6 +9130,29 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +[[package]] +name = "shrink_bitvm2" +version = "0.14.0" +dependencies = [ + "anyhow", + "ark-bn254", + "ark-ff 0.5.0", + "ark-groth16", + "ark-serialize 0.5.0", + "blake3", + "hex", + "num-bigint 0.4.6", + "num-traits", + "risc0-groth16", + "risc0-zkvm", + "serde", + "serde_json", + "sha2 0.10.9", + "tempfile", + "tokio", + "tracing", +] + [[package]] name = "signal-hook-registry" version = "1.4.5" diff --git a/Cargo.toml b/Cargo.toml index 8c2814263..75d6b605b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,7 +14,7 @@ members = [ "crates/indexer", "crates/ops-lambdas/indexer-monitor", "crates/order-generator", - "crates/order-stream", + "crates/order-stream", "crates/shrink_bitvm2", "crates/slasher", "documentation/doc-test", ] @@ -34,6 +34,7 @@ distributor = { path = "crates/distributor" } guest-assessor = { path = "crates/guest/assessor" } guest-util = { path = "crates/guest/util" } order-stream = { path = "crates/order-stream" } +shrink_bitvm2 = { path = "crates/shrink_bitvm2" } async-stream = "0.3" alloy = { version = "1.0.24", default-features = false } @@ -47,7 +48,7 @@ aws-sdk-s3 = "1.34" # used for minio for max compatibility axum = "0.8" axum-extra = { version = "0.10" } bincode = "1.3" -bonsai-sdk = { version = "1.4", features = ["non_blocking"] } +bonsai-sdk = { git = "https://github.com/risc0/risc0", branch = "flaub/shrink-bitvm2", features = ["non_blocking", "shrink_bitvm2"] } bs58 = "0.5" bytemuck = "1.16" clap = { version = "4.5", features = ["derive", "env"] } @@ -97,3 +98,6 @@ lto = true # [profile.release] # lto = "fat" # codegen-units = 1 + +[patch.crates-io] +risc0-ethereum-contracts = { path = "/home/etu/risc0-ethereum/contracts" } diff --git a/contracts/scripts/Deploy.s.sol b/contracts/scripts/Deploy.s.sol index 0fec60a0c..1c5cecc0d 100644 --- a/contracts/scripts/Deploy.s.sol +++ b/contracts/scripts/Deploy.s.sol @@ -10,6 +10,7 @@ import "forge-std/Test.sol"; import {IRiscZeroSelectable} from "risc0/IRiscZeroSelectable.sol"; import {IRiscZeroVerifier} from "risc0/IRiscZeroVerifier.sol"; import {ControlID, RiscZeroGroth16Verifier} from "risc0/groth16/RiscZeroGroth16Verifier.sol"; +import {RiscZeroBitvm2Groth16Verifier} from "risc0/bitvm/RiscZeroBitvm2Groth16Verifier.sol"; import {RiscZeroSetVerifier} from "risc0/RiscZeroSetVerifier.sol"; import {RiscZeroVerifierRouter} from "risc0/RiscZeroVerifierRouter.sol"; import {RiscZeroCheats} from "risc0/test/RiscZeroCheats.sol"; @@ -66,6 +67,16 @@ contract Deploy is Script, RiscZeroCheats { IRiscZeroSelectable selectable = IRiscZeroSelectable(address(_verifier)); bytes4 selector = selectable.SELECTOR(); verifierRouter.addVerifier(selector, _verifier); + console2.log("Added Groth16 verifier to router with selector"); + console2.logBytes4(selector); + + + IRiscZeroVerifier _bitvm2_verifier = deployRiscZeroBitvm2Verifier(); + IRiscZeroSelectable bitvm2_selectable = IRiscZeroSelectable(address(_bitvm2_verifier)); + bytes4 bitvm_selector = bitvm2_selectable.SELECTOR(); + verifierRouter.addVerifier(bitvm_selector, _bitvm2_verifier); + console2.log("Added BitVM2 verifier to router with selector"); + console2.logBytes4(bitvm_selector); // TODO: Create a more robust way of getting a URI for guests, and ensure that it is // in-sync with the configured image ID. diff --git a/contracts/test/BoundlessMarket.t.sol b/contracts/test/BoundlessMarket.t.sol index ac4398c04..b5bce60a0 100644 --- a/contracts/test/BoundlessMarket.t.sol +++ b/contracts/test/BoundlessMarket.t.sol @@ -19,7 +19,7 @@ import { ReceiptClaimLib, VerificationFailed } from "risc0/IRiscZeroVerifier.sol"; -import {TestReceipt} from "risc0/../test/TestReceipt.sol"; +import {TestReceipt} from "risc0/../test/TestReceiptV2_1.sol"; import {RiscZeroMockVerifier} from "risc0/test/RiscZeroMockVerifier.sol"; import {TestUtils} from "./TestUtils.sol"; import {Client} from "./clients/Client.sol"; diff --git a/crates/boundless-cli/Cargo.toml b/crates/boundless-cli/Cargo.toml index c7f37bdae..bb1f1684b 100644 --- a/crates/boundless-cli/Cargo.toml +++ b/crates/boundless-cli/Cargo.toml @@ -34,7 +34,9 @@ serde = { workspace = true } serde_json = { workspace = true } serde_yaml = { workspace = true } shadow-rs = { version = "1.1", default-features = false } +shrink_bitvm2 = { workspace = true } sqlx = { workspace = true, features = ["postgres", "runtime-tokio", "tls-rustls", "chrono"] } +tempfile = { workspace = true } tokio = { workspace = true, features = ["rt-multi-thread"] } tracing = { workspace = true } tracing-subscriber = { workspace = true, features = ["env-filter"] } @@ -53,9 +55,11 @@ order-stream = { workspace = true } sqlx = { workspace = true, features = ["postgres", "runtime-tokio", "tls-rustls", "chrono"] } tempfile = { workspace = true } tracing-test = { workspace = true } +test-log = { workspace = true } +shrink_bitvm2 = { workspace = true } [features] # Enables the prove feature on risc0-zkvm to build the prover directly into this CLI. prove = ["risc0-zkvm/prove"] # Enables the cuda feature on risc0-zkvm to build the prover directly into this CLI, with CUDA support. -cuda = ["prove", "risc0-zkvm/cuda"] +cuda = ["prove", "risc0-zkvm/cuda"] \ No newline at end of file diff --git a/crates/boundless-cli/src/bin/boundless.rs b/crates/boundless-cli/src/bin/boundless.rs index ab24c0cfa..7570afea5 100644 --- a/crates/boundless-cli/src/bin/boundless.rs +++ b/crates/boundless-cli/src/bin/boundless.rs @@ -86,7 +86,7 @@ use boundless_market::{ }, input::GuestEnv, request_builder::{OfferParams, RequirementParams}, - selector::ProofType, + selector::{is_shrink_bitvm2_selector, ProofType}, storage::{fetch_url, StorageProvider, StorageProviderConfig}, Client, Deployment, StandardClient, }; @@ -1103,6 +1103,7 @@ async fn submit_offer(client: StandardClient, args: &SubmitOfferArgs) -> Result< ProofType::Inclusion => requirements.selector(Selector::SetVerifierV0_7 as u32), ProofType::Groth16 => requirements.selector(Selector::Groth16V2_2 as u32), ProofType::Any => &mut requirements, + ProofType::ShrinkBitvm2 => requirements.selector(Selector::ShrinkBitvm2V0_1 as u32), ty => bail!("unsupported proof type provided in proof-type flag: {:?}", ty), }; let request = request.with_requirements(requirements); @@ -1211,6 +1212,14 @@ where // hex::encode(&request.requirements.predicate.data) // ); + // TODO(ec2): fixme + // if is_shrink_bitvm2_selector(request.requirements.selector) && journal.len() != 32 { + // bail!( + // "Preflight failed: Journal must be exactly 32 bytes for Shrink Bitvm2, got {} bytes", + // journal.len() + // ); + // } + tracing::info!("Preflight check passed"); } else { tracing::warn!("Skipping preflight check"); diff --git a/crates/boundless-cli/src/lib.rs b/crates/boundless-cli/src/lib.rs index 052051a6b..a02cf2c48 100644 --- a/crates/boundless-cli/src/lib.rs +++ b/crates/boundless-cli/src/lib.rs @@ -41,10 +41,11 @@ use boundless_market::{ RequestInputType, }, input::GuestEnv, - selector::{is_groth16_selector, SupportedSelectors}, + selector::{is_groth16_selector, is_shrink_bitvm2_selector, SupportedSelectors}, storage::fetch_url, ProofRequest, }; +use tempfile::tempdir; alloy::sol!( #[sol(all_derives)] @@ -176,6 +177,30 @@ impl DefaultProver { .await? } + pub(crate) async fn shrink_bitvm2(&self, receipt: &Receipt) -> Result { + if receipt.journal.bytes.len() != 32 { + bail!( + "Shrink BitVM2 requires a journal of 32 bytes, got {}", + receipt.journal.bytes.len() + ); + } + if is_dev_mode() { + return Ok(receipt.clone()); + } + let succinct_receipt = receipt.inner.succinct().unwrap(); + let p254_receipt = risc0_zkvm::recursion::identity_p254(succinct_receipt) + .context("identity predicate failed")?; + let temp_dir = tempdir().context("Failed to crate tmpdir")?; + let receipt = shrink_bitvm2::prove_and_verify( + "boundless_cli", + temp_dir.path(), + p254_receipt, + receipt.journal.clone(), + ) + .await?; + Ok(receipt) + } + // Finalizes the set builder. pub(crate) async fn finalize( &self, @@ -307,6 +332,9 @@ impl DefaultProver { let order_seal = if is_groth16_selector(req.requirements.selector) { let receipt = self.compress(&receipts[i]).await?; encode_seal(&receipt)? + } else if is_shrink_bitvm2_selector(req.requirements.selector) { + let receipt = self.shrink_bitvm2(&receipts[i]).await?; + encode_seal(&receipt)? } else { order_inclusion_receipt.abi_encode_seal()? }; @@ -405,6 +433,7 @@ mod tests { }; use boundless_market_test_utils::{ASSESSOR_GUEST_ELF, ECHO_ID, ECHO_PATH, SET_BUILDER_ELF}; use risc0_ethereum_contracts::selector::Selector; + use shrink_bitvm2::ShrinkBitvm2ReceiptClaim; async fn setup_proving_request_and_signature( signer: &PrivateKeySigner, @@ -460,6 +489,34 @@ mod tests { ) .expect("failed to create prover"); + prover.fulfill(&[(request, signature.as_bytes().into())]).await.unwrap(); + } + #[tokio::test] + #[test_log::test] + async fn test_shrink() { + let input = [255u8; 32].to_vec(); // Example output data + let blake3_claim_digest = + ShrinkBitvm2ReceiptClaim::ok(Digest::from(ECHO_ID), input.clone()).digest(); + let signer = PrivateKeySigner::random(); + let request = ProofRequest::new( + RequestId::new(signer.address(), 0), + Requirements::new(Predicate::claim_digest_match(blake3_claim_digest)) + .with_selector(FixedBytes::from(Selector::ShrinkBitvm2V0_1 as u32)), + format!("file://{ECHO_PATH}"), + RequestInput::builder().write_slice(&input).build_inline().unwrap(), + Offer::default(), + ); + + let signature = request.sign_request(&signer, Address::ZERO, 1).await.unwrap(); + let domain = eip712_domain(Address::ZERO, 1); + let prover = DefaultProver::new( + SET_BUILDER_ELF.to_vec(), + ASSESSOR_GUEST_ELF.to_vec(), + Address::ZERO, + domain, + ) + .expect("failed to create prover"); + prover.fulfill(&[(request, signature.as_bytes().into())]).await.unwrap(); } } diff --git a/crates/boundless-market/Cargo.toml b/crates/boundless-market/Cargo.toml index 11364c108..08cb44d9c 100644 --- a/crates/boundless-market/Cargo.toml +++ b/crates/boundless-market/Cargo.toml @@ -22,6 +22,7 @@ serde = { workspace = true } sha2 = { workspace = true } thiserror = { workspace = true } url = { workspace = true } +hex = { workspace = true } # Host dependencies [target.'cfg(not(target_os = "zkvm"))'.dependencies] @@ -35,7 +36,6 @@ clap = { workspace = true } dashmap = "6" futures = "0.3" futures-util = { workspace = true } -hex = { workspace = true } httpmock = "0.7" rand = { workspace = true } reqwest = { workspace = true, features = ["json", "multipart"] } diff --git a/crates/boundless-market/build.rs b/crates/boundless-market/build.rs index 25e6b2c14..ada3042dd 100644 --- a/crates/boundless-market/build.rs +++ b/crates/boundless-market/build.rs @@ -25,7 +25,7 @@ const EXCLUDE_CONTRACTS: [&str; 2] = [ ]; // Contracts to copy bytecode for. Used for deploying contracts in tests. -const ARTIFACT_TARGET_CONTRACTS: [&str; 8] = [ +const ARTIFACT_TARGET_CONTRACTS: [&str; 9] = [ "BoundlessMarket", "HitPoints", "RiscZeroMockVerifier", @@ -33,6 +33,7 @@ const ARTIFACT_TARGET_CONTRACTS: [&str; 8] = [ "ERC1967Proxy", "RiscZeroVerifierRouter", "RiscZeroGroth16Verifier", + "RiscZeroBitvm2Groth16Verifier", "MockCallback", ]; @@ -266,6 +267,9 @@ fn get_interfaces(contract: &str) -> &str { "RiscZeroGroth16Verifier" => { r#"constructor(bytes32 control_root, bytes32 bn254_control_id) {}"# } + "RiscZeroBitvm2Groth16Verifier" => { + r#"constructor(bytes32 control_root, bytes32 bn254_control_id) {}"# + } "MockCallback" => { r#"constructor(address verifier, address boundlessMarket, bytes32 imageId, uint256 _targetGas) {} function getCallCount() external view returns (uint256) {}"# diff --git a/crates/boundless-market/src/contracts/bytecode.rs b/crates/boundless-market/src/contracts/bytecode.rs index a9fddbf8d..59659fd4f 100644 --- a/crates/boundless-market/src/contracts/bytecode.rs +++ b/crates/boundless-market/src/contracts/bytecode.rs @@ -51,6 +51,13 @@ alloy::sol! { } } +alloy::sol! { + #[sol(rpc, bytecode = "6101808060405234610a5257604081611c2980380380916100208285610a56565b833981010312610a5257805160209182015191600882811c7eff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff169083901b7fff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff001617601081811c7dffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff1691901b7fffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000161780821c7bffffffff00000000ffffffff00000000ffffffff00000000ffffffff16911b7fffffffff00000000ffffffff00000000ffffffff00000000ffffffff000000001617604081811c77ffffffffffffffff0000000000000000ffffffffffffffff1691901b7fffffffffffffffff0000000000000000ffffffffffffffff00000000000000001617608081811c91901b176001600160801b031981811660a052608091821b16905260c08290526040517f72697363302e47726f74683136526563656970745665726966696572506172618152656d657465727360d01b602082810191909152905f9060269060025afa156108de575f5191600881811c7eff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff1691901b7fff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff001617601081811c7dffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff1691901b7fffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff00001617602081811c7bffffffff00000000ffffffff00000000ffffffff00000000ffffffff1691901b7fffffffff00000000ffffffff00000000ffffffff00000000ffffffff000000001617604081811c77ffffffffffffffff0000000000000000ffffffffffffffff1691901b7fffffffffffffffff0000000000000000ffffffffffffffff00000000000000001617608081811c91901b17915f610120526060610120526040516103106101205182610a56565b6002815261012051601f190161010081905236602083013760205f604051828101907f0ecf6f8bd15c247a360bd40aad38aca3c05122d867574d6d9fa4578d62a2356982527f170fc95a0b81b960145a374c5441fda1713baa2c68fe5d82906abe3d17a78e3c60408201526040815261038c6101205182610a56565b604051918291518091835e8101838152039060025afa156108de575f516103b282610a8d565b5260205f604051828101907f2cb74a0c83341e68f50b891a4a87fb9dc4b39e6a161afd12175930c503f1d3fa82527f0727afd0d191e04d7ebd951bb440668a5756d6bc6f4abbb0cca6bb2a94fb12646040820152604081526104176101205182610a56565b604051918291518091835e8101838152039060025afa156108de575f5161043d82610a9a565b5260205f601a6040517f72697363305f67726f746831362e566572696679696e674b6579000000000000815260025afa156108de575f519260205f604051828101907f2d4d9aa7e302d9df41749d5507949d05dbea33fbb16c643b22f599a2be6df2e282527f14bedd503c37ceb061d8ec60209fe345ce89830a19230301f076caff004d19266040820152604081526104d96101205182610a56565b604051918291518091835e8101838152039060025afa156108de575f519460205f604051828101907f0967032fcbf776d1afc985f88877f182d38480a653f2decaa9794cbc3bf3060c82527f0e187847ad4c798374d0d6732bf501847dd68bc0e071241e0213bc7fc13db7ab60408201527f304cfbd1e08a704a99f5e847d93f8c3caafddec46b7a0d379da69a4d112346a7610120518201527f1739c1b1a457a8c7313123d24d2f9192f896b7c63eea05a9d57f06547ad0cec86080820152608081526105a760a082610a56565b604051918291518091835e8101838152039060025afa156108de575f519360205f604051828101907f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c282527f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed60408201527f090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b610120518201527f12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa60808201526080815261067560a082610a56565b604051918291518091835e8101838152039060025afa156108de575f519660205f604051828101907f2c0859cec32a8ac8272b87c11cf949b67388d6f48c43a92abe715a622d72cd7d82527f2c0f395435a8745c2512fb6dac5146577d65f3079c56d308065491783ec4af2260408201527f01ff15f2902311b2ef58617c7d89079bf87a7c9502a47ea310a81d5236a29f48610120518201527f0a22cacd7e87b85c3cd035641338c9f41a9492765db7a2d59bbdcc32911200ee60808201526080815261074360a082610a56565b604051918291518091835e8101838152039060025afa156108de575f519660205f601d6040517f72697363305f67726f746831362e566572696679696e674b65792e4943000000815260025afa156108de575f80516101405260206101605297885b8751808b1015610947575f19810190808211610933578b90035f190190811161093357885181101561091f57610160519060051b89010151604051916107ee6101205184610a56565b60028352610160518301916101005136843761080984610a8d565b5261081383610a9a565b526040516108246101605182610a56565b5f8152601f196101605101366101605183013782519161ffff831161090757604080516101405161016051820152945185939291840191905f905b8082106108e95750505092816108ab94600294935180926101605101825e019061ffff60f01b9061ff0060ff8260081c169160081b161760f01b16815203601d19810184520182610a56565b5f60405191805180916101605101845e820191818352806101605193039060025afa156108de5760015f519901986107a5565b6040513d5f823e3d90fd5b8251845261016051889650938401939092019160019091019061085f565b826306dfcc6560e41b5f52601060045260245260445ffd5b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b505f92918b8a60405196610160518801958652604088015261012051870152608086015260a085015260c0840152600560f81b60e084015260c2835261098e60e284610a56565b60405192518091845e820191818352806101605193039060025afa156108de575f91825190604051946101605186019384526040860152610120518501526080840152600360f81b60a0840152608283526109ea60a284610a56565b60405192518091845e820191818352806101605193039060025afa156108de575f516001600160e01b03191660e05260405161117e9081610aab823960805181610b59015260a05181610b14015260c051816102a2015260e05181818160be01526101530152f35b5f80fd5b601f909101601f19168101906001600160401b03821190821017610a7957604052565b634e487b7160e01b5f52604160045260245ffd5b80511561091f5760200190565b80516001101561091f576040019056fe60806040526004361015610011575f80fd5b5f3560e01c8063053c238d146100a45780631599ead51461009f578063258038e21461009a57806343753b4d1461009557806365f4826e146100905780638989fa2e1461008b5780639181e4b114610086578063ab750e75146100815763ffa1ad741461007c575f80fd5b610c4c565b610b89565b610b44565b610aff565b610641565b6102e0565b61028b565b6100eb565b346100e7575f3660031901126100e75763ffffffff60e01b7f00000000000000000000000000000000000000000000000000000000000000001660805260206080f35b5f80fd5b346100e75760203660031901126100e75760043567ffffffffffffffff81116100e75780360360406003198201126100e757600482013590602219018112156100e757810160048101359067ffffffffffffffff82116100e75760240181360381136100e7577f00000000000000000000000000000000000000000000000000000000000000006101956101886101828585610deb565b90610e16565b6001600160e01b03191690565b6001600160e01b031982160361025657506101b6826020936101be93610df9565b810190610e93565b80516101f86040848401519301519460246101d886610c3c565b91013581526040516343753b4d60e01b8152958694859460048601610f84565b0381305afa908115610251575f91610222575b501561021357005b63439cc0cd60e01b5f5260045ffd5b610244915060203d60201161024a575b61023c8183610c1a565b810190610f1e565b5f61020b565b503d610232565b610d9b565b6102666101828461028894610deb565b632e2ce35360e21b5f526001600160e01b031990811660045216602452604490565b5ffd5b346100e7575f3660031901126100e75760206040517f00000000000000000000000000000000000000000000000000000000000000008152f35b906004916044116100e757565b9060c491610104116100e757565b346100e7576101203660031901126100e7576102fb366102c5565b3660c4116100e75761030c366102d2565b36610124116100e7576103607f0a22cacd7e87b85c3cd035641338c9f41a9492765db7a2d59bbdcc32911200ee9160206040519161038083016040526101043561035581610caa565b61036161012435610caa565b7f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd478360808601987f0ecf6f8bd15c247a360bd40aad38aca3c05122d867574d6d9fa4578d62a2356987526103db828801947f170fc95a0b81b960145a374c5441fda1713baa2c68fe5d82906abe3d17a78e3c865288610cdb565b80358a52013581030660a085015260443560c085015260643560e085015260843561010085015260a4356101208501527f2d4d9aa7e302d9df41749d5507949d05dbea33fbb16c643b22f599a2be6df2e26101408501527f14bedd503c37ceb061d8ec60209fe345ce89830a19230301f076caff004d19266101608501527f0967032fcbf776d1afc985f88877f182d38480a653f2decaa9794cbc3bf3060c6101808501527f0e187847ad4c798374d0d6732bf501847dd68bc0e071241e0213bc7fc13db7ab6101a08501527f304cfbd1e08a704a99f5e847d93f8c3caafddec46b7a0d379da69a4d112346a76101c08501527f1739c1b1a457a8c7313123d24d2f9192f896b7c63eea05a9d57f06547ad0cec86101e08501528351610200850152516102208401527f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c26102408401527f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed6102608401527f090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b6102808401527f12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa6102a084015280356102c084015201356102e08201527f2c0859cec32a8ac8272b87c11cf949b67388d6f48c43a92abe715a622d72cd7d6103008201527f2c0f395435a8745c2512fb6dac5146577d65f3079c56d308065491783ec4af226103208201527f01ff15f2902311b2ef58617c7d89079bf87a7c9502a47ea310a81d5236a29f4861034082015201526020816103008160086107cf195a01fa9051165f5260205ff35b346100e7575f3660031901126100e757610659610d67565b60205f6106d66040516106ca816106bc8682016040907f0ecf6f8bd15c247a360bd40aad38aca3c05122d867574d6d9fa4578d62a2356981527f170fc95a0b81b960145a374c5441fda1713baa2c68fe5d82906abe3d17a78e3c60208201520190565b03601f198101835282610c1a565b60405191828092610d89565b039060025afa15610251575f516106ec82610da6565b5260205f6107506040516106ca816106bc8682016040907f2cb74a0c83341e68f50b891a4a87fb9dc4b39e6a161afd12175930c503f1d3fa81527f0727afd0d191e04d7ebd951bb440668a5756d6bc6f4abbb0cca6bb2a94fb126460208201520190565b039060025afa15610251575f5161076682610dc7565b5260205f6040518061079c81601a907f72697363305f67726f746831362e566572696679696e674b657900000000000081520190565b039060025afa15610251575f5160205f61080c6040516106ca816106bc8682016040907f2d4d9aa7e302d9df41749d5507949d05dbea33fbb16c643b22f599a2be6df2e281527f14bedd503c37ceb061d8ec60209fe345ce89830a19230301f076caff004d192660208201520190565b039060025afa15610251575f519060205f6108c96040516106ca816106bc8682016080907f0967032fcbf776d1afc985f88877f182d38480a653f2decaa9794cbc3bf3060c81527f0e187847ad4c798374d0d6732bf501847dd68bc0e071241e0213bc7fc13db7ab60208201527f304cfbd1e08a704a99f5e847d93f8c3caafddec46b7a0d379da69a4d112346a760408201527f1739c1b1a457a8c7313123d24d2f9192f896b7c63eea05a9d57f06547ad0cec860608201520190565b039060025afa15610251575f519160205f6109866040516106ca816106bc8682016080907f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c281527f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed60208201527f090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b60408201527f12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa60608201520190565b039060025afa15610251575f519160205f610a436040516106ca816106bc8682016080907f2c0859cec32a8ac8272b87c11cf949b67388d6f48c43a92abe715a622d72cd7d81527f2c0f395435a8745c2512fb6dac5146577d65f3079c56d308065491783ec4af2260208201527f01ff15f2902311b2ef58617c7d89079bf87a7c9502a47ea310a81d5236a29f4860408201527f0a22cacd7e87b85c3cd035641338c9f41a9492765db7a2d59bbdcc32911200ee60608201520190565b039060025afa15610251575f519060205f60405180610a8681601d907f72697363305f67726f746831362e566572696679696e674b65792e494300000081520190565b039060025afa15610251576106bc5f95610ae7956106ca94610aab60209a8a51611022565b604080518c810197885260208801999099528601939093526060850191909152608084015260a0830152600560f81b60c0830152839160c20190565b039060025afa15610251575f51604051908152602090f35b346100e7575f3660031901126100e7576040517f00000000000000000000000000000000000000000000000000000000000000006001600160801b0319168152602090f35b346100e7575f3660031901126100e7576040517f00000000000000000000000000000000000000000000000000000000000000006001600160801b0319168152602090f35b346100e75760603660031901126100e75760043567ffffffffffffffff81116100e757366023820112156100e757806004013567ffffffffffffffff81116100e757369101602401116100e75763439cc0cd60e01b5f5260045ffd5b634e487b7160e01b5f52604160045260245ffd5b6060810190811067ffffffffffffffff821117610c1557604052565b610be5565b90601f8019910116810190811067ffffffffffffffff821117610c1557604052565b90610c4a6040519283610c1a565b565b346100e7575f3660031901126100e7576040805190610c6b8183610c1a565b60058252602082019164302e302e3160d81b83528151928391602083525180918160208501528484015e5f828201840152601f01601f19168101030190f35b7f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd471115610cd357565b5f805260205ff35b604051917f2cb74a0c83341e68f50b891a4a87fb9dc4b39e6a161afd12175930c503f1d3fa83527f0727afd0d191e04d7ebd951bb440668a5756d6bc6f4abbb0cca6bb2a94fb126460208401526040830190815260408360608160076107cf195a01fa15610cd357815190526020810151606083015260409160809060066107cf195a01fa15610cd357565b60405160609190610d788382610c1a565b6002815291601f1901366020840137565b805191908290602001825e015f815290565b6040513d5f823e3d90fd5b805115610db35760200190565b634e487b7160e01b5f52603260045260245ffd5b805160011015610db35760400190565b8051821015610db35760209160051b010190565b906004116100e75790600490565b90929192836004116100e75783116100e757600401916003190190565b356001600160e01b0319811692919060048210610e31575050565b6001600160e01b031960049290920360031b82901b16169150565b9080601f830112156100e75760405191610e67604084610c1a565b8290604081019283116100e757905b828210610e835750505090565b8135815260209182019101610e76565b610100818303126100e75760405191610eab83610bf9565b610eb58183610e4c565b835280605f830112156100e7576040918251610ed18482610c1a565b8060c08301928484116100e75785809101915b848310610f04575050506020850152610efd9190610e4c565b9082015290565b602090610f118785610e4c565b8152019101908590610ee4565b908160209103126100e7575180151581036100e75790565b905f905b60028210610f4757505050565b6020806001928551815201930191019091610f3a565b905f905b60018210610f6e57505050565b6020806001928551815201930191019091610f61565b919493929094610f9983610120810197610f36565b5f604084015b60028210610fc75750505081610fc06101009260c0610c4a96950190610f36565b0190610f5d565b82515f90825b60028310610feb575050506020604060019201930191019091610f9f565b6020806001928451815201920192019190610fcd565b9190820391821161100e57565b634e487b7160e01b5f52601160045260245ffd5b90916020915f918290815b865180861015611115575f19810190811161100e5761104f8661105592611001565b88610dd7565b519061105f610d67565b9161106983610da6565b5261107382610dc7565b52604051906110828783610c1a565b5f8252833688840137805161ffff81116110fe5787926106ca5f936106bc6110d861ffff6110e796166110c76110bd8261ff009060081b1690565b9160081c60ff1690565b1760f01b6001600160f01b03191690565b6040519485938c8a860161111f565b039060025afa156102515760015f5194019361102d565b6306dfcc6560e41b5f52601060045260245260445ffd5b5095509350505050565b60209193929381520160208351919301905f5b81811061115b575050506002929161114991610d89565b6001600160f01b031990911681520190565b825185526020948501949092019160010161113256fea164736f6c634300081a000a")] + contract RiscZeroBitvm2Groth16Verifier { + constructor(bytes32 control_root, bytes32 bn254_control_id) {} + } +} + alloy::sol! { #[sol(rpc, bytecode = "60e0346100bb57601f61087938819003918201601f19168301916001600160401b038311848410176100bf578084926080946040528339810103126100bb578051906001600160a01b03821682036100bb5760208101516001600160a01b03811681036100bb57606060408301519201519260805260a05260c0526001556040516107a590816100d4823960805181818161039301526106a3015260a05181818160800152610127015260c05181818161015701526106520152f35b5f80fd5b634e487b7160e01b5f52604160045260245ffdfe6080806040526004361015610012575f80fd5b5f905f3560e01c90816308c84e7014610691575080634b28f9a214610675578063549206ed1461063b5780636330d59d1461061e578063a12da43f146100cf578063a96b2dc0146100b25763c65c72911461006b575f80fd5b346100af57806003193601126100af576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b80fd5b50346100af57806003193601126100af5760209054604051908152f35b503461058457606036600319011261058457600435906024356001600160401b038111610584576101049036906004016106d2565b6044356001600160401b038111610584576101239036906004016106d2565b94907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031633036105e8577f000000000000000000000000000000000000000000000000000000000000000082036105b05760205f6040518587823780868101838152039060025afa15610579575f515f60806040516101a9816106ff565b8281528260208201526040516101be8161071a565b83815283602082015260408201528260608201520152604051906101e18261071a565b5f82525f6020830152604051906101f78261071a565b8152602081015f815260205f600c6040516b1c9a5cd8cc0b93dd5d1c1d5d60a21b815260025afa15610579576020915f918251915190516040519185830193845260408301526060820152600160f91b60808201526062815261025b608282610735565b604051918291518091835e8101838152039060025afa15610579575f5190604051610285816106ff565b84815260208101907fa3acc27117418996340b84e5a90f3ef4c49d22c79e44aad822ec9c313e1eb8e282526040810192835260608101915f83526080820194855260205f60126040517172697363302e52656365697074436c61696d60701b815260025afa15610579575f51925191519051945184515190600382101561059c57945160209081015160408051808401978852908101959095526060850193909352608084019690965260a08301949094526001600160f81b031960f894851b811660c0840152931b90921660c4830152600160fa1b60c883015260aa82525f9161037160ca82610735565b604051918291518091835e8101838152039060025afa15610579575f516040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316916103c58261071a565b6001600160401b038911610588576040516103ea601f8b01601f191660200182610735565b898152368a86011161058457898560208301375f60208b83010152825260208201908152823b15610584576020925f926084604051809681958294631599ead560e01b845282600485015251604060248501528051928391826064870152018585015e8282018401889052516044830152601f01601f191681010301915afa80156105795761053d575b506104c9907f47ed3f58af358c0ab2b6b2bf11812f81b240613fa30c7d845e1e4f41ce3a0f4e9495966104bb5a976040519687968752606060208801526060870191610756565b918483036040860152610756565b0390a16104d68254610776565b8255815b5a8203828111610529576001541115610525576105209060405160208101908282526020815261050b604082610735565b51902084526002602052806040852055610776565b6104da565b8280f35b634e487b7160e01b84526011600452602484fd5b7f47ed3f58af358c0ab2b6b2bf11812f81b240613fa30c7d845e1e4f41ce3a0f4e9495509061056f5f6104c993610735565b5f95945090610474565b6040513d5f823e3d90fd5b5f80fd5b634e487b7160e01b5f52604160045260245ffd5b634e487b7160e01b5f52602160045260245ffd5b60405162461bcd60e51b815260206004820152601060248201526f125b9d985b1a5908125b5859d948125160821b6044820152606490fd5b60405162461bcd60e51b815260206004820152600e60248201526d24b73b30b634b21039b2b73232b960911b6044820152606490fd5b34610584575f366003190112610584576020600154604051908152f35b34610584575f3660031901126105845760206040517f00000000000000000000000000000000000000000000000000000000000000008152f35b34610584575f3660031901126105845760205f54604051908152f35b34610584575f366003190112610584577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b9181601f84011215610584578235916001600160401b038311610584576020838186019501011161058457565b60a081019081106001600160401b0382111761058857604052565b604081019081106001600160401b0382111761058857604052565b90601f801991011681019081106001600160401b0382111761058857604052565b908060209392818452848401375f828201840152601f01601f1916010190565b5f1981146107845760010190565b634e487b7160e01b5f52601160045260245ffdfea164736f6c634300081a000a")] contract MockCallback { diff --git a/crates/boundless-market/src/contracts/mod.rs b/crates/boundless-market/src/contracts/mod.rs index 294bf0ea9..9026d29a1 100644 --- a/crates/boundless-market/src/contracts/mod.rs +++ b/crates/boundless-market/src/contracts/mod.rs @@ -551,6 +551,18 @@ impl Requirements { } } + /// Set the selector for a shrink bitvm2 proof. + /// + /// This will set the selector to the appropriate value based on the current environment. + /// In dev mode, the selector will be set to `FakeReceipt`, otherwise it will be set + /// to `Groth16V2_2`. + #[cfg(not(target_os = "zkvm"))] + pub fn with_shrink_bitvm2_proof(self) -> Self { + match crate::util::is_dev_mode() { + true => Self { selector: FixedBytes::from(Selector::FakeReceipt as u32), ..self }, + false => Self { selector: FixedBytes::from(Selector::ShrinkBitvm2V0_1 as u32), ..self }, + } + } /// Returns image id from the predicate type. Returns none if claim digest match. Panics if /// the predicate data is not long enough. pub fn image_id(&self) -> Option { diff --git a/crates/boundless-market/src/request_builder/finalizer.rs b/crates/boundless-market/src/request_builder/finalizer.rs index 783ac63dd..ee36b2546 100644 --- a/crates/boundless-market/src/request_builder/finalizer.rs +++ b/crates/boundless-market/src/request_builder/finalizer.rs @@ -14,11 +14,14 @@ use super::{Adapt, Layer, RequestParams}; use crate::{ - contracts::{FulfillmentData, Offer, ProofRequest, RequestId, RequestInput, Requirements}, + contracts::{ + FulfillmentData, Offer, PredicateType, ProofRequest, RequestId, RequestInput, Requirements, + }, util::now_timestamp, }; use anyhow::{bail, Context}; use derive_builder::Builder; +use risc0_zkvm::Digest; use url::Url; #[non_exhaustive] @@ -130,11 +133,21 @@ impl Adapt for RequestParams { // As an extra consistency check. verify the journal satisfies the required predicate. if let Some(ref journal) = self.journal { if let Some(image_id) = self.image_id { - let fulfillment_data = - FulfillmentData::from_image_id_and_journal(image_id, journal.bytes.clone()); - // TODO(ec2): fixme - if !requirements.predicate.eval(&fulfillment_data) { - bail!("journal in request builder does not match requirements predicate; check request parameters.\npredicate = {:?}\njournal = 0x{}", requirements.predicate, hex::encode(journal)); + match requirements.predicate.predicateType { + // TODO(ec2): fixme + PredicateType::ClaimDigestMatch => { + tracing::debug!("skipping predicate check since claim digest match type") + } + // If the predicate is not ClaimDigestMatch, we verify it against FulfillmentData. + _ => { + let fulfillment_data = FulfillmentData::from_image_id_and_journal( + image_id, + journal.bytes.clone(), + ); + if !requirements.predicate.eval(&fulfillment_data) { + bail!("journal in request builder does not match requirements predicate; check request parameters.\npredicate = {:?}\njournal = 0x{}", requirements.predicate, hex::encode(journal)); + } + } } } } diff --git a/crates/boundless-market/src/request_builder/mod.rs b/crates/boundless-market/src/request_builder/mod.rs index c8b191d70..389ba9577 100644 --- a/crates/boundless-market/src/request_builder/mod.rs +++ b/crates/boundless-market/src/request_builder/mod.rs @@ -29,7 +29,7 @@ use risc0_zkvm::{Digest, Journal}; use url::Url; use crate::{ - contracts::{ProofRequest, RequestId, RequestInput}, + contracts::{Predicate, ProofRequest, RequestId, RequestInput}, input::GuestEnv, storage::{StandardStorageProvider, StorageProvider}, util::NotProvided, @@ -567,6 +567,25 @@ impl RequestParams { }; Self { requirements, ..self } } + + /// Request a stand-alone Shrink Bitvm2 proof for this request. + /// + /// This is a convinience method to set the selector on the requirements. Note that calling + /// [RequestParams::with_requirements] after this function will overwrite the change. + pub fn with_shrink_bitvm2_proof(self) -> Self { + let mut requirements = self.requirements; + requirements.selector = match crate::util::is_dev_mode() { + true => Some((Selector::FakeReceipt as u32).into()), + false => Some((Selector::ShrinkBitvm2V0_1 as u32).into()), + }; + // if let Some(ref predicate) = requirements.predicate { + // if predicate.predicateType == crate::contracts::PredicateType::ClaimDigestMatch { + // // If the predicate is a claim digest match, we need to set the image ID. + // requirements.image_id = Some(predicate.data.0.as_ref().try_into().unwrap()); + // } + // } + Self { requirements, ..self } + } } impl Debug for RequestParams { diff --git a/crates/boundless-market/src/selector.rs b/crates/boundless-market/src/selector.rs index 2ed0f7130..045fd7f98 100644 --- a/crates/boundless-market/src/selector.rs +++ b/crates/boundless-market/src/selector.rs @@ -38,6 +38,8 @@ pub enum ProofType { Groth16, /// Inclusion proof type. Inclusion, + /// BitVM2 compatible Groth16 proof type. + ShrinkBitvm2, } /// A struct to hold the supported selectors. @@ -51,7 +53,11 @@ impl Default for SupportedSelectors { fn default() -> Self { let mut supported_selectors = Self::new() .with_selector(UNSPECIFIED_SELECTOR, ProofType::Any) - .with_selector(FixedBytes::from(Selector::Groth16V2_2 as u32), ProofType::Groth16); + .with_selector(FixedBytes::from(Selector::Groth16V2_2 as u32), ProofType::Groth16) + .with_selector( + FixedBytes::from(Selector::ShrinkBitvm2V0_1 as u32), + ProofType::ShrinkBitvm2, + ); if is_dev_mode() { supported_selectors = supported_selectors .with_selector(FixedBytes::from(Selector::FakeReceipt as u32), ProofType::Any); @@ -124,6 +130,18 @@ pub fn is_groth16_selector(selector: FixedBytes<4>) -> bool { } } +/// Check if a selector is a bitvm2 groth16 selector. +pub fn is_shrink_bitvm2_selector(selector: FixedBytes<4>) -> bool { + let sel = Selector::from_bytes(selector.into()); + match sel { + Some(selector) => { + selector.get_type() == SelectorType::FakeReceipt + || selector.get_type() == SelectorType::ShrinkBitvm2 + } + None => false, + } +} + #[cfg(test)] mod tests { use super::*; diff --git a/crates/boundless-market/src/storage/fetch.rs b/crates/boundless-market/src/storage/fetch.rs index 9217a5577..6d82845c2 100644 --- a/crates/boundless-market/src/storage/fetch.rs +++ b/crates/boundless-market/src/storage/fetch.rs @@ -27,7 +27,7 @@ pub async fn fetch_url(url_str: impl AsRef) -> anyhow::Result> { match url.scheme() { "http" | "https" => fetch_http(&url).await, "file" => { - ensure!(is_dev_mode(), "file fetch is only enabled when RISC0_DEV_MODE is enabled"); + // ensure!(is_dev_mode(), "file fetch is only enabled when RISC0_DEV_MODE is enabled"); fetch_file(&url).await } _ => bail!("unsupported URL scheme: {}", url.scheme()), diff --git a/crates/boundless-market/test-utils/Cargo.toml b/crates/boundless-market/test-utils/Cargo.toml index d0f854c0c..49207edbd 100644 --- a/crates/boundless-market/test-utils/Cargo.toml +++ b/crates/boundless-market/test-utils/Cargo.toml @@ -17,6 +17,7 @@ boundless-market = { workspace = true, features = ["test-utils"] } guest-assessor = { workspace = true } guest-set-builder = { workspace = true } guest-util = { workspace = true } +hex = { workspace = true } risc0-aggregation = { workspace = true } risc0-circuit-recursion = { workspace = true } risc0-ethereum-contracts = { workspace = true, features = ["unstable"] } diff --git a/crates/boundless-market/test-utils/src/lib.rs b/crates/boundless-market/test-utils/src/lib.rs index da78dc64b..d76e48595 100644 --- a/crates/boundless-market/test-utils/src/lib.rs +++ b/crates/boundless-market/test-utils/src/lib.rs @@ -36,6 +36,7 @@ use boundless_market::{ dynamic_gas_filler::DynamicGasFiller, nonce_layer::NonceProvider, }; +use hex::FromHex; use risc0_aggregation::{ merkle_path, merkle_root, GuestState, SetInclusionReceipt, SetInclusionReceiptVerifierParameters, @@ -96,6 +97,18 @@ pub async fn deploy_groth16_verifier( Ok(*instance.address()) } +pub async fn deploy_bitvm2_verifier( + deployer_provider: P, + control_root: B256, + bn254_control_id: B256, +) -> Result
{ + let instance = + RiscZeroBitvm2Groth16Verifier::deploy(deployer_provider, control_root, bn254_control_id) + .await + .context("failed to deploy RiscZeroBitvm2Groth16Verifier")?; + Ok(*instance.address()) +} + pub async fn deploy_mock_verifier(deployer_provider: P) -> Result
{ let instance = RiscZeroMockVerifier::deploy(deployer_provider, FixedBytes([0xFFu8; 4])) .await @@ -223,6 +236,7 @@ pub async fn deploy_contracts( let mut bn254_control_id = BN254_IDENTITY_CONTROL_ID; bn254_control_id.as_mut_bytes().reverse(); let verifier_parameters_digest = Groth16ReceiptVerifierParameters::default().digest(); + println!("g16 verifier_parameters_digest {verifier_parameters_digest}"); ( deploy_groth16_verifier( &deployer_provider, @@ -234,6 +248,7 @@ pub async fn deploy_contracts( ) } }; + let set_verifier = deploy_set_verifier(&deployer_provider, verifier_router, set_builder_id, set_builder_url) .await?; @@ -243,6 +258,31 @@ pub async fn deploy_contracts( deployer_provider.clone(), ); + match is_dev_mode() { + true => println!("Skipping Bitvm2 verifier deployment in dev mode"), + false => { + let control_root = ALLOWED_CONTROL_ROOT; + let mut bn254_control_id = BN254_IDENTITY_CONTROL_ID; + bn254_control_id.as_mut_bytes().reverse(); + let verifier_parameters_digest = Digest::from_hex( + "b72859b60cfe0bb13cbde70859fbc67ef9dbd5410bbe66bdb7be64a3dcf6814e", + ) + .unwrap(); + let bvm2_verifier = deploy_bitvm2_verifier( + &deployer_provider, + <[u8; 32]>::from(control_root).into(), + <[u8; 32]>::from(bn254_control_id).into(), + ) + .await?; + + let bvm2_selector = verifier_parameters_digest.as_bytes()[..4].try_into()?; + + let call = &router_instance + .addVerifier(bvm2_selector, bvm2_verifier) + .from(deployer_signer.address()); + let _ = call.send().await?; + } + } let call = &router_instance .addVerifier(groth16_selector.into(), groth16_verifier) .from(deployer_signer.address()); diff --git a/crates/broker/Cargo.toml b/crates/broker/Cargo.toml index cc9ad8425..8762c1be0 100644 --- a/crates/broker/Cargo.toml +++ b/crates/broker/Cargo.toml @@ -31,6 +31,8 @@ hex = { workspace = true } http-cache-reqwest = "0.15.1" moka = { version = "0.12", features = ["future"] } notify = "6.1" +num-bigint = { version = "0.4", features = ["std"] } +num-traits = "0.2.19" rand = { workspace = true } reqwest = { workspace = true } reqwest-middleware = "0.4.1" @@ -41,6 +43,7 @@ risc0-zkvm = { workspace = true, features = ["std", "client"] } serde = { workspace = true } serde_json = { workspace = true } sha2 = "0.10" +shrink_bitvm2 = { workspace = true } sqlx = { workspace = true, features = ["sqlite", "postgres", "runtime-tokio", "json", "migrate", "macros"] } tempfile = { workspace = true } thiserror = { workspace = true } @@ -52,6 +55,7 @@ tracing-subscriber = { workspace = true, features = ["env-filter", "json"] } url = { workspace = true } uuid = { workspace = true } + [dev-dependencies] alloy = { workspace = true, features = ["node-bindings"] } aws-smithy-http-client = { version = "1.0", features = ["test-util"] } @@ -67,8 +71,18 @@ rand = { workspace = true } risc0-zkvm = { workspace = true, default-features = true } serial_test = "3.2" temp-env = { version = "0.3", features = ["async_closure"] } +test-log = { workspace = true } tokio = { workspace = true, features = ["full"] } tracing-test = { workspace = true } +risc0-groth16 = { version = "2.0.2", features = ["prove"] } +ark-bn254 = "0.5.0" +ark-ff = "0.5.0" +ark-groth16 = { version = "0.5.0" } +ark-serialize = "0.5.0" +ark-ec = "0.5.0" +blake3 = { version = "1.5.0" } + + [features] test-utils = ["dep:boundless-market-test-utils"] diff --git a/crates/broker/src/aggregator.rs b/crates/broker/src/aggregator.rs index 47148beb8..a4f0e8394 100644 --- a/crates/broker/src/aggregator.rs +++ b/crates/broker/src/aggregator.rs @@ -200,7 +200,6 @@ impl AggregatorService { let proof_id = order .proof_id .with_context(|| format!("Missing proof_id for order: {order_id}"))?; - assumptions.push(proof_id.clone()); let journal = self diff --git a/crates/broker/src/lib.rs b/crates/broker/src/lib.rs index 4c48e5878..223e52d20 100644 --- a/crates/broker/src/lib.rs +++ b/crates/broker/src/lib.rs @@ -29,7 +29,7 @@ use anyhow::{Context, Result}; use boundless_market::{ contracts::{boundless_market::BoundlessMarketService, ProofRequest}, order_stream_client::OrderStreamClient, - selector::is_groth16_selector, + selector::{is_groth16_selector, is_shrink_bitvm2_selector}, Deployment, }; use chrono::{serde::ts_seconds, DateTime, Utc}; @@ -307,6 +307,13 @@ impl std::fmt::Display for OrderRequest { } } +#[derive(Debug, PartialEq, Eq)] +enum CompressionType { + None, + Groth16, + ShrinkBitvm2, +} + /// An Order represents a proof request and a specific method of fulfillment. /// /// Requests can be fulfilled in multiple ways, for example by locking then fulfilling them, @@ -388,9 +395,22 @@ impl Order { .clone() } - pub fn is_groth16(&self) -> bool { + fn is_groth16(&self) -> bool { is_groth16_selector(self.request.requirements.selector) } + + fn is_shrink_bitvm2(&self) -> bool { + is_shrink_bitvm2_selector(self.request.requirements.selector) + } + pub fn compression_type(&self) -> CompressionType { + if self.is_groth16() { + CompressionType::Groth16 + } else if self.is_shrink_bitvm2() { + CompressionType::ShrinkBitvm2 + } else { + CompressionType::None + } + } } impl std::fmt::Display for Order { @@ -752,28 +772,31 @@ where } // Construct the prover object interface - let prover: provers::ProverObj = if is_dev_mode() { - tracing::warn!("WARNING: Running the Broker in dev mode does not generate valid receipts. \ - Receipts generated from this process are invalid and should never be used in production."); - Arc::new(provers::DefaultProver::new()) - } else if let (Some(bonsai_api_key), Some(bonsai_api_url)) = - (self.args.bonsai_api_key.as_ref(), self.args.bonsai_api_url.as_ref()) - { - tracing::info!("Configured to run with Bonsai backend"); - Arc::new( - provers::Bonsai::new(config.clone(), bonsai_api_url.as_ref(), bonsai_api_key) - .context("Failed to construct Bonsai client")?, - ) - } else if let Some(bento_api_url) = self.args.bento_api_url.as_ref() { - tracing::info!("Configured to run with Bento backend"); - - Arc::new( - provers::Bonsai::new(config.clone(), bento_api_url.as_ref(), "") - .context("Failed to initialize Bento client")?, - ) - } else { - Arc::new(provers::DefaultProver::new()) - }; + // let prover: provers::ProverObj = if is_dev_mode() { + // tracing::warn!("WARNING: Running the Broker in dev mode does not generate valid receipts. \ + // Receipts generated from this process are invalid and should never be used in production."); + // Arc::new(provers::DefaultProver::new()) + // } else if let (Some(bonsai_api_key), Some(bonsai_api_url)) = + // (self.args.bonsai_api_key.as_ref(), self.args.bonsai_api_url.as_ref()) + // { + // tracing::info!("Configured to run with Bonsai backend"); + // Arc::new( + // provers::Bonsai::new(config.clone(), bonsai_api_url.as_ref(), bonsai_api_key) + // .context("Failed to construct Bonsai client")?, + // ) + // } else if let Some(bento_api_url) = self.args.bento_api_url.as_ref() { + // tracing::info!("Configured to run with Bento backend"); + + // Arc::new( + // provers::Bonsai::new(config.clone(), bento_api_url.as_ref(), "") + // .context("Failed to initialize Bento client")?, + // ) + // } else { + // tracing::warn!("LOCAL PROBVER!!"); + // Arc::new(provers::DefaultProver::new()) + // }; + + let prover: provers::ProverObj = Arc::new(provers::DefaultProver::new()); let (pricing_tx, pricing_rx) = mpsc::channel(PRICING_CHANNEL_CAPACITY); diff --git a/crates/broker/src/order_picker.rs b/crates/broker/src/order_picker.rs index c3aea7764..14b6a25f5 100644 --- a/crates/broker/src/order_picker.rs +++ b/crates/broker/src/order_picker.rs @@ -48,7 +48,7 @@ use boundless_market::{ boundless_market::BoundlessMarketService, FulfillmentData, PredicateType, RequestError, RequestInputType, }, - selector::SupportedSelectors, + selector::{is_shrink_bitvm2_selector, SupportedSelectors}, }; use moka::future::Cache; use thiserror::Error; @@ -665,6 +665,14 @@ where return Ok(Skip); } + // If the selector is a shrink bitvm2 selector, ensure the journal is exactly 32 bytes + if is_shrink_bitvm2_selector(order.request.requirements.selector) && journal.len() != 32 { + tracing::info!( + "Order {order_id} journal is not 32 bytes for shrink bitvm2 selector, skipping", + ); + return Ok(Skip); + } + // Validate the predicates: match order.request.requirements.predicate.predicateType { PredicateType::ClaimDigestMatch => { @@ -1346,7 +1354,7 @@ fn calculate_max_cycles_for_time(prove_khz: u64, time_seconds: u64) -> u64 { #[cfg(test)] pub(crate) mod tests { - use std::time::Duration; + use std::{path::PathBuf, time::Duration}; use super::*; use crate::{ @@ -2725,6 +2733,19 @@ pub(crate) mod tests { ) -> Result>, ProverError> { self.default_prover.get_compressed_receipt(proof_id).await } + async fn shrink_bitvm2( + &self, + _proof_id: &str, + _work_dir: Option, + ) -> Result { + todo!("Shrink BitVM is not implemented yet"); + } + async fn get_shrink_bitvm2_receipt( + &self, + _proof_id: &str, + ) -> Result>, ProverError> { + todo!("Shrink BitVM is not implemented yet"); + } } #[tokio::test] diff --git a/crates/broker/src/provers/bonsai.rs b/crates/broker/src/provers/bonsai.rs index ed1f90b1d..253044f3d 100644 --- a/crates/broker/src/provers/bonsai.rs +++ b/crates/broker/src/provers/bonsai.rs @@ -12,11 +12,11 @@ // See the License for the specific language governing permissions and // limitations under the License. -use std::future::Future; +use std::{future::Future, path::PathBuf}; use async_trait::async_trait; use bonsai_sdk::{ - non_blocking::{Client as BonsaiClient, SessionId, SnarkId}, + non_blocking::{Client as BonsaiClient, SessionId, ShrinkBitvm2Id, SnarkId}, SdkErr, }; use risc0_zkvm::Receipt; @@ -274,6 +274,46 @@ impl StatusPoller { } } } + + async fn poll_with_retries_shrink_bitvm2_id( + &self, + proof_id: &ShrinkBitvm2Id, + client: &BonsaiClient, + ) -> Result { + loop { + let status = retry::<_, SdkErr, _, _>( + self.retry_counts, + self.poll_sleep_ms, + || async { proof_id.status(client).await }, + "get snark status", + ) + .await; + + if let Err(_err) = status { + return Err(ProverError::StatusFailure); + } + + let status = status.unwrap(); + + match status.status.as_ref() { + "RUNNING" => { + tokio::time::sleep(tokio::time::Duration::from_millis(self.poll_sleep_ms)) + .await; + continue; + } + "SUCCEEDED" => return Ok(proof_id.uuid.clone()), + status_code => { + let err_msg = status.error_msg.unwrap_or_default(); + if err_msg.contains("INTERNAL_ERROR") { + return Err(ProverError::ProverInternalError(err_msg.clone())); + } + return Err(ProverError::ProvingFailed(format!( + "snark proving failed with status {status_code}: {err_msg}" + ))); + } + } + } + } } #[async_trait] @@ -523,6 +563,50 @@ impl Prover for Bonsai { Ok(Some(receipt_buf)) } + + async fn shrink_bitvm2( + &self, + proof_id: &str, + _work_dir: Option, + ) -> Result { + let proof_id = self + .retry( + || async { Ok(self.client.shrink_bitvm2(proof_id.into()).await?) }, + "create snark", + ) + .await?; + + let poller = StatusPoller { + poll_sleep_ms: self.status_poll_ms, + retry_counts: self.status_poll_retry_count, + }; + + poller.poll_with_retries_shrink_bitvm2_id(&proof_id, &self.client).await?; + + Ok(proof_id.uuid) + } + async fn get_shrink_bitvm2_receipt( + &self, + proof_id: &str, + ) -> Result>, ProverError> { + let snark_id = ShrinkBitvm2Id { uuid: proof_id.into() }; + let status = self + .retry( + || async { Ok(snark_id.status(&self.client).await?) }, + "get status of bitvm2 snark", + ) + .await?; + + let Some(output) = status.output else { return Ok(None) }; + let receipt_buf = self + .retry( + || async { Ok(self.client.download(&output).await?) }, + "download bitvm2 snark output", + ) + .await?; + + Ok(Some(receipt_buf)) + } } async fn create_pg_pool() -> Result { diff --git a/crates/broker/src/provers/default.rs b/crates/broker/src/provers/default.rs index 2dead678e..8a60b0d01 100644 --- a/crates/broker/src/provers/default.rs +++ b/crates/broker/src/provers/default.rs @@ -12,16 +12,17 @@ // See the License for the specific language governing permissions and // limitations under the License. -use std::{borrow::Borrow, collections::HashMap, sync::Arc}; +use std::{borrow::Borrow, collections::HashMap, path::PathBuf, sync::Arc}; use crate::config::ProverConf; use crate::provers::{ExecutorResp, ProofResult, Prover, ProverError}; -use anyhow::{Context, Result as AnyhowResult}; +use anyhow::{anyhow, Context, Result as AnyhowResult}; use async_trait::async_trait; use risc0_zkvm::{ default_executor, default_prover, ExecutorEnv, ProveInfo, ProverOpts, Receipt, SessionInfo, VERSION, }; +use tempfile::tempdir; use tokio::sync::RwLock; use uuid::Uuid; @@ -345,6 +346,7 @@ impl Prover for DefaultProver { } async fn compress(&self, proof_id: &str) -> Result { + tracing::info!("Compressing proof Groth16 {proof_id}"); let receipt = self .get_receipt(proof_id) .await? @@ -395,13 +397,84 @@ impl Prover for DefaultProver { .ok_or_else(|| ProverError::NotFound(format!("proof {proof_id}")))?; Ok(proof_data.compressed_receipt.as_ref().cloned()) } + + async fn shrink_bitvm2( + &self, + proof_id: &str, + work_dir: Option, + ) -> Result { + let temp_dir = tempdir().context("Failed to crate tmpdir")?; + tracing::info!("Compressing proof Shrink bitvm2 {proof_id}"); + let receipt = self + .get_receipt(proof_id) + .await? + .ok_or_else(|| ProverError::NotFound(format!("no receipt for proof {proof_id}")))?; + if receipt.journal.bytes.len() != 32 { + return Err(ProverError::UnexpectedError(anyhow!( + "Shrink BitVM2 requires a journal of 32 bytes, got {}", + receipt.journal.bytes.len() + ))); + } + let proof_id = format!("snark_{}", Uuid::new_v4()); + self.state.proofs.write().await.insert(proof_id.clone(), ProofData::default()); + + tracing::debug!("shrink bitvm2 identity_p254 for proof {proof_id}"); + let succinct_receipt = receipt.inner.succinct().unwrap(); + let p254_receipt = risc0_zkvm::recursion::identity_p254(succinct_receipt) + .context("identity predicate failed")?; + + tracing::info!("Completing identity predicate, {proof_id}"); + + let work_dir = + if let Some(work_dir) = work_dir { work_dir } else { temp_dir.path().to_path_buf() }; + + let compress_result = + shrink_bitvm2::prove_and_verify(&proof_id, &work_dir, p254_receipt, receipt.journal) + .await + .map_err(ProverError::from); + + let compressed_bytes = compress_result + .as_ref() + .map(|receipt| bincode::serialize(receipt).unwrap()) + .unwrap_or_default(); + + let mut proofs = self.state.proofs.write().await; + let proof = proofs.get_mut(&proof_id).unwrap(); + match compress_result { + Ok(_) => { + proof.status = Status::Succeeded; + proof.compressed_receipt = Some(compressed_bytes); + + Ok(proof_id) + } + Err(err) => { + proof.status = Status::Failed; + proof.error_msg = err.to_string(); + + Err(err) + } + } + } + async fn get_shrink_bitvm2_receipt( + &self, + proof_id: &str, + ) -> Result>, ProverError> { + let proofs = self.state.proofs.read().await; + let proof_data = proofs + .get(proof_id) + .ok_or_else(|| ProverError::NotFound(format!("proof {proof_id}")))?; + Ok(proof_data.compressed_receipt.as_ref().cloned()) + } } #[cfg(test)] mod tests { use super::*; + use ark_ff::PrimeField; use boundless_market_test_utils::{ECHO_ELF, ECHO_ID}; - use risc0_zkvm::sha::Digest; + use risc0_zkvm::{sha::Digest, Groth16Seal}; + use shrink_bitvm2::ShrinkBitvm2ReceiptClaim; + use tempfile::tempdir; use tokio::test; #[test] @@ -496,6 +569,53 @@ mod tests { receipt.verify(image_id).unwrap(); } + #[test_log::test(tokio::test)] + async fn test_shrink() { + let work_dir = tempdir().expect("Failed to create temp dir"); + let prover = DefaultProver::new(); + + // Upload test data + let input_data = [255u8; 32].to_vec(); // Example input data + let input_id = prover.upload_input(input_data.clone()).await.unwrap(); + let image_id = Digest::from(ECHO_ID); + prover.upload_image(&image_id.to_string(), ECHO_ELF.to_vec()).await.unwrap(); + + // Run SNARK proving + let ProofResult { id: stark_id, .. } = + prover.prove_and_monitor_stark(&image_id.to_string(), &input_id, vec![]).await.unwrap(); + + let snark_id = + prover.shrink_bitvm2(&stark_id, Some(work_dir.path().to_path_buf())).await.unwrap(); + + // Fetch the compressed receipt + let compressed_receipt = prover.get_compressed_receipt(&snark_id).await.unwrap().unwrap(); + let shrink_receipt: Receipt = bincode::deserialize(&compressed_receipt).unwrap(); + + let stark_receipt = prover.get_receipt(&stark_id).await.unwrap().unwrap(); + + let groth16_receipt = shrink_receipt.inner.groth16().unwrap(); + let groth16_seal = Groth16Seal::from_vec(&groth16_receipt.seal) + .expect("Failed to create Groth16 seal from receipt"); + + let final_output_bytes = + ShrinkBitvm2ReceiptClaim::ok(image_id, stark_receipt.journal.bytes).digest().into(); + let public_input_scalar = ark_bn254::Fr::from_be_bytes_mod_order(&final_output_bytes); + + let public_input_scalar_str = public_input_scalar.to_string(); + let public_input_scalar = + risc0_groth16::PublicInputsJson { values: vec![public_input_scalar_str] } + .to_scalar() + .unwrap(); + println!("R0 Verify Start"); + + let verifying_key = shrink_bitvm2::get_r0_verifying_key(); + + let v = risc0_groth16::Verifier::new(&groth16_seal, &public_input_scalar, &verifying_key) + .unwrap(); + println!("R0 Verify result: {:?}", v.verify().is_ok()); + assert!(v.verify().is_ok(), "R0 verification failed"); + } + #[test] async fn test_error_handling() { let prover = DefaultProver::new(); diff --git a/crates/broker/src/provers/mod.rs b/crates/broker/src/provers/mod.rs index 394eeab9d..b59dccb98 100644 --- a/crates/broker/src/provers/mod.rs +++ b/crates/broker/src/provers/mod.rs @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use std::sync::Arc; +use std::{path::PathBuf, sync::Arc}; use async_trait::async_trait; use bonsai_sdk::SdkErr; @@ -140,6 +140,16 @@ pub trait Prover { async fn get_journal(&self, proof_id: &str) -> Result>, ProverError>; async fn compress(&self, proof_id: &str) -> Result; async fn get_compressed_receipt(&self, proof_id: &str) -> Result>, ProverError>; + + async fn shrink_bitvm2( + &self, + proof_id: &str, + work_dir: Option, + ) -> Result; + async fn get_shrink_bitvm2_receipt( + &self, + proof_id: &str, + ) -> Result>, ProverError>; } pub type ProverObj = Arc; diff --git a/crates/broker/src/proving.rs b/crates/broker/src/proving.rs index ba3a68849..3fd5b134d 100644 --- a/crates/broker/src/proving.rs +++ b/crates/broker/src/proving.rs @@ -24,7 +24,7 @@ use crate::{ provers::ProverObj, task::{RetryRes, RetryTask, SupervisorErr}, utils::cancel_proof_and_fail_order, - Order, OrderStateChange, OrderStatus, + CompressionType, Order, OrderStateChange, OrderStatus, }; use anyhow::{Context, Result}; use thiserror::Error; @@ -92,7 +92,7 @@ impl ProvingService { &self, order_id: &str, stark_proof_id: &str, - is_groth16: bool, + compression_type: CompressionType, snark_proof_id: Option, ) -> Result { let proof_res = self @@ -101,9 +101,25 @@ impl ProvingService { .await .context("Monitoring proof (stark) failed")?; - if is_groth16 && snark_proof_id.is_none() { - let compressed_proof_id = - self.prover.compress(stark_proof_id).await.context("Failed to compress proof")?; + tracing::info!( + "compression_type: {compression_type:?}, snark_proof_id: {snark_proof_id:?}" + ); + let is_compress = compression_type != CompressionType::None; + + if is_compress && snark_proof_id.is_none() { + let compressed_proof_id = match compression_type { + CompressionType::Groth16 => self + .prover + .compress(stark_proof_id) + .await + .context("Failed to compress proof")?, + CompressionType::ShrinkBitvm2 => self + .prover + .shrink_bitvm2(stark_proof_id, None) + .await + .context("Failed to shrink proof")?, + CompressionType::None => unreachable!("Compression type should not be None here"), + }; self.db .set_order_compressed_proof_id(order_id, &compressed_proof_id) .await @@ -114,7 +130,7 @@ impl ProvingService { })?; }; - let status = match is_groth16 { + let status = match is_compress { false => OrderStatus::PendingAgg, true => OrderStatus::SkipAggregation, }; @@ -227,7 +243,7 @@ impl ProvingService { let monitor_task = self.monitor_proof_internal( &order_id, proof_id, - order.is_groth16(), + order.compression_type(), order.compressed_proof_id, ); tokio::pin!(monitor_task); diff --git a/crates/broker/src/storage.rs b/crates/broker/src/storage.rs index b506a2507..0beff6605 100644 --- a/crates/broker/src/storage.rs +++ b/crates/broker/src/storage.rs @@ -81,9 +81,9 @@ pub(crate) async fn create_uri_handler( match uri.scheme() { "file" => { - if !is_dev_mode() { - return Err(StorageErr::UnsupportedScheme("file".to_string())); - } + // if !is_dev_mode() { + // return Err(StorageErr::UnsupportedScheme("file".to_string())); + // } let max_size = if skip_max_size_check { usize::MAX } else { diff --git a/crates/broker/src/submitter.rs b/crates/broker/src/submitter.rs index a96de9327..04d35687f 100644 --- a/crates/broker/src/submitter.rs +++ b/crates/broker/src/submitter.rs @@ -30,7 +30,7 @@ use boundless_market::{ boundless_market_contract::CallbackData, encode_seal, AssessorJournal, AssessorReceipt, Fulfillment, PredicateType, }, - selector::is_groth16_selector, + selector::{is_groth16_selector, is_shrink_bitvm2_selector}, }; use hex::FromHex; use risc0_aggregation::{SetInclusionReceipt, SetInclusionReceiptVerifierParameters}; @@ -298,7 +298,9 @@ where let order_claim = ReceiptClaim::ok(order_img_id, MaybePruned::Pruned(order_journal.digest())); let order_claim_digest = order_claim.digest(); - let seal = if is_groth16_selector(order_request.requirements.selector) { + let seal = if is_groth16_selector(order_request.requirements.selector) + || is_shrink_bitvm2_selector(order_request.requirements.selector) + { let compressed_proof_id = self.db.get_order_compressed_proof_id(order_id).await.context( "Failed to get order compressed proof ID from DB for submission", diff --git a/crates/broker/src/utils.rs b/crates/broker/src/utils.rs index 8233ad8dd..62861c751 100644 --- a/crates/broker/src/utils.rs +++ b/crates/broker/src/utils.rs @@ -96,7 +96,7 @@ pub async fn estimate_gas_to_fulfill( .context("unsupported selector")? { ProofType::Any | ProofType::Inclusion => 0, - ProofType::Groth16 => groth16, + ProofType::Groth16 | ProofType::ShrinkBitvm2 => groth16, proof_type => { tracing::warn!("Unknown proof type in gas cost estimation: {proof_type:?}"); 0 diff --git a/crates/guest/assessor/assessor-guest/src/main.rs b/crates/guest/assessor/assessor-guest/src/main.rs index ae80b349b..68c010adc 100644 --- a/crates/guest/assessor/assessor-guest/src/main.rs +++ b/crates/guest/assessor/assessor-guest/src/main.rs @@ -7,7 +7,6 @@ #![no_std] extern crate alloc; - use alloc::vec::Vec; use alloy_primitives::{Address, U256}; use alloy_sol_types::{SolStruct, SolValue}; diff --git a/crates/shrink_bitvm2/Cargo.toml b/crates/shrink_bitvm2/Cargo.toml new file mode 100644 index 000000000..4da876b8a --- /dev/null +++ b/crates/shrink_bitvm2/Cargo.toml @@ -0,0 +1,32 @@ +[package] +name = "shrink_bitvm2" +resolver = "2" +version.workspace = true +edition.workspace = true +homepage.workspace = true +repository.workspace = true +publish = false + +[package.metadata.release] +release = false + +[dependencies] +anyhow = { workspace = true } +hex = { workspace = true } +num-bigint = { version = "0.4", features = ["std"] } +num-traits = "0.2.19" +risc0-groth16 = { version = "2.0.2", features = ["prove"] } +risc0-zkvm = { workspace = true, features = ["std", "client", "prove"] } +serde = { workspace = true } +serde_json = { workspace = true } +sha2 = "0.10" +tempfile = { workspace = true } +tokio = { workspace = true, features = ["rt-multi-thread", "macros", "fs", "process"] } + +tracing = { workspace = true } + +ark-bn254 = "0.5.0" +ark-ff = "0.5.0" +ark-groth16 = { version = "0.5.0" } +ark-serialize = "0.5.0" +blake3 = { version = "1.5.0" } diff --git a/crates/shrink_bitvm2/src/lib.rs b/crates/shrink_bitvm2/src/lib.rs new file mode 100644 index 000000000..66bdb28b7 --- /dev/null +++ b/crates/shrink_bitvm2/src/lib.rs @@ -0,0 +1,425 @@ +use std::path::Path; + +use hex::FromHex; +use risc0_zkvm::{ + digest, seal_to_json, sha::Digestible, Digest, Groth16ProofJson, Groth16Receipt, Groth16Seal, + Journal, MaybePruned, Receipt, ReceiptClaim, SuccinctReceipt, SystemState, +}; + +use anyhow::{ensure, Context, Result}; +use num_bigint::BigUint; +use num_traits::Num; + +use serde::Serialize; +use tokio::process::Command; +pub const ALLOWED_CONTROL_ROOT: Digest = + digest!("ce52bf56033842021af3cf6db8a50d1b7535c125a34f1a22c6fdcf002c5a1529"); + +pub const BN254_IDENTITY_CONTROL_ID: Digest = + digest!("c07a65145c3cb48b6101962ea607a4dd93c753bb26975cb47feb00d3666e4404"); + +#[derive(Clone, Debug, Serialize)] +pub struct ShrinkBitvm2ReceiptClaim { + control_root: Digest, + pre: MaybePruned, + post: MaybePruned, + control_id: Digest, + // Note: This journal has to be exactly 32 bytes + journal: Vec, +} + +impl ShrinkBitvm2ReceiptClaim { + pub fn ok( + image_id: impl Into, + journal: impl Into>, + ) -> ShrinkBitvm2ReceiptClaim { + let verifier_params = risc0_zkvm::SuccinctReceiptVerifierParameters::default(); + let control_root = verifier_params.control_root; + Self { + control_root, + pre: MaybePruned::Pruned(image_id.into()), + post: MaybePruned::Value(SystemState { pc: 0, merkle_root: Digest::ZERO }), + control_id: BN254_IDENTITY_CONTROL_ID, + journal: journal.into(), + } + } +} + +impl Digestible for ShrinkBitvm2ReceiptClaim { + fn digest(&self) -> Digest { + use sha2::{Digest as _, Sha256}; + + let mut control_root_bytes: [u8; 32] = self.control_root.as_bytes().try_into().unwrap(); + for byte in &mut control_root_bytes { + *byte = byte.reverse_bits(); + } + let mut hasher = Sha256::new(); + hasher.update(control_root_bytes); + hasher.update(self.pre.digest()); + hasher.update(self.post.digest()); + hasher.update(self.control_id.as_bytes()); + + let output_prefix = hasher.finalize(); + + // final blake3 hash + let mut hasher = blake3::Hasher::new(); + hasher.update(&output_prefix); + hasher.update(&self.journal); + + let mut digest_bytes: [u8; 32] = hasher.finalize().into(); + // trim to 31 bytes + digest_bytes[31] = 0; + // shift because of endianness + digest_bytes.rotate_right(1); + digest_bytes.into() + } +} + +pub async fn prove_and_verify( + proof_id: &str, + work_dir: &Path, + p254_receipt: SuccinctReceipt, + journal: Journal, +) -> Result { + let receipt_claim = p254_receipt.claim.clone().value()?; + + let seal_path = work_dir.join("input.json"); + let proof_path = work_dir.join("proof.json"); + let public_path = work_dir.join("public.json"); + + write_seal(&journal.bytes, p254_receipt, &receipt_claim, &seal_path).await?; + + let proof_json = generate_proof(work_dir, &proof_path).await?; + tracing::info!("{proof_id}: generated shrink groth16 proof"); + + let image_id = receipt_claim.pre.digest(); + let final_receipt = finalize(journal.bytes, receipt_claim, proof_json)?; + let output_bytes = decode_output(&public_path).await?; + tracing::info!("bvm2 decoded output byte length: {}", output_bytes.len()); + + check_output(image_id, &final_receipt, &output_bytes)?; + + verify_proof(&final_receipt, &output_bytes)?; + + Ok(final_receipt) +} + +fn check_output(image_id: Digest, final_receipt: &Receipt, output_bytes: &[u8]) -> Result<()> { + let expected_output_bytes: [u8; 32] = + ShrinkBitvm2ReceiptClaim::ok(image_id, final_receipt.journal.bytes.clone()).digest().into(); + + let expected_output_bytes: [u8; 31] = expected_output_bytes[1..=31].try_into()?; + tracing::info!("check output: computed output: {}", hex::encode(expected_output_bytes)); + + ensure!(expected_output_bytes == output_bytes, "check output: public output mismatch"); + + Ok(()) +} + +async fn decode_output(public_path: &Path) -> Result> { + let output_content_dec = tokio::fs::read_to_string(public_path).await?; + + // Convert output_content_dec from decimal to hex + let parsed_json: serde_json::Value = serde_json::from_str(&output_content_dec)?; + let output_str = parsed_json[0].as_str().context("read public output from json")?; + let output_content_hex = BigUint::from_str_radix(output_str, 10)?.to_str_radix(16); + + // If the length of the hexadecimal string is odd, add a leading zero + let output_content_hex = if output_content_hex.len() % 2 == 0 { + output_content_hex + } else { + format!("0{output_content_hex}") + }; + + Ok(hex::decode(&output_content_hex)?) +} + +fn finalize( + journal_bytes: Vec, + receipt_claim: ReceiptClaim, + proof_json: Groth16ProofJson, +) -> Result { + let seal: Groth16Seal = proof_json.try_into()?; + let verifier_parameters_digest = + Digest::from_hex("b72859b60cfe0bb13cbde70859fbc67ef9dbd5410bbe66bdb7be64a3dcf6814e") + .unwrap(); // TODO(ec2): dont hardcode this (actually not sure if this is ever even used, so could be digest zero) + let groth16_receipt = + Groth16Receipt::new(seal.to_vec(), receipt_claim.into(), verifier_parameters_digest); + let receipt = Receipt::new(risc0_zkvm::InnerReceipt::Groth16(groth16_receipt), journal_bytes); + Ok(receipt) +} + +async fn write_seal( + journal_bytes: &[u8], + p254_receipt: SuccinctReceipt, + receipt_claim: &ReceiptClaim, + seal_path: &Path, +) -> Result<()> { + tracing::info!("Writing seal"); + + let seal_bytes = p254_receipt.get_seal_bytes(); + let mut seal_json = Vec::new(); + seal_to_json(seal_bytes.as_slice(), &mut seal_json)?; + let mut seal_json: serde_json::Value = + serde_json::from_str(std::str::from_utf8(seal_json.as_slice())?)?; + + let mut journal_bits = Vec::new(); + for byte in journal_bytes { + for i in 0..8 { + journal_bits.push((byte >> (7 - i)) & 1); + } + } + + let pre_state_digest_bits: Vec<_> = receipt_claim + .pre + .digest() + .as_bytes() + .iter() + .flat_map(|&byte| (0..8).rev().map(move |i| ((byte >> i) & 1).to_string())) + .collect(); + + let post_state_digest_bits: Vec<_> = receipt_claim + .post + .digest() + .as_bytes() + .iter() + .flat_map(|&byte| (0..8).rev().map(move |i| ((byte >> i) & 1).to_string())) + .collect(); + + let mut id_bn254_fr_bits: Vec = p254_receipt + .control_id + .as_bytes() + .iter() + .flat_map(|&byte| (0..8).rev().map(move |i| ((byte >> i) & 1).to_string())) + .collect(); + id_bn254_fr_bits.remove(248); + id_bn254_fr_bits.remove(248); + + let mut succinct_control_root_bytes: [u8; 32] = + risc0_zkvm::SuccinctReceiptVerifierParameters::default() + .control_root + .as_bytes() + .try_into()?; + + succinct_control_root_bytes.reverse(); + let succinct_control_root_hex = hex::encode(succinct_control_root_bytes); + + let a1_str = succinct_control_root_hex[0..32].to_string(); + let a0_str = succinct_control_root_hex[32..64].to_string(); + let a0_dec = to_decimal(&a0_str).context("a0_str returned None")?; + let a1_dec = to_decimal(&a1_str).context("a1_str returned None")?; + + let control_root = vec![a0_dec, a1_dec]; + + seal_json["journal_digest_bits"] = journal_bits.into(); + seal_json["pre_state_digest_bits"] = pre_state_digest_bits.into(); + seal_json["post_state_digest_bits"] = post_state_digest_bits.into(); + seal_json["id_bn254_fr_bits"] = id_bn254_fr_bits.into(); + seal_json["control_root"] = control_root.into(); + + tokio::fs::write(seal_path, serde_json::to_string_pretty(&seal_json)?).await?; + + Ok(()) +} + +// #!/bin/bash +// +// set -eoux +// +// ulimit -s unlimited +// ./verify_for_guest /mnt/input.json output.wtns +// rapidsnark verify_for_guest_final.zkey output.wtns /mnt/proof.json /mnt/public.json + +pub async fn generate_proof(work_dir: &Path, proof_path: &Path) -> Result { + tracing::info!("docker run ozancw/risc0-to-bitvm2-groth16-prover"); + + let volume = format!("{}:/mnt", work_dir.display()); + let status = Command::new("docker") + .args(["run", "--rm", "-v", &volume, "ozancw/risc0-to-bitvm2-groth16-prover"]) + .status() + .await?; + + anyhow::ensure!( + status.success(), + "ozancw/risc0-to-bitvm2-groth16-prover failed: {:?}", + status.code() + ); + + let proof_content = tokio::fs::read_to_string(proof_path).await?; + let proof_json: Groth16ProofJson = serde_json::from_str(&proof_content)?; + + Ok(proof_json) +} + +fn to_decimal(s: &str) -> Option { + let int = BigUint::from_str_radix(s, 16).ok(); + int.map(|n| n.to_str_radix(10)) +} + +pub fn verify_proof(final_receipt: &Receipt, output_bytes: &[u8]) -> Result<()> { + tracing::info!("verify_proof output bytes: {}", hex::encode(output_bytes)); + use ark_ff::PrimeField; + + let ark_proof = from_seal(&final_receipt.inner.groth16()?.seal); + let public_input_scalar = ark_bn254::Fr::from_be_bytes_mod_order(output_bytes); + let ark_vk = get_ark_verifying_key(); + let ark_pvk = ark_groth16::prepare_verifying_key(&ark_vk); + let res = ark_groth16::Groth16::::verify_proof( + &ark_pvk, + &ark_proof, + &[public_input_scalar], + ) + .unwrap(); + tracing::info!("Shrink bitvm2 Proof verification result: {:?}", res); + + ensure!(res, "proof verification failed"); + + Ok(()) +} + +pub fn get_ark_verifying_key() -> ark_groth16::VerifyingKey { + use ark_bn254::{Fq, Fq2, G1Affine, G2Affine}; + use std::str::FromStr; + + let alpha_g1 = G1Affine::new( + Fq::from_str( + "20491192805390485299153009773594534940189261866228447918068658471970481763042", + ) + .unwrap(), + Fq::from_str( + "9383485363053290200918347156157836566562967994039712273449902621266178545958", + ) + .unwrap(), + ); + + let beta_g2 = G2Affine::new( + Fq2::new( + Fq::from_str( + "6375614351688725206403948262868962793625744043794305715222011528459656738731", + ) + .unwrap(), + Fq::from_str( + "4252822878758300859123897981450591353533073413197771768651442665752259397132", + ) + .unwrap(), + ), + Fq2::new( + Fq::from_str( + "10505242626370262277552901082094356697409835680220590971873171140371331206856", + ) + .unwrap(), + Fq::from_str( + "21847035105528745403288232691147584728191162732299865338377159692350059136679", + ) + .unwrap(), + ), + ); + + let gamma_g2 = G2Affine::new( + Fq2::new( + Fq::from_str( + "10857046999023057135944570762232829481370756359578518086990519993285655852781", + ) + .unwrap(), + Fq::from_str( + "11559732032986387107991004021392285783925812861821192530917403151452391805634", + ) + .unwrap(), + ), + Fq2::new( + Fq::from_str( + "8495653923123431417604973247489272438418190587263600148770280649306958101930", + ) + .unwrap(), + Fq::from_str( + "4082367875863433681332203403145435568316851327593401208105741076214120093531", + ) + .unwrap(), + ), + ); + + let delta_g2 = G2Affine::new( + Fq2::new( + Fq::from_str( + "19928663713463533589216209779412278386769407450988172849262535478593422929698", + ) + .unwrap(), + Fq::from_str( + "19916519943909223643323234301580053157586699704876134064841182937085943926141", + ) + .unwrap(), + ), + Fq2::new( + Fq::from_str( + "4584600978911428195337731119171761277167808711062125916470525050324985708782", + ) + .unwrap(), + Fq::from_str( + "903010326261527050999816348900764705196723158942686053018929539519969664840", + ) + .unwrap(), + ), + ); + + let gamma_abc_g1 = vec![ + G1Affine::new( + Fq::from_str( + "6698887085900109660417671413804888867145870700073340970189635830129386206569", + ) + .unwrap(), + Fq::from_str( + "10431087902009508261375793061696708147989126018612269070732549055898651692604", + ) + .unwrap(), + ), + G1Affine::new( + Fq::from_str( + "20225609417084538563062516991929114218412992453664808591983416996515711931386", + ) + .unwrap(), + Fq::from_str( + "3236310410959095762960658876334609343091075204896196791007975095263664214628", + ) + .unwrap(), + ), + ]; + + ark_groth16::VerifyingKey { alpha_g1, beta_g2, gamma_g2, delta_g2, gamma_abc_g1 } +} +pub fn get_r0_verifying_key() -> risc0_groth16::VerifyingKey { + let json_content = std::fs::read_to_string("/home/etu/risc0-to-bitvm2/vkey_guest.json") + .expect("Failed to read verification key JSON file"); + let vk_json: risc0_groth16::VerifyingKeyJson = + serde_json::from_str(&json_content).expect("Failed to parse verification key JSON"); + + vk_json.verifying_key().unwrap() +} +pub fn from_seal(seal_bytes: &[u8]) -> ark_groth16::Proof { + use ark_bn254::{Fq, Fq2, G1Affine, G2Affine}; + use ark_ff::{Field, PrimeField}; + + let a = G1Affine::new( + Fq::from_be_bytes_mod_order(&seal_bytes[0..32]), + Fq::from_be_bytes_mod_order(&seal_bytes[32..64]), + ); + + let b = G2Affine::new( + Fq2::from_base_prime_field_elems([ + Fq::from_be_bytes_mod_order(&seal_bytes[96..128]), + Fq::from_be_bytes_mod_order(&seal_bytes[64..96]), + ]) + .unwrap(), + Fq2::from_base_prime_field_elems([ + Fq::from_be_bytes_mod_order(&seal_bytes[160..192]), + Fq::from_be_bytes_mod_order(&seal_bytes[128..160]), + ]) + .unwrap(), + ); + + let c = G1Affine::new( + Fq::from_be_bytes_mod_order(&seal_bytes[192..224]), + Fq::from_be_bytes_mod_order(&seal_bytes[224..256]), + ); + + ark_groth16::Proof { a, b, c } +} diff --git a/examples/composition/Cargo.lock b/examples/composition/Cargo.lock index dba0d5a95..95f7958d5 100644 --- a/examples/composition/Cargo.lock +++ b/examples/composition/Cargo.lock @@ -599,7 +599,7 @@ dependencies = [ "alloy-json-abi", "alloy-sol-macro-input", "const-hex", - "heck 0.5.0", + "heck", "indexmap 2.10.0", "proc-macro-error2", "proc-macro2", @@ -618,7 +618,7 @@ dependencies = [ "alloy-json-abi", "const-hex", "dunce", - "heck 0.5.0", + "heck", "macro-string", "proc-macro2", "quote", @@ -840,6 +840,7 @@ dependencies = [ "digest 0.10.7", "fnv", "merlin", + "rayon", "sha2", ] @@ -872,6 +873,7 @@ dependencies = [ "num-bigint 0.4.6", "num-integer", "num-traits", + "rayon", "zeroize", ] @@ -930,6 +932,7 @@ dependencies = [ "num-bigint 0.4.6", "num-traits", "paste", + "rayon", "zeroize", ] @@ -1014,6 +1017,7 @@ dependencies = [ "ark-relations", "ark-serialize 0.5.0", "ark-std 0.5.0", + "rayon", ] [[package]] @@ -1029,6 +1033,7 @@ dependencies = [ "educe", "fnv", "hashbrown 0.15.4", + "rayon", ] [[package]] @@ -1092,6 +1097,7 @@ dependencies = [ "arrayvec", "digest 0.10.7", "num-bigint 0.4.6", + "rayon", ] [[package]] @@ -1145,6 +1151,7 @@ checksum = "246a225cc6131e9ee4f24619af0f19d67761fff15d7ccc22e42b80846e69449a" dependencies = [ "num-traits", "rand 0.8.5", + "rayon", ] [[package]] @@ -1153,6 +1160,12 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7d902e3d592a523def97af8f317b08ce16b7ab854c1985a0c671e6f15cebc236" +[[package]] +name = "arrayref" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" + [[package]] name = "arrayvec" version = "0.7.6" @@ -2042,6 +2055,19 @@ dependencies = [ "digest 0.10.7", ] +[[package]] +name = "blake3" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3888aaa89e4b2a40fca9848e400f6a658a5a3978de7be858e209cafa8be9a4a0" +dependencies = [ + "arrayref", + "arrayvec", + "cc", + "cfg-if", + "constant_time_eq", +] + [[package]] name = "block" version = "0.1.6" @@ -2084,15 +2110,14 @@ dependencies = [ [[package]] name = "bonsai-sdk" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bce8d6acc5286a16e94c29e9c885d1869358885e08a6feeb6bc54e36fe20055" +version = "1.4.1" +source = "git+https://github.com/risc0/risc0?branch=flaub%2Fshrink-bitvm2#6ed3f0321638ae7eb9c097b8aa8becba3f4b1350" dependencies = [ "duplicate", "maybe-async", "reqwest", "serde", - "thiserror 1.0.69", + "thiserror 2.0.12", "tokio", ] @@ -2187,6 +2212,7 @@ dependencies = [ "guest-assessor", "guest-set-builder", "guest-util", + "hex", "risc0-aggregation", "risc0-circuit-recursion", "risc0-ethereum-contracts", @@ -2217,6 +2243,8 @@ dependencies = [ "http-cache-reqwest", "moka", "notify", + "num-bigint 0.4.6", + "num-traits", "rand 0.9.1", "reqwest", "reqwest-middleware", @@ -2227,6 +2255,7 @@ dependencies = [ "serde", "serde_json", "sha2", + "shrink_bitvm2", "sqlx", "tempfile", "thiserror 2.0.12", @@ -2456,7 +2485,7 @@ version = "4.5.41" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef4f52386a59ca4c860f7393bcf8abd8dfd91ecccc0f774635ff68e92eeef491" dependencies = [ - "heck 0.5.0", + "heck", "proc-macro2", "quote", "syn 2.0.104", @@ -2540,6 +2569,12 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "constant_time_eq" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" + [[package]] name = "core-foundation" version = "0.9.4" @@ -3061,12 +3096,13 @@ checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" [[package]] name = "duplicate" -version = "1.0.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de78e66ac9061e030587b2a2e75cc88f22304913c907b11307bca737141230cb" +checksum = "97af9b5f014e228b33e77d75ee0e6e87960124f0f4b16337b586a6bec91867b1" dependencies = [ - "heck 0.4.1", - "proc-macro-error", + "heck", + "proc-macro2", + "proc-macro2-diagnostics", ] [[package]] @@ -3930,12 +3966,6 @@ dependencies = [ "stable_deref_trait", ] -[[package]] -name = "heck" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" - [[package]] name = "heck" version = "0.5.0" @@ -5808,30 +5838,6 @@ dependencies = [ "toml_edit", ] -[[package]] -name = "proc-macro-error" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" -dependencies = [ - "proc-macro-error-attr", - "proc-macro2", - "quote", - "syn 1.0.109", - "version_check", -] - -[[package]] -name = "proc-macro-error-attr" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" -dependencies = [ - "proc-macro2", - "quote", - "version_check", -] - [[package]] name = "proc-macro-error-attr2" version = "2.0.0" @@ -5863,6 +5869,19 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "proc-macro2-diagnostics" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", + "version_check", + "yansi", +] + [[package]] name = "proptest" version = "1.7.0" @@ -7399,6 +7418,29 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +[[package]] +name = "shrink_bitvm2" +version = "0.14.0" +dependencies = [ + "anyhow", + "ark-bn254", + "ark-ff 0.5.0", + "ark-groth16", + "ark-serialize 0.5.0", + "blake3", + "hex", + "num-bigint 0.4.6", + "num-traits", + "risc0-groth16", + "risc0-zkvm", + "serde", + "serde_json", + "sha2", + "tempfile", + "tokio", + "tracing", +] + [[package]] name = "signal-hook-registry" version = "1.4.5" @@ -7595,7 +7637,7 @@ checksum = "19a9c1841124ac5a61741f96e1d9e2ec77424bf323962dd894bdb93f37d5219b" dependencies = [ "dotenvy", "either", - "heck 0.5.0", + "heck", "hex", "once_cell", "proc-macro2", @@ -7807,7 +7849,7 @@ version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" dependencies = [ - "heck 0.5.0", + "heck", "proc-macro2", "quote", "rustversion", @@ -7820,7 +7862,7 @@ version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c77a8c5abcaf0f9ce05d62342b7d298c346515365c36b673df4ebe3ced01fde8" dependencies = [ - "heck 0.5.0", + "heck", "proc-macro2", "quote", "rustversion", @@ -9269,6 +9311,12 @@ dependencies = [ "hashlink 0.9.1", ] +[[package]] +name = "yansi" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" + [[package]] name = "yoke" version = "0.8.0" diff --git a/examples/counter-with-callback/Cargo.lock b/examples/counter-with-callback/Cargo.lock index 890e81396..f7e96e7fa 100644 --- a/examples/counter-with-callback/Cargo.lock +++ b/examples/counter-with-callback/Cargo.lock @@ -72,9 +72,9 @@ checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" [[package]] name = "alloy" -version = "1.0.24" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48dff4dd98e17de00203f851800bbc8b76eb29a4d4e3e44074614338b7a3308d" +checksum = "8ad4eb51e7845257b70c51b38ef8d842d5e5e93196701fcbd757577971a043c6" dependencies = [ "alloy-consensus", "alloy-contract", @@ -107,9 +107,9 @@ dependencies = [ [[package]] name = "alloy-consensus" -version = "1.0.24" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eda689f7287f15bd3582daba6be8d1545bad3740fd1fb778f629a1fe866bb43b" +checksum = "ca3b746060277f3d7f9c36903bb39b593a741cb7afcb0044164c28f0e9b673f0" dependencies = [ "alloy-eips", "alloy-primitives", @@ -132,9 +132,9 @@ dependencies = [ [[package]] name = "alloy-consensus-any" -version = "1.0.24" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b5659581e41e8fe350ecc3593cb5c9dcffddfd550896390f2b78a07af67b0fa" +checksum = "bf98679329fa708fa809ea596db6d974da892b068ad45e48ac1956f582edf946" dependencies = [ "alloy-consensus", "alloy-eips", @@ -146,9 +146,9 @@ dependencies = [ [[package]] name = "alloy-contract" -version = "1.0.24" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "944085cf3ac8f32d96299aa26c03db7c8ca6cdaafdbc467910b889f0328e6b70" +checksum = "a10e47f5305ea08c37b1772086c1573e9a0a257227143996841172d37d3831bb" dependencies = [ "alloy-consensus", "alloy-dyn-abi", @@ -233,9 +233,9 @@ dependencies = [ [[package]] name = "alloy-eips" -version = "1.0.24" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f35887da30b5fc50267109a3c61cd63e6ca1f45967983641053a40ee83468c1" +checksum = "f562a81278a3ed83290e68361f2d1c75d018ae3b8589a314faf9303883e18ec9" dependencies = [ "alloy-eip2124", "alloy-eip2930", @@ -253,9 +253,9 @@ dependencies = [ [[package]] name = "alloy-genesis" -version = "1.0.24" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11d4009efea6f403b3a80531f9c6f70fc242399498ff71196a1688cc1c901f44" +checksum = "dc41384e9ab8c9b2fb387c52774d9d432656a28edcda1c2d4083e96051524518" dependencies = [ "alloy-eips", "alloy-primitives", @@ -292,9 +292,9 @@ dependencies = [ [[package]] name = "alloy-json-rpc" -version = "1.0.24" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "883dee3b4020fcb5667ee627b4f401e899dad82bf37b246620339dd980720ed9" +checksum = "12c454fcfcd5d26ed3b8cae5933cbee9da5f0b05df19b46d4bd4446d1f082565" dependencies = [ "alloy-primitives", "alloy-sol-types", @@ -307,9 +307,9 @@ dependencies = [ [[package]] name = "alloy-network" -version = "1.0.24" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd6e5b8ac1654a05c224390008e43634a2bdc74e181e02cf8ed591d8b3d4ad08" +checksum = "42d6d39eabe5c7b3d8f23ac47b0b683b99faa4359797114636c66e0743103d05" dependencies = [ "alloy-consensus", "alloy-consensus-any", @@ -333,9 +333,9 @@ dependencies = [ [[package]] name = "alloy-network-primitives" -version = "1.0.24" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80d7980333dd9391719756ac28bc2afa9baa705fc70ffd11dc86ab078dd64477" +checksum = "3704fa8b7ba9ba3f378d99b3d628c8bc8c2fc431b709947930f154e22a8368b6" dependencies = [ "alloy-consensus", "alloy-eips", @@ -346,9 +346,9 @@ dependencies = [ [[package]] name = "alloy-node-bindings" -version = "1.0.24" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "984c20af8aee7d123bb4bf40cf758b362b38cb9ff7160d986b6face604a1e6a9" +checksum = "6441582b4fc44d4e3ce583848cf1a4e1c202eb7eb33193fe459869e965ae1e24" dependencies = [ "alloy-genesis", "alloy-hardforks", @@ -394,9 +394,9 @@ dependencies = [ [[package]] name = "alloy-provider" -version = "1.0.24" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "478a42fe167057b7b919cd8b0c2844f0247f667473340dad100eaf969de5754e" +checksum = "08800e8cbe70c19e2eb7cf3d7ff4b28bdd9b3933f8e1c8136c7d910617ba03bf" dependencies = [ "alloy-chains", "alloy-consensus", @@ -420,6 +420,7 @@ dependencies = [ "either", "futures", "futures-utils-wasm", + "http 1.3.1", "lru 0.13.0", "parking_lot 0.12.4", "pin-project", @@ -457,9 +458,9 @@ dependencies = [ [[package]] name = "alloy-rpc-client" -version = "1.0.24" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a0c6d723fbdf4a87454e2e3a275e161be27edcfbf46e2e3255dd66c138634b6" +checksum = "162301b5a57d4d8f000bf30f4dcb82f9f468f3e5e846eeb8598dd39e7886932c" dependencies = [ "alloy-json-rpc", "alloy-primitives", @@ -480,9 +481,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types" -version = "1.0.24" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c41492dac39365b86a954de86c47ec23dcc7452cdb2fde591caadc194b3e34c6" +checksum = "6cd8ca94ae7e2b32cc3895d9981f3772aab0b4756aa60e9ed0bcfee50f0e1328" dependencies = [ "alloy-primitives", "alloy-rpc-types-eth", @@ -492,9 +493,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-anvil" -version = "1.0.24" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10493fa300a2757d8134f584800fef545c15905c95122bed1f6dde0b0d9dae27" +checksum = "9f3ff6a778ebda3deaed9af17930d678611afe1effa895c4260b61009c314f82" dependencies = [ "alloy-primitives", "alloy-rpc-types-eth", @@ -504,9 +505,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-any" -version = "1.0.24" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f7eb22670a972ad6c222a6c6dac3eef905579acffe9d63ab42be24c7d158535" +checksum = "076b47e834b367d8618c52dd0a0d6a711ddf66154636df394805300af4923b8a" dependencies = [ "alloy-consensus-any", "alloy-rpc-types-eth", @@ -515,9 +516,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-eth" -version = "1.0.24" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b777b98526bbe5b7892ca22a7fd5f18ed624ff664a79f40d0f9f2bf94ba79a84" +checksum = "2c2f847e635ec0be819d06e2ada4bcc4e4204026a83c4bfd78ae8d550e027ae7" dependencies = [ "alloy-consensus", "alloy-consensus-any", @@ -536,9 +537,9 @@ dependencies = [ [[package]] name = "alloy-serde" -version = "1.0.24" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee8d2c52adebf3e6494976c8542fbdf12f10123b26e11ad56f77274c16a2a039" +checksum = "ae699248d02ade9db493bbdae61822277dc14ae0f82a5a4153203b60e34422a6" dependencies = [ "alloy-primitives", "serde", @@ -547,9 +548,9 @@ dependencies = [ [[package]] name = "alloy-signer" -version = "1.0.24" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c0494d1e0f802716480aabbe25549c7f6bc2a25ff33b08fd332bbb4b7d06894" +checksum = "3cf7d793c813515e2b627b19a15693960b3ed06670f9f66759396d06ebe5747b" dependencies = [ "alloy-primitives", "async-trait", @@ -562,9 +563,9 @@ dependencies = [ [[package]] name = "alloy-signer-local" -version = "1.0.24" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59c2435eb8979a020763ced3fb478932071c56e5f75ea86db41f320915d325ba" +checksum = "51a424bc5a11df0d898ce0fd15906b88ebe2a6e4f17a514b51bc93946bb756bd" dependencies = [ "alloy-consensus", "alloy-network", @@ -599,7 +600,7 @@ dependencies = [ "alloy-json-abi", "alloy-sol-macro-input", "const-hex", - "heck 0.5.0", + "heck", "indexmap 2.10.0", "proc-macro-error2", "proc-macro2", @@ -618,7 +619,7 @@ dependencies = [ "alloy-json-abi", "const-hex", "dunce", - "heck 0.5.0", + "heck", "macro-string", "proc-macro2", "quote", @@ -651,13 +652,12 @@ dependencies = [ [[package]] name = "alloy-transport" -version = "1.0.24" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c0107675e10c7f248bf7273c1e7fdb02409a717269cc744012e6f3c39959bfb" +checksum = "4f317d20f047b3de4d9728c556e2e9a92c9a507702d2016424cd8be13a74ca5e" dependencies = [ "alloy-json-rpc", "alloy-primitives", - "auto_impl", "base64 0.22.1", "derive_more 2.0.1", "futures", @@ -675,9 +675,9 @@ dependencies = [ [[package]] name = "alloy-transport-http" -version = "1.0.24" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78e3736701b5433afd06eecff08f0688a71a10e0e1352e0bbf0bed72f0dd4e35" +checksum = "ff084ac7b1f318c87b579d221f11b748341d68b9ddaa4ffca5e62ed2b8cfefb4" dependencies = [ "alloy-json-rpc", "alloy-transport", @@ -706,9 +706,9 @@ dependencies = [ [[package]] name = "alloy-tx-macros" -version = "1.0.24" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6acb36318dfa50817154064fea7932adf2eec3f51c86680e2b37d7e8906c66bb" +checksum = "1154c8187a5ff985c95a8b2daa2fedcf778b17d7668e5e50e556c4ff9c881154" dependencies = [ "alloy-primitives", "darling", @@ -840,6 +840,7 @@ dependencies = [ "digest 0.10.7", "fnv", "merlin", + "rayon", "sha2", ] @@ -872,6 +873,7 @@ dependencies = [ "num-bigint 0.4.6", "num-integer", "num-traits", + "rayon", "zeroize", ] @@ -930,6 +932,7 @@ dependencies = [ "num-bigint 0.4.6", "num-traits", "paste", + "rayon", "zeroize", ] @@ -1014,6 +1017,7 @@ dependencies = [ "ark-relations", "ark-serialize 0.5.0", "ark-std 0.5.0", + "rayon", ] [[package]] @@ -1029,6 +1033,7 @@ dependencies = [ "educe", "fnv", "hashbrown 0.15.4", + "rayon", ] [[package]] @@ -1092,6 +1097,7 @@ dependencies = [ "arrayvec", "digest 0.10.7", "num-bigint 0.4.6", + "rayon", ] [[package]] @@ -1145,6 +1151,7 @@ checksum = "246a225cc6131e9ee4f24619af0f19d67761fff15d7ccc22e42b80846e69449a" dependencies = [ "num-traits", "rand 0.8.5", + "rayon", ] [[package]] @@ -1153,6 +1160,12 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7d902e3d592a523def97af8f317b08ce16b7ab854c1985a0c671e6f15cebc236" +[[package]] +name = "arrayref" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" + [[package]] name = "arrayvec" version = "0.7.6" @@ -2042,6 +2055,19 @@ dependencies = [ "digest 0.10.7", ] +[[package]] +name = "blake3" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3888aaa89e4b2a40fca9848e400f6a658a5a3978de7be858e209cafa8be9a4a0" +dependencies = [ + "arrayref", + "arrayvec", + "cc", + "cfg-if", + "constant_time_eq", +] + [[package]] name = "block" version = "0.1.6" @@ -2084,15 +2110,14 @@ dependencies = [ [[package]] name = "bonsai-sdk" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bce8d6acc5286a16e94c29e9c885d1869358885e08a6feeb6bc54e36fe20055" +version = "1.4.1" +source = "git+https://github.com/risc0/risc0?branch=flaub%2Fshrink-bitvm2#6ed3f0321638ae7eb9c097b8aa8becba3f4b1350" dependencies = [ "duplicate", "maybe-async", "reqwest", "serde", - "thiserror 1.0.69", + "thiserror 2.0.12", "tokio", ] @@ -2187,6 +2212,7 @@ dependencies = [ "guest-assessor", "guest-set-builder", "guest-util", + "hex", "risc0-aggregation", "risc0-circuit-recursion", "risc0-ethereum-contracts", @@ -2217,6 +2243,8 @@ dependencies = [ "http-cache-reqwest", "moka", "notify", + "num-bigint 0.4.6", + "num-traits", "rand 0.9.1", "reqwest", "reqwest-middleware", @@ -2227,6 +2255,7 @@ dependencies = [ "serde", "serde_json", "sha2", + "shrink_bitvm2", "sqlx", "tempfile", "thiserror 2.0.12", @@ -2456,7 +2485,7 @@ version = "4.5.41" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef4f52386a59ca4c860f7393bcf8abd8dfd91ecccc0f774635ff68e92eeef491" dependencies = [ - "heck 0.5.0", + "heck", "proc-macro2", "quote", "syn 2.0.104", @@ -2540,6 +2569,12 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "constant_time_eq" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" + [[package]] name = "core-foundation" version = "0.9.4" @@ -3061,12 +3096,13 @@ checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" [[package]] name = "duplicate" -version = "1.0.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de78e66ac9061e030587b2a2e75cc88f22304913c907b11307bca737141230cb" +checksum = "97af9b5f014e228b33e77d75ee0e6e87960124f0f4b16337b586a6bec91867b1" dependencies = [ - "heck 0.4.1", - "proc-macro-error", + "heck", + "proc-macro2", + "proc-macro2-diagnostics", ] [[package]] @@ -3336,6 +3372,7 @@ dependencies = [ "clap", "guest-util", "risc0-zkvm", + "shrink_bitvm2", "test-log", "tokio", "tracing", @@ -3928,12 +3965,6 @@ dependencies = [ "stable_deref_trait", ] -[[package]] -name = "heck" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" - [[package]] name = "heck" version = "0.5.0" @@ -5806,30 +5837,6 @@ dependencies = [ "toml_edit", ] -[[package]] -name = "proc-macro-error" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" -dependencies = [ - "proc-macro-error-attr", - "proc-macro2", - "quote", - "syn 1.0.109", - "version_check", -] - -[[package]] -name = "proc-macro-error-attr" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" -dependencies = [ - "proc-macro2", - "quote", - "version_check", -] - [[package]] name = "proc-macro-error-attr2" version = "2.0.0" @@ -5861,6 +5868,19 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "proc-macro2-diagnostics" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", + "version_check", + "yansi", +] + [[package]] name = "proptest" version = "1.7.0" @@ -6587,8 +6607,6 @@ dependencies = [ [[package]] name = "risc0-ethereum-contracts" version = "2.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d3a6978f67c13fcf3e9123d28882368a3a3d686f881a35bb0caaebc585f93d6" dependencies = [ "alloy", "alloy-primitives", @@ -7397,6 +7415,29 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +[[package]] +name = "shrink_bitvm2" +version = "0.14.0" +dependencies = [ + "anyhow", + "ark-bn254", + "ark-ff 0.5.0", + "ark-groth16", + "ark-serialize 0.5.0", + "blake3", + "hex", + "num-bigint 0.4.6", + "num-traits", + "risc0-groth16", + "risc0-zkvm", + "serde", + "serde_json", + "sha2", + "tempfile", + "tokio", + "tracing", +] + [[package]] name = "signal-hook-registry" version = "1.4.5" @@ -7593,7 +7634,7 @@ checksum = "19a9c1841124ac5a61741f96e1d9e2ec77424bf323962dd894bdb93f37d5219b" dependencies = [ "dotenvy", "either", - "heck 0.5.0", + "heck", "hex", "once_cell", "proc-macro2", @@ -7805,7 +7846,7 @@ version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" dependencies = [ - "heck 0.5.0", + "heck", "proc-macro2", "quote", "rustversion", @@ -7818,7 +7859,7 @@ version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c77a8c5abcaf0f9ce05d62342b7d298c346515365c36b673df4ebe3ced01fde8" dependencies = [ - "heck 0.5.0", + "heck", "proc-macro2", "quote", "rustversion", @@ -9267,6 +9308,12 @@ dependencies = [ "hashlink 0.9.1", ] +[[package]] +name = "yansi" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" + [[package]] name = "yoke" version = "0.8.0" diff --git a/examples/counter-with-callback/Cargo.toml b/examples/counter-with-callback/Cargo.toml index 8fd4070ca..7c0b21e79 100644 --- a/examples/counter-with-callback/Cargo.toml +++ b/examples/counter-with-callback/Cargo.toml @@ -29,3 +29,6 @@ url = "2.5" # Always optimize; otherwise, local proving takes much longer to run [profile.dev] opt-level = 3 + +[patch.crates-io] +risc0-ethereum-contracts = { path = "/home/etu/risc0-ethereum/contracts" } diff --git a/examples/counter-with-callback/apps/Cargo.toml b/examples/counter-with-callback/apps/Cargo.toml index 94a68ad7c..d947132df 100644 --- a/examples/counter-with-callback/apps/Cargo.toml +++ b/examples/counter-with-callback/apps/Cargo.toml @@ -11,6 +11,7 @@ boundless-market = { workspace = true } clap = { workspace = true } guest-util = { workspace = true } risc0-zkvm = { workspace = true } +shrink_bitvm2 = { path = "/home/etu/boundless/crates/shrink_bitvm2" } tokio = { workspace = true, features = ["full"] } tracing = { workspace = true } tracing-subscriber = { workspace = true, features = ["env-filter"] } diff --git a/examples/counter-with-callback/apps/src/main.rs b/examples/counter-with-callback/apps/src/main.rs index 6e1b7c51c..c3d1ee8ea 100644 --- a/examples/counter-with-callback/apps/src/main.rs +++ b/examples/counter-with-callback/apps/src/main.rs @@ -21,10 +21,13 @@ use crate::counter::{ICounter, ICounter::ICounterInstance}; use alloy::{primitives::Address, signers::local::PrivateKeySigner, sol_types::SolCall}; use anyhow::{Context, Result}; use boundless_market::{ - request_builder::RequirementParams, Client, Deployment, StorageProviderConfig, + contracts::Predicate, + request_builder::{OfferParams, RequirementParams}, + Client, Deployment, StorageProviderConfig, }; use clap::Parser; -use guest_util::ECHO_ELF; +use guest_util::{ECHO_ELF, ECHO_ID}; +use risc0_zkvm::{sha::Digestible, Digest, ReceiptClaim}; use tracing_subscriber::{filter::LevelFilter, prelude::*, EnvFilter}; use url::Url; @@ -88,21 +91,43 @@ async fn run(args: Args) -> Result<()> { .await .context("failed to build boundless client")?; - // We use a timestamp as input to the ECHO guest code as the Counter contract + let counter = ICounterInstance::new(args.counter_address, client.provider().clone()); + + // Use the current count as input to the ECHO guest code as the Counter contract // accepts only unique proofs. Using the same input twice would result in the same proof. - let echo_message = format!("{:?}", SystemTime::now()); + let echo_message = counter + .count() + .call() + .await + .with_context(|| format!("failed to call {}", ICounter::countCall::SIGNATURE))?; + + // Shrink Bitvm2 proofs require the input to be 32 bytes + let echo_message = echo_message.as_le_bytes(); + + // let r0_claim_digest = ReceiptClaim::ok(ECHO_ID, echo_message.to_vec()).digest(); + let blake3_claim_digest = + shrink_bitvm2::blake3_claim_digest(&Digest::from(ECHO_ID), echo_message.as_ref()); // Create a request with a callback to the counter contract let request = client .new_request() .with_program(ECHO_ELF) - .with_stdin(echo_message.as_bytes()) + .with_stdin(echo_message) // Add the callback to the counter contract by configuring the requirements .with_requirements( RequirementParams::builder() .callback_address(args.counter_address) - .callback_gas_limit(100_000), - ); + .callback_gas_limit(100_000) + .predicate(Predicate::claim_digest_match(blake3_claim_digest)), + ) + .with_offer( + OfferParams::builder() + .min_price(alloy::primitives::utils::parse_ether("0.001")?) + .max_price(alloy::primitives::utils::parse_ether("0.002")?) + .timeout(1000) + .lock_timeout(1000), + ) + .with_shrink_bitvm2_proof(); // Submit the request to the blockchain let (request_id, expires_at) = client.submit_onchain(request).await?; @@ -112,7 +137,7 @@ async fn run(args: Args) -> Result<()> { let (_journal, _seal) = client .wait_for_request_fulfillment( request_id, - Duration::from_secs(5), // check every 5 seconds + Duration::from_secs(10), // check every 5 seconds expires_at, ) .await?; @@ -120,7 +145,6 @@ async fn run(args: Args) -> Result<()> { // We interact with the Counter contract by calling the getCount function to check that the callback // was executed correctly. - let counter = ICounterInstance::new(args.counter_address, client.provider().clone()); let count = counter .count() .call() diff --git a/examples/counter/Cargo.lock b/examples/counter/Cargo.lock index 0de317f18..5114be64a 100644 --- a/examples/counter/Cargo.lock +++ b/examples/counter/Cargo.lock @@ -599,7 +599,7 @@ dependencies = [ "alloy-json-abi", "alloy-sol-macro-input", "const-hex", - "heck 0.5.0", + "heck", "indexmap 2.10.0", "proc-macro-error2", "proc-macro2", @@ -618,7 +618,7 @@ dependencies = [ "alloy-json-abi", "const-hex", "dunce", - "heck 0.5.0", + "heck", "macro-string", "proc-macro2", "quote", @@ -840,6 +840,7 @@ dependencies = [ "digest 0.10.7", "fnv", "merlin", + "rayon", "sha2", ] @@ -872,6 +873,7 @@ dependencies = [ "num-bigint 0.4.6", "num-integer", "num-traits", + "rayon", "zeroize", ] @@ -930,6 +932,7 @@ dependencies = [ "num-bigint 0.4.6", "num-traits", "paste", + "rayon", "zeroize", ] @@ -1014,6 +1017,7 @@ dependencies = [ "ark-relations", "ark-serialize 0.5.0", "ark-std 0.5.0", + "rayon", ] [[package]] @@ -1029,6 +1033,7 @@ dependencies = [ "educe", "fnv", "hashbrown 0.15.4", + "rayon", ] [[package]] @@ -1092,6 +1097,7 @@ dependencies = [ "arrayvec", "digest 0.10.7", "num-bigint 0.4.6", + "rayon", ] [[package]] @@ -1145,6 +1151,7 @@ checksum = "246a225cc6131e9ee4f24619af0f19d67761fff15d7ccc22e42b80846e69449a" dependencies = [ "num-traits", "rand 0.8.5", + "rayon", ] [[package]] @@ -1153,6 +1160,12 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7d902e3d592a523def97af8f317b08ce16b7ab854c1985a0c671e6f15cebc236" +[[package]] +name = "arrayref" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" + [[package]] name = "arrayvec" version = "0.7.6" @@ -2042,6 +2055,19 @@ dependencies = [ "digest 0.10.7", ] +[[package]] +name = "blake3" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3888aaa89e4b2a40fca9848e400f6a658a5a3978de7be858e209cafa8be9a4a0" +dependencies = [ + "arrayref", + "arrayvec", + "cc", + "cfg-if", + "constant_time_eq", +] + [[package]] name = "block" version = "0.1.6" @@ -2084,15 +2110,14 @@ dependencies = [ [[package]] name = "bonsai-sdk" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bce8d6acc5286a16e94c29e9c885d1869358885e08a6feeb6bc54e36fe20055" +version = "1.4.1" +source = "git+https://github.com/risc0/risc0?branch=flaub%2Fshrink-bitvm2#6ed3f0321638ae7eb9c097b8aa8becba3f4b1350" dependencies = [ "duplicate", "maybe-async", "reqwest", "serde", - "thiserror 1.0.69", + "thiserror 2.0.12", "tokio", ] @@ -2187,6 +2212,7 @@ dependencies = [ "guest-assessor", "guest-set-builder", "guest-util", + "hex", "risc0-aggregation", "risc0-circuit-recursion", "risc0-ethereum-contracts", @@ -2217,6 +2243,8 @@ dependencies = [ "http-cache-reqwest", "moka", "notify", + "num-bigint 0.4.6", + "num-traits", "rand 0.9.1", "reqwest", "reqwest-middleware", @@ -2227,6 +2255,7 @@ dependencies = [ "serde", "serde_json", "sha2", + "shrink_bitvm2", "sqlx", "tempfile", "thiserror 2.0.12", @@ -2456,7 +2485,7 @@ version = "4.5.41" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef4f52386a59ca4c860f7393bcf8abd8dfd91ecccc0f774635ff68e92eeef491" dependencies = [ - "heck 0.5.0", + "heck", "proc-macro2", "quote", "syn 2.0.104", @@ -2540,6 +2569,12 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "constant_time_eq" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" + [[package]] name = "core-foundation" version = "0.9.4" @@ -3061,12 +3096,13 @@ checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" [[package]] name = "duplicate" -version = "1.0.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de78e66ac9061e030587b2a2e75cc88f22304913c907b11307bca737141230cb" +checksum = "97af9b5f014e228b33e77d75ee0e6e87960124f0f4b16337b586a6bec91867b1" dependencies = [ - "heck 0.4.1", - "proc-macro-error", + "heck", + "proc-macro2", + "proc-macro2-diagnostics", ] [[package]] @@ -3336,6 +3372,7 @@ dependencies = [ "clap", "guest-util", "risc0-zkvm", + "shrink_bitvm2", "test-log", "tokio", "tracing", @@ -3928,12 +3965,6 @@ dependencies = [ "stable_deref_trait", ] -[[package]] -name = "heck" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" - [[package]] name = "heck" version = "0.5.0" @@ -5806,30 +5837,6 @@ dependencies = [ "toml_edit", ] -[[package]] -name = "proc-macro-error" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" -dependencies = [ - "proc-macro-error-attr", - "proc-macro2", - "quote", - "syn 1.0.109", - "version_check", -] - -[[package]] -name = "proc-macro-error-attr" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" -dependencies = [ - "proc-macro2", - "quote", - "version_check", -] - [[package]] name = "proc-macro-error-attr2" version = "2.0.0" @@ -5861,6 +5868,19 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "proc-macro2-diagnostics" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", + "version_check", + "yansi", +] + [[package]] name = "proptest" version = "1.7.0" @@ -6587,8 +6607,6 @@ dependencies = [ [[package]] name = "risc0-ethereum-contracts" version = "2.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d3a6978f67c13fcf3e9123d28882368a3a3d686f881a35bb0caaebc585f93d6" dependencies = [ "alloy", "alloy-primitives", @@ -7397,6 +7415,29 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +[[package]] +name = "shrink_bitvm2" +version = "0.14.0" +dependencies = [ + "anyhow", + "ark-bn254", + "ark-ff 0.5.0", + "ark-groth16", + "ark-serialize 0.5.0", + "blake3", + "hex", + "num-bigint 0.4.6", + "num-traits", + "risc0-groth16", + "risc0-zkvm", + "serde", + "serde_json", + "sha2", + "tempfile", + "tokio", + "tracing", +] + [[package]] name = "signal-hook-registry" version = "1.4.5" @@ -7593,7 +7634,7 @@ checksum = "19a9c1841124ac5a61741f96e1d9e2ec77424bf323962dd894bdb93f37d5219b" dependencies = [ "dotenvy", "either", - "heck 0.5.0", + "heck", "hex", "once_cell", "proc-macro2", @@ -7805,7 +7846,7 @@ version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" dependencies = [ - "heck 0.5.0", + "heck", "proc-macro2", "quote", "rustversion", @@ -7818,7 +7859,7 @@ version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c77a8c5abcaf0f9ce05d62342b7d298c346515365c36b673df4ebe3ced01fde8" dependencies = [ - "heck 0.5.0", + "heck", "proc-macro2", "quote", "rustversion", @@ -9267,6 +9308,12 @@ dependencies = [ "hashlink 0.9.1", ] +[[package]] +name = "yansi" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" + [[package]] name = "yoke" version = "0.8.0" diff --git a/examples/counter/Cargo.toml b/examples/counter/Cargo.toml index 8fd4070ca..e3d507b78 100644 --- a/examples/counter/Cargo.toml +++ b/examples/counter/Cargo.toml @@ -13,7 +13,6 @@ guest-util = { path = "../../crates/guest/util" } boundless-market = { path = "../../crates/boundless-market" } boundless-market-test-utils = { path = "../../crates/boundless-market/test-utils" } broker = { path = "../../crates/broker" } - # risc0 monorepo dependencies. risc0-zkvm = { version = "2.3", default-features = false } @@ -29,3 +28,6 @@ url = "2.5" # Always optimize; otherwise, local proving takes much longer to run [profile.dev] opt-level = 3 + +[patch.crates-io] +risc0-ethereum-contracts = { path = "/home/etu/risc0-ethereum/contracts" } \ No newline at end of file diff --git a/examples/counter/apps/Cargo.toml b/examples/counter/apps/Cargo.toml index 68bd55e55..6a74ecf44 100644 --- a/examples/counter/apps/Cargo.toml +++ b/examples/counter/apps/Cargo.toml @@ -11,6 +11,7 @@ boundless-market = { workspace = true } clap = { workspace = true } guest-util = { workspace = true } risc0-zkvm = { workspace = true } +shrink_bitvm2 = { path = "/home/etu/boundless/crates/shrink_bitvm2" } tokio = { workspace = true, features = ["full"] } tracing = { workspace = true } tracing-subscriber = { workspace = true, features = ["env-filter"] } diff --git a/examples/counter/apps/src/main.rs b/examples/counter/apps/src/main.rs index 95f3c8bd1..95828729b 100644 --- a/examples/counter/apps/src/main.rs +++ b/examples/counter/apps/src/main.rs @@ -22,12 +22,12 @@ use alloy::{primitives::Address, signers::local::PrivateKeySigner, sol_types::So use anyhow::{Context, Result}; use boundless_market::{ contracts::{Predicate, PredicateType}, - request_builder::RequirementParams, + request_builder::{OfferParams, RequirementParams}, Client, Deployment, StorageProviderConfig, }; use clap::Parser; use guest_util::{ECHO_ELF, ECHO_ID}; -use risc0_zkvm::{sha::Digestible, ReceiptClaim}; +use risc0_zkvm::{sha::Digestible, Digest, ReceiptClaim}; use tracing_subscriber::{filter::LevelFilter, prelude::*, EnvFilter}; use url::Url; @@ -94,31 +94,64 @@ async fn run(args: Args) -> Result<()> { .await .context("failed to build boundless client")?; - // Use the default ECHO program with timestamp input - // We use a timestamp as input to the ECHO guest code as the Counter contract + let counter = ICounterInstance::new(args.counter_address, client.provider().clone()); + + // Use the current count as input to the ECHO guest code as the Counter contract // accepts only unique proofs. Using the same input twice would result in the same proof. - let echo_message = format!("{:?}", SystemTime::now()); - let r0_claim_digest = ReceiptClaim::ok(ECHO_ID, echo_message.as_bytes().to_vec()).digest(); + let start_count = counter + .getCount(client.caller()) + .call() + .await + .with_context(|| format!("failed to call {}", ICounter::getCountCall::SIGNATURE))?; + + // Shrink Bitvm2 proofs require the input to be 32 bytes + let echo_message = start_count.as_le_bytes(); + + // let r0_claim_digest = ReceiptClaim::ok(ECHO_ID, echo_message.as_bytes().to_vec()).digest(); + let blake3_claim_digest = + shrink_bitvm2::blake3_claim_digest(&Digest::from(ECHO_ID), echo_message.as_ref()); // Build the request based on whether program URL is provided let request = if let Some(program_url) = args.program_url { // Use the provided URL - client.new_request().with_program_url(program_url)?.with_stdin(echo_message.as_bytes()) + client + .new_request() + .with_program_url(program_url)? + .with_stdin(echo_message) + .with_requirements( + RequirementParams::builder() + .predicate(Predicate::claim_digest_match(blake3_claim_digest)) + .build() + .unwrap(), + ) + .with_offer( + OfferParams::builder() + .min_price(alloy::primitives::utils::parse_ether("0.001")?) + .max_price(alloy::primitives::utils::parse_ether("0.002")?) + .timeout(1000) + .lock_timeout(1000), + ) + .with_shrink_bitvm2_proof() } else { client .new_request() .with_program(ECHO_ELF) - .with_stdin(echo_message.as_bytes()) + .with_stdin(echo_message) .with_requirements( RequirementParams::builder() - .predicate(Predicate { - predicateType: PredicateType::ClaimDigestMatch, - data: r0_claim_digest.as_bytes().to_vec().into(), - }) + .predicate(Predicate::claim_digest_match(blake3_claim_digest)) .build() .unwrap(), ) + .with_offer( + OfferParams::builder() + .min_price(alloy::primitives::utils::parse_ether("0.001")?) + .max_price(alloy::primitives::utils::parse_ether("0.002")?) + .timeout(1000) + .lock_timeout(1000), + ) + .with_shrink_bitvm2_proof() }; let (request_id, expires_at) = client.submit_onchain(request).await?; @@ -137,9 +170,7 @@ async fn run(args: Args) -> Result<()> { // We interact with the Counter contract by calling the increment function with the journal and // seal returned by the market. - let counter = ICounterInstance::new(args.counter_address, client.provider().clone()); - let call_increment = - counter.increment(seal, <[u8; 32]>::from(r0_claim_digest).into()).from(client.caller()); + let call_increment = counter.increment(seal, blake3_claim_digest.into()).from(client.caller()); // By calling the increment function, we verify the seal against the published roots // of the SetVerifier contract. diff --git a/examples/smart-contract-requestor/Cargo.lock b/examples/smart-contract-requestor/Cargo.lock index 99a08b3e2..1022d0fe6 100644 --- a/examples/smart-contract-requestor/Cargo.lock +++ b/examples/smart-contract-requestor/Cargo.lock @@ -840,6 +840,7 @@ dependencies = [ "digest 0.10.7", "fnv", "merlin", + "rayon", "sha2", ] @@ -872,6 +873,7 @@ dependencies = [ "num-bigint 0.4.6", "num-integer", "num-traits", + "rayon", "zeroize", ] @@ -930,6 +932,7 @@ dependencies = [ "num-bigint 0.4.6", "num-traits", "paste", + "rayon", "zeroize", ] @@ -1014,6 +1017,7 @@ dependencies = [ "ark-relations", "ark-serialize 0.5.0", "ark-std 0.5.0", + "rayon", ] [[package]] @@ -1029,6 +1033,7 @@ dependencies = [ "educe", "fnv", "hashbrown 0.15.4", + "rayon", ] [[package]] @@ -1092,6 +1097,7 @@ dependencies = [ "arrayvec", "digest 0.10.7", "num-bigint 0.4.6", + "rayon", ] [[package]] @@ -1145,6 +1151,7 @@ checksum = "246a225cc6131e9ee4f24619af0f19d67761fff15d7ccc22e42b80846e69449a" dependencies = [ "num-traits", "rand 0.8.5", + "rayon", ] [[package]] @@ -1153,6 +1160,12 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7d902e3d592a523def97af8f317b08ce16b7ab854c1985a0c671e6f15cebc236" +[[package]] +name = "arrayref" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" + [[package]] name = "arrayvec" version = "0.7.6" @@ -2042,6 +2055,19 @@ dependencies = [ "digest 0.10.7", ] +[[package]] +name = "blake3" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3888aaa89e4b2a40fca9848e400f6a658a5a3978de7be858e209cafa8be9a4a0" +dependencies = [ + "arrayref", + "arrayvec", + "cc", + "cfg-if", + "constant_time_eq", +] + [[package]] name = "block" version = "0.1.6" @@ -2088,11 +2114,23 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0bce8d6acc5286a16e94c29e9c885d1869358885e08a6feeb6bc54e36fe20055" dependencies = [ - "duplicate", + "duplicate 1.0.0", "maybe-async", "reqwest", "serde", "thiserror 1.0.69", +] + +[[package]] +name = "bonsai-sdk" +version = "1.4.1" +source = "git+https://github.com/risc0/risc0?branch=flaub%2Fshrink-bitvm2#6ed3f0321638ae7eb9c097b8aa8becba3f4b1350" +dependencies = [ + "duplicate 2.0.0", + "maybe-async", + "reqwest", + "serde", + "thiserror 2.0.12", "tokio", ] @@ -2187,6 +2225,7 @@ dependencies = [ "guest-assessor", "guest-set-builder", "guest-util", + "hex", "risc0-aggregation", "risc0-circuit-recursion", "risc0-ethereum-contracts", @@ -2205,7 +2244,7 @@ dependencies = [ "aws-config", "aws-sdk-s3", "bincode", - "bonsai-sdk", + "bonsai-sdk 1.4.1", "boundless-assessor", "boundless-market", "boundless-market-test-utils", @@ -2217,6 +2256,8 @@ dependencies = [ "http-cache-reqwest", "moka", "notify", + "num-bigint 0.4.6", + "num-traits", "rand 0.9.1", "reqwest", "reqwest-middleware", @@ -2227,6 +2268,7 @@ dependencies = [ "serde", "serde_json", "sha2", + "shrink_bitvm2", "sqlx", "tempfile", "thiserror 2.0.12", @@ -2540,6 +2582,12 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "constant_time_eq" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" + [[package]] name = "core-foundation" version = "0.9.4" @@ -3069,6 +3117,17 @@ dependencies = [ "proc-macro-error", ] +[[package]] +name = "duplicate" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97af9b5f014e228b33e77d75ee0e6e87960124f0f4b16337b586a6bec91867b1" +dependencies = [ + "heck 0.5.0", + "proc-macro2", + "proc-macro2-diagnostics", +] + [[package]] name = "dyn-clone" version = "1.0.19" @@ -5861,6 +5920,19 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "proc-macro2-diagnostics" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", + "version_check", + "yansi", +] + [[package]] name = "proptest" version = "1.7.0" @@ -6691,7 +6763,7 @@ dependencies = [ "addr2line 0.22.0", "anyhow", "bincode", - "bonsai-sdk", + "bonsai-sdk 1.4.0", "borsh", "bytemuck", "bytes", @@ -7398,6 +7470,29 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +[[package]] +name = "shrink_bitvm2" +version = "0.14.0" +dependencies = [ + "anyhow", + "ark-bn254", + "ark-ff 0.5.0", + "ark-groth16", + "ark-serialize 0.5.0", + "blake3", + "hex", + "num-bigint 0.4.6", + "num-traits", + "risc0-groth16", + "risc0-zkvm", + "serde", + "serde_json", + "sha2", + "tempfile", + "tokio", + "tracing", +] + [[package]] name = "signal-hook-registry" version = "1.4.5" @@ -9268,6 +9363,12 @@ dependencies = [ "hashlink 0.9.1", ] +[[package]] +name = "yansi" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" + [[package]] name = "yoke" version = "0.8.0" diff --git a/remappings.txt b/remappings.txt index 58db52928..33d5c4152 100644 --- a/remappings.txt +++ b/remappings.txt @@ -3,5 +3,5 @@ openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/ openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/ forge-std/=lib/forge-std/src/ -risc0/=lib/risc0-ethereum/contracts/src/ +risc0/=/home/etu/risc0-ethereum/contracts/src/ solmate/=lib/solmate/src \ No newline at end of file