From 1c1f84dd389b42b9743bff840e039d347c54c958 Mon Sep 17 00:00:00 2001 From: Jonathan LEI Date: Tue, 8 Oct 2024 07:55:26 +0800 Subject: [PATCH 01/21] feat: only call entrypoint in zkvm (#1611) --- crates/zkvm/entrypoint/src/lib.rs | 8 ++++++++ examples/json/program/src/main.rs | 2 +- examples/patch-testing/program/src/main.rs | 2 +- examples/patch-testing/script/src/main.rs | 2 +- examples/ssz-withdrawals/program/src/main.rs | 2 +- examples/tendermint/program/src/main.rs | 2 +- examples/tendermint/script/src/main.rs | 2 +- tests/tendermint-benchmark/src/main.rs | 2 +- tests/uint256-mul/src/main.rs | 2 +- 9 files changed, 16 insertions(+), 8 deletions(-) diff --git a/crates/zkvm/entrypoint/src/lib.rs b/crates/zkvm/entrypoint/src/lib.rs index fe7ba875d7..46dbed730d 100644 --- a/crates/zkvm/entrypoint/src/lib.rs +++ b/crates/zkvm/entrypoint/src/lib.rs @@ -102,6 +102,14 @@ macro_rules! entrypoint { #[no_mangle] fn main() { + // Link to the actual entrypoint only when compiling for zkVM. Doing this avoids + // compilation errors when building for the host target. + // + // Note that, however, it's generally considered wasted effort compiling zkVM + // programs against the host target. This just makes it such that doing so wouldn't + // result in an error, which can happen when building a Cargo workspace containing + // zkVM program crates. + #[cfg(target_os = "zkvm")] super::ZKVM_ENTRY() } } diff --git a/examples/json/program/src/main.rs b/examples/json/program/src/main.rs index 5c35470cf6..dea5ed9b37 100644 --- a/examples/json/program/src/main.rs +++ b/examples/json/program/src/main.rs @@ -4,7 +4,7 @@ sp1_zkvm::entrypoint!(main); use lib::{Account, Transaction}; // Custom structs. use serde_json::Value; // Generic JSON. -fn main() { +pub fn main() { // read generic JSON example inputs. let data_str = sp1_zkvm::io::read::(); let key = sp1_zkvm::io::read::(); diff --git a/examples/patch-testing/program/src/main.rs b/examples/patch-testing/program/src/main.rs index 3458c1099e..efd60f15db 100644 --- a/examples/patch-testing/program/src/main.rs +++ b/examples/patch-testing/program/src/main.rs @@ -166,7 +166,7 @@ fn test_secp256k1_patch() { } /// To add testing for a new patch, add a new case to the function below. -fn main() { +pub fn main() { // TODO: Specify which syscalls are linked to each function invocation, iterate // over this list that is shared between the program and script. test_keccak(); diff --git a/examples/patch-testing/script/src/main.rs b/examples/patch-testing/script/src/main.rs index 45f97198ff..57eb099335 100644 --- a/examples/patch-testing/script/src/main.rs +++ b/examples/patch-testing/script/src/main.rs @@ -3,7 +3,7 @@ use sp1_sdk::{utils, ProverClient, SP1Stdin}; const PATCH_TEST_ELF: &[u8] = include_bytes!("../../program/elf/riscv32im-succinct-zkvm-elf"); /// This script is used to test that SP1 patches are correctly applied and syscalls are triggered. -fn main() { +pub fn main() { utils::setup_logger(); let stdin = SP1Stdin::new(); diff --git a/examples/ssz-withdrawals/program/src/main.rs b/examples/ssz-withdrawals/program/src/main.rs index cdce58b998..1c7937e20e 100644 --- a/examples/ssz-withdrawals/program/src/main.rs +++ b/examples/ssz-withdrawals/program/src/main.rs @@ -14,7 +14,7 @@ use hex_literal::hex; use ssz_rs::prelude::*; use std::collections::HashMap; -fn main() { +pub fn main() { // Get inputs. let beacon_block_root = node_from_bytes(hex!("d00c4da1a3ad4d42bd35f128544227d19e163194569d69d54a3d14112e3c897c")); diff --git a/examples/tendermint/program/src/main.rs b/examples/tendermint/program/src/main.rs index e6d42390a3..53db8535e6 100644 --- a/examples/tendermint/program/src/main.rs +++ b/examples/tendermint/program/src/main.rs @@ -6,7 +6,7 @@ use tendermint_light_client_verifier::{ options::Options, types::LightBlock, ProdVerifier, Verdict, Verifier, }; -fn main() { +pub fn main() { // Normally we could just do this to read in the LightBlocks, but bincode doesn't work with LightBlock. // This is likely a bug in tendermint-rs. // let light_block_1 = sp1_zkvm::io::read::(); diff --git a/examples/tendermint/script/src/main.rs b/examples/tendermint/script/src/main.rs index 7b4d9a60f1..5bdc06936c 100644 --- a/examples/tendermint/script/src/main.rs +++ b/examples/tendermint/script/src/main.rs @@ -19,7 +19,7 @@ fn get_light_blocks() -> (LightBlock, LightBlock) { (light_block_1, light_block_2) } -fn main() { +pub fn main() { // Generate proof. utils::setup_logger(); diff --git a/tests/tendermint-benchmark/src/main.rs b/tests/tendermint-benchmark/src/main.rs index 3cd2111d1a..455c837b09 100644 --- a/tests/tendermint-benchmark/src/main.rs +++ b/tests/tendermint-benchmark/src/main.rs @@ -33,7 +33,7 @@ pub struct BlockValidatorSet { pub total: String, } -fn main() { +pub fn main() { let peer_id: [u8; 20] = [ 0x72, 0x6b, 0xc8, 0xd2, 0x60, 0x38, 0x7c, 0xf5, 0x6e, 0xcf, 0xad, 0x3a, 0x6b, 0xf6, 0xfe, 0xcd, 0x90, 0x3e, 0x18, 0xa2, diff --git a/tests/uint256-mul/src/main.rs b/tests/uint256-mul/src/main.rs index 89e5efba10..fa58a127a5 100644 --- a/tests/uint256-mul/src/main.rs +++ b/tests/uint256-mul/src/main.rs @@ -26,7 +26,7 @@ fn biguint_to_bytes_le(x: BigUint) -> [u8; 32] { } #[sp1_derive::cycle_tracker] -fn main() { +pub fn main() { for _ in 0..50 { // Test with random numbers. let mut rng = rand::thread_rng(); From d706145821f6400eba5bf135f50fcda94b3de528 Mon Sep 17 00:00:00 2001 From: Matt Stam <15695189+mattstam@users.noreply.github.com> Date: Tue, 8 Oct 2024 10:42:00 -0700 Subject: [PATCH 02/21] feat(sdk): network-v2 (#1607) Co-authored-by: John Guibas --- Cargo.lock | 1167 ++++++++++++++++- crates/sdk/Cargo.toml | 24 +- crates/sdk/src/artifacts.rs | 4 +- crates/sdk/src/install.rs | 8 +- crates/sdk/src/lib.rs | 32 +- crates/sdk/src/network-v2/client.rs | 228 ++++ crates/sdk/src/network-v2/mod.rs | 19 + crates/sdk/src/network-v2/proto/artifact.rs | 278 ++++ crates/sdk/src/network-v2/proto/mod.rs | 2 + crates/sdk/src/network-v2/proto/network.rs | 907 +++++++++++++ crates/sdk/src/network-v2/prover.rs | 216 +++ crates/sdk/src/network-v2/sign_message.rs | 73 ++ crates/sdk/src/network/auth.rs | 2 +- crates/sdk/src/network/client.rs | 4 +- crates/sdk/src/network/mod.rs | 3 + crates/sdk/src/network/proto/mod.rs | 1 + crates/sdk/src/{ => network}/proto/network.rs | 0 crates/sdk/src/network/prover.rs | 3 +- 18 files changed, 2903 insertions(+), 68 deletions(-) create mode 100644 crates/sdk/src/network-v2/client.rs create mode 100644 crates/sdk/src/network-v2/mod.rs create mode 100644 crates/sdk/src/network-v2/proto/artifact.rs create mode 100644 crates/sdk/src/network-v2/proto/mod.rs create mode 100644 crates/sdk/src/network-v2/proto/network.rs create mode 100644 crates/sdk/src/network-v2/prover.rs create mode 100644 crates/sdk/src/network-v2/sign_message.rs create mode 100644 crates/sdk/src/network/proto/mod.rs rename crates/sdk/src/{ => network}/proto/network.rs (100%) diff --git a/Cargo.lock b/Cargo.lock index a86cc9e493..154243cb57 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -130,6 +130,107 @@ version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" +[[package]] +name = "alloy-consensus" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "629b62e38d471cc15fea534eb7283d2f8a4e8bdb1811bcc5d66dda6cfce6fae1" +dependencies = [ + "alloy-eips", + "alloy-primitives 0.8.5", + "alloy-rlp", + "alloy-serde", + "c-kzg", + "serde", +] + +[[package]] +name = "alloy-eip2930" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0069cf0642457f87a01a014f6dc29d5d893cd4fd8fddf0c3cdfad1bb3ebafc41" +dependencies = [ + "alloy-primitives 0.8.5", + "alloy-rlp", + "serde", +] + +[[package]] +name = "alloy-eip7702" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea59dc42102bc9a1905dc57901edc6dd48b9f38115df86c7d252acba70d71d04" +dependencies = [ + "alloy-primitives 0.8.5", + "alloy-rlp", + "serde", +] + +[[package]] +name = "alloy-eips" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f923dd5fca5f67a43d81ed3ebad0880bd41f6dd0ada930030353ac356c54cd0f" +dependencies = [ + "alloy-eip2930", + "alloy-eip7702", + "alloy-primitives 0.8.5", + "alloy-rlp", + "alloy-serde", + "c-kzg", + "derive_more 1.0.0", + "once_cell", + "serde", + "sha2 0.10.8", +] + +[[package]] +name = "alloy-json-rpc" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3c717b5298fad078cd3a418335b266eba91b511383ca9bd497f742d5975d5ab" +dependencies = [ + "alloy-primitives 0.8.5", + "alloy-sol-types 0.8.5", + "serde", + "serde_json", + "thiserror", + "tracing", +] + +[[package]] +name = "alloy-network" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb3705ce7d8602132bcf5ac7a1dd293a42adc2f183abf5907c30ac535ceca049" +dependencies = [ + "alloy-consensus", + "alloy-eips", + "alloy-json-rpc", + "alloy-network-primitives", + "alloy-primitives 0.8.5", + "alloy-rpc-types-eth", + "alloy-serde", + "alloy-signer", + "alloy-sol-types 0.8.5", + "async-trait", + "auto_impl", + "futures-utils-wasm", + "thiserror", +] + +[[package]] +name = "alloy-network-primitives" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94ad40869867ed2d9cd3842b1e800889e5b49e6b92da346e93862b4a741bedf3" +dependencies = [ + "alloy-eips", + "alloy-primitives 0.8.5", + "alloy-serde", + "serde", +] + [[package]] name = "alloy-primitives" version = "0.7.7" @@ -140,7 +241,7 @@ dependencies = [ "bytes 1.7.1", "cfg-if", "const-hex", - "derive_more", + "derive_more 0.99.18", "hex-literal", "itoa", "k256", @@ -152,45 +253,178 @@ dependencies = [ "tiny-keccak", ] +[[package]] +name = "alloy-primitives" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "260d3ff3bff0bb84599f032a2f2c6828180b0ea0cd41fdaf44f39cef3ba41861" +dependencies = [ + "alloy-rlp", + "bytes 1.7.1", + "cfg-if", + "const-hex", + "derive_more 1.0.0", + "hashbrown 0.14.5", + "hex-literal", + "indexmap 2.6.0", + "itoa", + "k256", + "keccak-asm", + "paste", + "proptest", + "rand 0.8.5", + "ruint", + "rustc-hash 2.0.0", + "serde", + "sha3", + "tiny-keccak", +] + [[package]] name = "alloy-rlp" version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26154390b1d205a4a7ac7352aa2eb4f81f391399d4e2f546fb81a2f8bb383f62" dependencies = [ + "alloy-rlp-derive", "arrayvec", "bytes 1.7.1", ] +[[package]] +name = "alloy-rlp-derive" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d0f2d905ebd295e7effec65e5f6868d153936130ae718352771de3e7d03c75c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.72", +] + +[[package]] +name = "alloy-rpc-types-eth" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83aa984386deda02482660aa31cb8ca1e63d533f1c31a52d7d181ac5ec68e9b8" +dependencies = [ + "alloy-consensus", + "alloy-eips", + "alloy-network-primitives", + "alloy-primitives 0.8.5", + "alloy-rlp", + "alloy-serde", + "alloy-sol-types 0.8.5", + "cfg-if", + "derive_more 1.0.0", + "hashbrown 0.14.5", + "itertools 0.13.0", + "serde", + "serde_json", +] + +[[package]] +name = "alloy-serde" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "731f75ec5d383107fd745d781619bd9cedf145836c51ecb991623d41278e71fa" +dependencies = [ + "alloy-primitives 0.8.5", + "serde", + "serde_json", +] + +[[package]] +name = "alloy-signer" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "307324cca94354cd654d6713629f0383ec037e1ff9e3e3d547212471209860c0" +dependencies = [ + "alloy-primitives 0.8.5", + "async-trait", + "auto_impl", + "elliptic-curve 0.13.8", + "k256", + "thiserror", +] + +[[package]] +name = "alloy-signer-local" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fabe917ab1778e760b4701628d1cae8e028ee9d52ac6307de4e1e9286ab6b5f" +dependencies = [ + "alloy-consensus", + "alloy-network", + "alloy-primitives 0.8.5", + "alloy-signer", + "async-trait", + "k256", + "rand 0.8.5", + "thiserror", +] + [[package]] name = "alloy-sol-macro" version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b40397ddcdcc266f59f959770f601ce1280e699a91fc1862f29cef91707cd09" dependencies = [ - "alloy-sol-macro-expander", - "alloy-sol-macro-input", + "alloy-sol-macro-expander 0.7.7", + "alloy-sol-macro-input 0.7.7", "proc-macro-error", "proc-macro2", "quote", "syn 2.0.72", ] +[[package]] +name = "alloy-sol-macro" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68e7f6e8fe5b443f82b3f1e15abfa191128f71569148428e49449d01f6f49e8b" +dependencies = [ + "alloy-sol-macro-expander 0.8.5", + "alloy-sol-macro-input 0.8.5", + "proc-macro-error2", + "proc-macro2", + "quote", + "syn 2.0.72", +] + [[package]] name = "alloy-sol-macro-expander" version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "867a5469d61480fea08c7333ffeca52d5b621f5ca2e44f271b117ec1fc9a0525" dependencies = [ - "alloy-sol-macro-input", + "alloy-sol-macro-input 0.7.7", "const-hex", "heck", - "indexmap 2.3.0", + "indexmap 2.6.0", "proc-macro-error", "proc-macro2", "quote", "syn 2.0.72", - "syn-solidity", + "syn-solidity 0.7.7", + "tiny-keccak", +] + +[[package]] +name = "alloy-sol-macro-expander" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b96ce28d2fde09abb6135f410c41fad670a3a770b6776869bd852f1df102e6f" +dependencies = [ + "alloy-sol-macro-input 0.8.5", + "const-hex", + "heck", + "indexmap 2.6.0", + "proc-macro-error2", + "proc-macro2", + "quote", + "syn 2.0.72", + "syn-solidity 0.8.5", "tiny-keccak", ] @@ -206,7 +440,22 @@ dependencies = [ "proc-macro2", "quote", "syn 2.0.72", - "syn-solidity", + "syn-solidity 0.7.7", +] + +[[package]] +name = "alloy-sol-macro-input" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "906746396a8296537745711630d9185746c0b50c033d5e9d18b0a6eba3d53f90" +dependencies = [ + "const-hex", + "dunce", + "heck", + "proc-macro2", + "quote", + "syn 2.0.72", + "syn-solidity 0.8.5", ] [[package]] @@ -215,12 +464,23 @@ version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a91ca40fa20793ae9c3841b83e74569d1cc9af29a2f5237314fd3452d51e38c7" dependencies = [ - "alloy-primitives", - "alloy-sol-macro", + "alloy-primitives 0.7.7", + "alloy-sol-macro 0.7.7", "const-hex", "serde", ] +[[package]] +name = "alloy-sol-types" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d86a533ce22525969661b25dfe296c112d35eb6861f188fd284f8bd4bb3842ae" +dependencies = [ + "alloy-primitives 0.8.5", + "alloy-sol-macro 0.8.5", + "const-hex", +] + [[package]] name = "android-tzdata" version = "0.1.1" @@ -592,6 +852,28 @@ dependencies = [ "wasm-bindgen-futures", ] +[[package]] +name = "async-stream" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b5a71a6f37880a80d1d7f19efd781e4b5de42c88f0722cc13bcb6cc2cfe8476" +dependencies = [ + "async-stream-impl", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-stream-impl" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.72", +] + [[package]] name = "async-task" version = "4.7.1" @@ -669,6 +951,381 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +[[package]] +name = "aws-config" +version = "1.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8191fb3091fa0561d1379ef80333c3c7191c6f0435d986e85821bcf7acbd1126" +dependencies = [ + "aws-credential-types", + "aws-runtime", + "aws-sdk-sso", + "aws-sdk-ssooidc", + "aws-sdk-sts", + "aws-smithy-async", + "aws-smithy-http", + "aws-smithy-json", + "aws-smithy-runtime", + "aws-smithy-runtime-api", + "aws-smithy-types", + "aws-types", + "bytes 1.7.1", + "fastrand 2.1.0", + "hex", + "http 0.2.12", + "ring 0.17.8", + "time 0.3.36", + "tokio", + "tracing", + "url", + "zeroize", +] + +[[package]] +name = "aws-credential-types" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60e8f6b615cb5fc60a98132268508ad104310f0cfb25a1c22eee76efdf9154da" +dependencies = [ + "aws-smithy-async", + "aws-smithy-runtime-api", + "aws-smithy-types", + "zeroize", +] + +[[package]] +name = "aws-runtime" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a10d5c055aa540164d9561a0e2e74ad30f0dcf7393c3a92f6733ddf9c5762468" +dependencies = [ + "aws-credential-types", + "aws-sigv4", + "aws-smithy-async", + "aws-smithy-eventstream", + "aws-smithy-http", + "aws-smithy-runtime", + "aws-smithy-runtime-api", + "aws-smithy-types", + "aws-types", + "bytes 1.7.1", + "fastrand 2.1.0", + "http 0.2.12", + "http-body 0.4.6", + "once_cell", + "percent-encoding", + "pin-project-lite", + "tracing", + "uuid 1.10.0", +] + +[[package]] +name = "aws-sdk-s3" +version = "1.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43fad71130014e11f42fadbdcce5df12ee61866f8ab9bad773b138d4b3c11087" +dependencies = [ + "ahash", + "aws-credential-types", + "aws-runtime", + "aws-sigv4", + "aws-smithy-async", + "aws-smithy-checksums", + "aws-smithy-eventstream", + "aws-smithy-http", + "aws-smithy-json", + "aws-smithy-runtime", + "aws-smithy-runtime-api", + "aws-smithy-types", + "aws-smithy-xml", + "aws-types", + "bytes 1.7.1", + "fastrand 2.1.0", + "hex", + "hmac 0.12.1", + "http 0.2.12", + "http-body 0.4.6", + "lru", + "once_cell", + "percent-encoding", + "regex-lite", + "sha2 0.10.8", + "tracing", + "url", +] + +[[package]] +name = "aws-sdk-sso" +version = "1.44.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b90cfe6504115e13c41d3ea90286ede5aa14da294f3fe077027a6e83850843c" +dependencies = [ + "aws-credential-types", + "aws-runtime", + "aws-smithy-async", + "aws-smithy-http", + "aws-smithy-json", + "aws-smithy-runtime", + "aws-smithy-runtime-api", + "aws-smithy-types", + "aws-types", + "bytes 1.7.1", + "http 0.2.12", + "once_cell", + "regex-lite", + "tracing", +] + +[[package]] +name = "aws-sdk-ssooidc" +version = "1.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "167c0fad1f212952084137308359e8e4c4724d1c643038ce163f06de9662c1d0" +dependencies = [ + "aws-credential-types", + "aws-runtime", + "aws-smithy-async", + "aws-smithy-http", + "aws-smithy-json", + "aws-smithy-runtime", + "aws-smithy-runtime-api", + "aws-smithy-types", + "aws-types", + "bytes 1.7.1", + "http 0.2.12", + "once_cell", + "regex-lite", + "tracing", +] + +[[package]] +name = "aws-sdk-sts" +version = "1.44.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2cb5f98188ec1435b68097daa2a37d74b9d17c9caa799466338a8d1544e71b9d" +dependencies = [ + "aws-credential-types", + "aws-runtime", + "aws-smithy-async", + "aws-smithy-http", + "aws-smithy-json", + "aws-smithy-query", + "aws-smithy-runtime", + "aws-smithy-runtime-api", + "aws-smithy-types", + "aws-smithy-xml", + "aws-types", + "http 0.2.12", + "once_cell", + "regex-lite", + "tracing", +] + +[[package]] +name = "aws-sigv4" +version = "1.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc8db6904450bafe7473c6ca9123f88cc11089e41a025408f992db4e22d3be68" +dependencies = [ + "aws-credential-types", + "aws-smithy-eventstream", + "aws-smithy-http", + "aws-smithy-runtime-api", + "aws-smithy-types", + "bytes 1.7.1", + "crypto-bigint 0.5.5", + "form_urlencoded", + "hex", + "hmac 0.12.1", + "http 0.2.12", + "http 1.1.0", + "once_cell", + "p256", + "percent-encoding", + "ring 0.17.8", + "sha2 0.10.8", + "subtle", + "time 0.3.36", + "tracing", + "zeroize", +] + +[[package]] +name = "aws-smithy-async" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62220bc6e97f946ddd51b5f1361f78996e704677afc518a4ff66b7a72ea1378c" +dependencies = [ + "futures-util", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "aws-smithy-checksums" +version = "0.60.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "598b1689d001c4d4dc3cb386adb07d37786783aee3ac4b324bcadac116bf3d23" +dependencies = [ + "aws-smithy-http", + "aws-smithy-types", + "bytes 1.7.1", + "crc32c", + "crc32fast", + "hex", + "http 0.2.12", + "http-body 0.4.6", + "md-5", + "pin-project-lite", + "sha1 0.10.6", + "sha2 0.10.8", + "tracing", +] + +[[package]] +name = "aws-smithy-eventstream" +version = "0.60.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cef7d0a272725f87e51ba2bf89f8c21e4df61b9e49ae1ac367a6d69916ef7c90" +dependencies = [ + "aws-smithy-types", + "bytes 1.7.1", + "crc32fast", +] + +[[package]] +name = "aws-smithy-http" +version = "0.60.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c8bc3e8fdc6b8d07d976e301c02fe553f72a39b7a9fea820e023268467d7ab6" +dependencies = [ + "aws-smithy-eventstream", + "aws-smithy-runtime-api", + "aws-smithy-types", + "bytes 1.7.1", + "bytes-utils", + "futures-core", + "http 0.2.12", + "http-body 0.4.6", + "once_cell", + "percent-encoding", + "pin-project-lite", + "pin-utils", + "tracing", +] + +[[package]] +name = "aws-smithy-json" +version = "0.60.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4683df9469ef09468dad3473d129960119a0d3593617542b7d52086c8486f2d6" +dependencies = [ + "aws-smithy-types", +] + +[[package]] +name = "aws-smithy-query" +version = "0.60.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2fbd61ceb3fe8a1cb7352e42689cec5335833cd9f94103a61e98f9bb61c64bb" +dependencies = [ + "aws-smithy-types", + "urlencoding", +] + +[[package]] +name = "aws-smithy-runtime" +version = "1.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1ce695746394772e7000b39fe073095db6d45a862d0767dd5ad0ac0d7f8eb87" +dependencies = [ + "aws-smithy-async", + "aws-smithy-http", + "aws-smithy-runtime-api", + "aws-smithy-types", + "bytes 1.7.1", + "fastrand 2.1.0", + "h2 0.3.26", + "http 0.2.12", + "http-body 0.4.6", + "http-body 1.0.1", + "httparse", + "hyper 0.14.30", + "hyper-rustls 0.24.2", + "once_cell", + "pin-project-lite", + "pin-utils", + "rustls 0.21.12", + "tokio", + "tracing", +] + +[[package]] +name = "aws-smithy-runtime-api" +version = "1.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e086682a53d3aa241192aa110fa8dfce98f2f5ac2ead0de84d41582c7e8fdb96" +dependencies = [ + "aws-smithy-async", + "aws-smithy-types", + "bytes 1.7.1", + "http 0.2.12", + "http 1.1.0", + "pin-project-lite", + "tokio", + "tracing", + "zeroize", +] + +[[package]] +name = "aws-smithy-types" +version = "1.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147100a7bea70fa20ef224a6bad700358305f5dc0f84649c53769761395b355b" +dependencies = [ + "base64-simd", + "bytes 1.7.1", + "bytes-utils", + "futures-core", + "http 0.2.12", + "http 1.1.0", + "http-body 0.4.6", + "http-body 1.0.1", + "http-body-util", + "itoa", + "num-integer", + "pin-project-lite", + "pin-utils", + "ryu", + "serde", + "time 0.3.36", + "tokio", + "tokio-util", +] + +[[package]] +name = "aws-smithy-xml" +version = "0.60.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab0b0166827aa700d3dc519f72f8b3a91c35d0b8d042dc5d643a91e6f80648fc" +dependencies = [ + "xmlparser", +] + +[[package]] +name = "aws-types" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5221b91b3e441e6675310829fd8984801b772cb1546ef6c0e54dec9f1ac13fef" +dependencies = [ + "aws-credential-types", + "aws-smithy-async", + "aws-smithy-runtime-api", + "aws-smithy-types", + "rustc_version 0.4.0", + "tracing", +] + [[package]] name = "axum" version = "0.7.7" @@ -746,6 +1403,12 @@ version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4cbbc9d0964165b47557570cce6c952866c2678457aca742aafc9fb771d30270" +[[package]] +name = "base16ct" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" + [[package]] name = "base16ct" version = "0.2.0" @@ -770,6 +1433,16 @@ version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" +[[package]] +name = "base64-simd" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "339abbe78e73178762e23bea9dfd08e697eb3f3301cd4be981c0f78ba5859195" +dependencies = [ + "outref", + "vsimd", +] + [[package]] name = "base64ct" version = "1.6.0" @@ -931,6 +1604,18 @@ dependencies = [ "subtle", ] +[[package]] +name = "blst" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4378725facc195f1a538864863f6de233b500a8862747e7f165078a419d5e874" +dependencies = [ + "cc", + "glob", + "threadpool", + "zeroize", +] + [[package]] name = "bs58" version = "0.5.1" @@ -980,6 +1665,31 @@ dependencies = [ "serde", ] +[[package]] +name = "bytes-utils" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dafe3a8757b027e2be6e4e5601ed563c55989fcf1546e933c66c8eb3a058d35" +dependencies = [ + "bytes 1.7.1", + "either", +] + +[[package]] +name = "c-kzg" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0307f72feab3300336fb803a57134159f6e20139af1357f36c54cb90d8e8928" +dependencies = [ + "blst", + "cc", + "glob", + "hex", + "libc", + "once_cell", + "serde", +] + [[package]] name = "camino" version = "1.1.7" @@ -1350,6 +2060,24 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dcb25d077389e53838a8158c8e99174c5a9d902dee4904320db714f3c653ffba" +[[package]] +name = "crc32c" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a47af21622d091a8f0fb295b88bc886ac74efcc613efc19f5d0b21de5c89e47" +dependencies = [ + "rustc_version 0.4.0", +] + +[[package]] +name = "crc32fast" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" +dependencies = [ + "cfg-if", +] + [[package]] name = "criterion" version = "0.5.1" @@ -1417,6 +2145,18 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" +[[package]] +name = "crypto-bigint" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" +dependencies = [ + "generic-array 0.14.7", + "rand_core 0.6.4", + "subtle", + "zeroize", +] + [[package]] name = "crypto-bigint" version = "0.5.5" @@ -1703,6 +2443,16 @@ dependencies = [ "rustversion", ] +[[package]] +name = "der" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" +dependencies = [ + "const-oid", + "zeroize", +] + [[package]] name = "der" version = "0.7.9" @@ -1747,6 +2497,27 @@ dependencies = [ "syn 2.0.72", ] +[[package]] +name = "derive_more" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a9b99b9cbbe49445b21764dc0625032a89b145a2642e67603e1c936f5458d05" +dependencies = [ + "derive_more-impl", +] + +[[package]] +name = "derive_more-impl" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.72", + "unicode-xid", +] + [[package]] name = "digest" version = "0.9.0" @@ -1841,18 +2612,30 @@ version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" +[[package]] +name = "ecdsa" +version = "0.14.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" +dependencies = [ + "der 0.6.1", + "elliptic-curve 0.12.3", + "rfc6979 0.3.1", + "signature 1.6.4", +] + [[package]] name = "ecdsa" version = "0.16.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" dependencies = [ - "der", + "der 0.7.9", "digest 0.10.7", - "elliptic-curve", - "rfc6979", - "signature", - "spki", + "elliptic-curve 0.13.8", + "rfc6979 0.4.0", + "signature 2.2.0", + "spki 0.7.3", ] [[package]] @@ -1867,21 +2650,41 @@ version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4445909572dbd556c457c849c4ca58623d84b27c8fff1e74b0b4227d8b90d17b" +[[package]] +name = "elliptic-curve" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" +dependencies = [ + "base16ct 0.1.1", + "crypto-bigint 0.4.9", + "der 0.6.1", + "digest 0.10.7", + "ff 0.12.1", + "generic-array 0.14.7", + "group 0.12.1", + "pkcs8 0.9.0", + "rand_core 0.6.4", + "sec1 0.3.0", + "subtle", + "zeroize", +] + [[package]] name = "elliptic-curve" version = "0.13.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" dependencies = [ - "base16ct", - "crypto-bigint", + "base16ct 0.2.0", + "crypto-bigint 0.5.5", "digest 0.10.7", "ff 0.13.0", "generic-array 0.14.7", "group 0.13.0", - "pkcs8", + "pkcs8 0.10.2", "rand_core 0.6.4", - "sec1", + "sec1 0.7.3", "subtle", "zeroize", ] @@ -1993,7 +2796,7 @@ dependencies = [ "sha2 0.10.8", "sha3", "thiserror", - "uuid", + "uuid 0.8.2", ] [[package]] @@ -2138,7 +2941,7 @@ dependencies = [ "cargo_metadata", "chrono", "const-hex", - "elliptic-curve", + "elliptic-curve 0.13.8", "ethabi", "generic-array 0.14.7", "k256", @@ -2229,7 +3032,7 @@ dependencies = [ "coins-bip32", "coins-bip39", "const-hex", - "elliptic-curve", + "elliptic-curve 0.13.8", "eth-keystore", "ethers-core", "rand 0.8.5", @@ -2549,6 +3352,12 @@ dependencies = [ "slab", ] +[[package]] +name = "futures-utils-wasm" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42012b0f064e01aa58b545fe3727f90f7dd4020f4a3ea735b50344965f5a57e9" + [[package]] name = "fxhash" version = "0.2.1" @@ -2702,7 +3511,7 @@ dependencies = [ "futures-sink", "futures-util", "http 0.2.12", - "indexmap 2.3.0", + "indexmap 2.6.0", "slab", "tokio", "tokio-util", @@ -2721,7 +3530,7 @@ dependencies = [ "futures-core", "futures-sink", "http 1.1.0", - "indexmap 2.3.0", + "indexmap 2.6.0", "slab", "tokio", "tokio-util", @@ -2778,6 +3587,12 @@ dependencies = [ "serde", ] +[[package]] +name = "hashbrown" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" + [[package]] name = "hashers" version = "1.0.1" @@ -2810,6 +3625,9 @@ name = "hex" version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +dependencies = [ + "serde", +] [[package]] name = "hex-literal" @@ -3013,7 +3831,9 @@ dependencies = [ "futures-util", "http 0.2.12", "hyper 0.14.30", + "log", "rustls 0.21.12", + "rustls-native-certs 0.6.3", "tokio", "tokio-rustls 0.24.1", ] @@ -3036,6 +3856,19 @@ dependencies = [ "webpki-roots 0.26.3", ] +[[package]] +name = "hyper-timeout" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3203a961e5c83b6f5498933e78b6b263e208c197b63e9c6c53cc82ffd3f63793" +dependencies = [ + "hyper 1.4.1", + "hyper-util", + "pin-project-lite", + "tokio", + "tower-service", +] + [[package]] name = "hyper-tls" version = "0.6.0" @@ -3168,12 +4001,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.3.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3fc2e30ba82dd1b3911c8de1ffc143c74a914a14e99514d7637e3099df5ea0" +checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" dependencies = [ "equivalent", - "hashbrown 0.14.5", + "hashbrown 0.15.0", "serde", ] @@ -3357,11 +4190,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "956ff9b67e26e1a6a866cb758f12c6f8746208489e3e4a4b5580802f2f0a587b" dependencies = [ "cfg-if", - "ecdsa", - "elliptic-curve", + "ecdsa 0.16.9", + "elliptic-curve 0.13.8", "once_cell", "sha2 0.10.8", - "signature", + "signature 2.2.0", ] [[package]] @@ -3504,6 +4337,15 @@ dependencies = [ "value-bag", ] +[[package]] +name = "lru" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37ee39891760e7d94734f6f63fedc29a2e4a152f836120753a72503f09fcf904" +dependencies = [ + "hashbrown 0.14.5", +] + [[package]] name = "matchers" version = "0.1.0" @@ -3519,6 +4361,16 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" +[[package]] +name = "md-5" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" +dependencies = [ + "cfg-if", + "digest 0.10.7", +] + [[package]] name = "memchr" version = "2.7.4" @@ -3927,12 +4779,29 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" +[[package]] +name = "outref" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4030760ffd992bef45b0ae3f10ce1aba99e33464c90d14dd7c039884963ddc7a" + [[package]] name = "overload" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" +[[package]] +name = "p256" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51f44edd08f51e2ade572f141051021c5af22677e42b7dd28a88155151c33594" +dependencies = [ + "ecdsa 0.14.8", + "elliptic-curve 0.12.3", + "sha2 0.10.8", +] + [[package]] name = "p3-air" version = "0.1.3-succinct" @@ -4356,7 +5225,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" dependencies = [ "fixedbitset", - "indexmap 2.3.0", + "indexmap 2.6.0", ] [[package]] @@ -4412,14 +5281,24 @@ dependencies = [ "futures-io", ] +[[package]] +name = "pkcs8" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" +dependencies = [ + "der 0.6.1", + "spki 0.6.0", +] + [[package]] name = "pkcs8" version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" dependencies = [ - "der", - "spki", + "der 0.7.9", + "spki 0.7.3", ] [[package]] @@ -4618,6 +5497,28 @@ dependencies = [ "version_check", ] +[[package]] +name = "proc-macro-error-attr2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5" +dependencies = [ + "proc-macro2", + "quote", +] + +[[package]] +name = "proc-macro-error2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802" +dependencies = [ + "proc-macro-error-attr2", + "proc-macro2", + "quote", + "syn 2.0.72", +] + [[package]] name = "proc-macro-hack" version = "0.5.20+deprecated" @@ -4806,6 +5707,7 @@ dependencies = [ "libc", "rand_chacha 0.3.1", "rand_core 0.6.4", + "serde", ] [[package]] @@ -4945,6 +5847,12 @@ dependencies = [ "regex-syntax 0.8.4", ] +[[package]] +name = "regex-lite" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53a49587ad06b26609c52e423de037e7f57f20d53535d66e08c695f347df952a" + [[package]] name = "regex-syntax" version = "0.6.29" @@ -5063,6 +5971,17 @@ dependencies = [ "tower-service", ] +[[package]] +name = "rfc6979" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" +dependencies = [ + "crypto-bigint 0.4.9", + "hmac 0.12.1", + "zeroize", +] + [[package]] name = "rfc6979" version = "0.4.0" @@ -5284,6 +6203,7 @@ version = "0.23.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c58f8c84392efc0a126acce10fa59ff7b3d2ac06ab451a33f2741989b806b044" dependencies = [ + "log", "once_cell", "ring 0.17.8", "rustls-pki-types", @@ -5292,6 +6212,31 @@ dependencies = [ "zeroize", ] +[[package]] +name = "rustls-native-certs" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" +dependencies = [ + "openssl-probe", + "rustls-pemfile 1.0.4", + "schannel", + "security-framework", +] + +[[package]] +name = "rustls-native-certs" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcaf18a4f2be7326cd874a5fa579fae794320a0f388d365dca7e480e55f83f8a" +dependencies = [ + "openssl-probe", + "rustls-pemfile 2.1.3", + "rustls-pki-types", + "schannel", + "security-framework", +] + [[package]] name = "rustls-pemfile" version = "1.0.4" @@ -5387,7 +6332,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eca070c12893629e2cc820a9761bedf6ce1dcddc9852984d1dc734b8bd9bd024" dependencies = [ "cfg-if", - "derive_more", + "derive_more 0.99.18", "parity-scale-codec", "scale-info-derive", ] @@ -5486,16 +6431,30 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "177258b64c0faaa9ffd3c65cd3262c2bc7e2588dbbd9c1641d0346145c1bbda8" +[[package]] +name = "sec1" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" +dependencies = [ + "base16ct 0.1.1", + "der 0.6.1", + "generic-array 0.14.7", + "pkcs8 0.9.0", + "subtle", + "zeroize", +] + [[package]] name = "sec1" version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" dependencies = [ - "base16ct", - "der", + "base16ct 0.2.0", + "der 0.7.9", "generic-array 0.14.7", - "pkcs8", + "pkcs8 0.10.2", "subtle", "zeroize", ] @@ -5671,7 +6630,7 @@ dependencies = [ "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.3.0", + "indexmap 2.6.0", "serde", "serde_derive", "serde_json", @@ -5822,6 +6781,16 @@ dependencies = [ "libc", ] +[[package]] +name = "signature" +version = "1.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" +dependencies = [ + "digest 0.10.7", + "rand_core 0.6.4", +] + [[package]] name = "signature" version = "2.2.0" @@ -6028,7 +6997,7 @@ dependencies = [ "criterion", "curve25519-dalek", "elf", - "elliptic-curve", + "elliptic-curve 0.13.8", "generic-array 1.1.0", "hashbrown 0.14.5", "hex", @@ -6108,7 +7077,7 @@ version = "2.0.0" dependencies = [ "curve25519-dalek", "dashu", - "elliptic-curve", + "elliptic-curve 0.13.8", "generic-array 1.1.0", "itertools 0.13.0", "k256", @@ -6483,9 +7452,14 @@ dependencies = [ name = "sp1-sdk" version = "2.0.0" dependencies = [ - "alloy-sol-types", + "alloy-primitives 0.8.5", + "alloy-signer", + "alloy-signer-local", + "alloy-sol-types 0.7.7", "anyhow", "async-trait", + "aws-config", + "aws-sdk-s3", "axum", "bincode", "cfg-if", @@ -6522,6 +7496,7 @@ dependencies = [ "tempfile", "thiserror", "tokio", + "tonic", "tracing", "twirp-rs", "vergen", @@ -6598,6 +7573,16 @@ dependencies = [ "lock_api", ] +[[package]] +name = "spki" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" +dependencies = [ + "base64ct", + "der 0.6.1", +] + [[package]] name = "spki" version = "0.7.3" @@ -6605,7 +7590,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" dependencies = [ "base64ct", - "der", + "der 0.7.9", ] [[package]] @@ -6791,6 +7776,18 @@ dependencies = [ "syn 2.0.72", ] +[[package]] +name = "syn-solidity" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ab661c8148c2261222a4d641ad5477fd4bea79406a99056096a0b41b35617a5" +dependencies = [ + "paste", + "proc-macro2", + "quote", + "syn 2.0.72", +] + [[package]] name = "sync_wrapper" version = "0.1.2" @@ -6916,6 +7913,15 @@ dependencies = [ "once_cell", ] +[[package]] +name = "threadpool" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa" +dependencies = [ + "num_cpus", +] + [[package]] name = "time" version = "0.2.27" @@ -7081,6 +8087,17 @@ dependencies = [ "tokio", ] +[[package]] +name = "tokio-stream" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f4e6ce100d0eb49a2734f8c0812bcd324cf357d21810932c5df6b96ef2b86f1" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + [[package]] name = "tokio-util" version = "0.7.11" @@ -7121,7 +8138,7 @@ version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ - "indexmap 2.3.0", + "indexmap 2.6.0", "toml_datetime", "winnow 0.5.40", ] @@ -7132,7 +8149,7 @@ version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" dependencies = [ - "indexmap 2.3.0", + "indexmap 2.6.0", "toml_datetime", "winnow 0.5.40", ] @@ -7143,13 +8160,46 @@ version = "0.22.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "583c44c02ad26b0c3f3066fe629275e50627026c51ac2e595cca4c230ce1ce1d" dependencies = [ - "indexmap 2.3.0", + "indexmap 2.6.0", "serde", "serde_spanned", "toml_datetime", "winnow 0.6.18", ] +[[package]] +name = "tonic" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877c5b330756d856ffcc4553ab34a5684481ade925ecc54bcd1bf02b1d0d4d52" +dependencies = [ + "async-stream", + "async-trait", + "axum", + "base64 0.22.1", + "bytes 1.7.1", + "h2 0.4.5", + "http 1.1.0", + "http-body 1.0.1", + "http-body-util", + "hyper 1.4.1", + "hyper-timeout", + "hyper-util", + "percent-encoding", + "pin-project", + "prost", + "rustls-native-certs 0.8.0", + "rustls-pemfile 2.1.3", + "socket2 0.5.7", + "tokio", + "tokio-rustls 0.26.0", + "tokio-stream", + "tower 0.4.13", + "tower-layer", + "tower-service", + "tracing", +] + [[package]] name = "tower" version = "0.4.13" @@ -7158,11 +8208,16 @@ checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" dependencies = [ "futures-core", "futures-util", + "indexmap 1.9.3", "pin-project", "pin-project-lite", + "rand 0.8.5", + "slab", "tokio", + "tokio-util", "tower-layer", "tower-service", + "tracing", ] [[package]] @@ -7446,6 +8501,12 @@ dependencies = [ "serde", ] +[[package]] +name = "urlencoding" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" + [[package]] name = "utf-8" version = "0.7.6" @@ -7468,6 +8529,12 @@ dependencies = [ "serde", ] +[[package]] +name = "uuid" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314" + [[package]] name = "valuable" version = "0.1.0" @@ -7514,6 +8581,12 @@ version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" +[[package]] +name = "vsimd" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c3082ca00d5a5ef149bb8b555a72ae84c9c59f7250f013ac822ac2e49b19c64" + [[package]] name = "wait-timeout" version = "0.2.0" @@ -7969,6 +9042,12 @@ dependencies = [ "tap", ] +[[package]] +name = "xmlparser" +version = "0.13.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66fee0b777b0f5ac1c69bb06d361268faafa61cd4682ae064a171c16c433e9e4" + [[package]] name = "yansi" version = "1.0.1" diff --git a/crates/sdk/Cargo.toml b/crates/sdk/Cargo.toml index b52880c4f6..a60c2ee22c 100644 --- a/crates/sdk/Cargo.toml +++ b/crates/sdk/Cargo.toml @@ -10,7 +10,7 @@ keywords = { workspace = true } categories = { workspace = true } [dependencies] -prost = "0.13" +prost = { version = "0.13", optional = true } serde = { version = "1.0.204", features = ["derive"] } serde_json = "1.0.121" twirp = { package = "twirp-rs", version = "0.13.0-succinct", optional = true } @@ -55,6 +55,12 @@ sp1-stark = { workspace = true } sp1-primitives = { workspace = true } getrandom = { version = "0.2.15", features = ["custom", "js"] } itertools = "0.13.0" +tonic = { version = "0.12", features = ["tls", "tls-roots"], optional = true } +alloy-signer = { version = "0.3.6", optional = true } +alloy-signer-local = { version = "0.3.6", optional = true } +alloy-primitives = { version = "0.8.3", optional = true } +aws-sdk-s3 = { version = "1.53.0", optional = true } +aws-config = { version = "1.5.7", optional = true } [features] default = ["network"] @@ -63,6 +69,7 @@ native-gnark = ["sp1-prover/native-gnark"] # TODO: Once alloy has a 1.* release, we can likely remove this feature flag, as there will be less # dependency resolution issues. network = [ + "dep:prost", "dep:alloy-sol-types", "dep:tokio", "dep:ethers", @@ -70,6 +77,21 @@ network = [ "dep:twirp", "dep:reqwest-middleware", ] +network-v2 = [ + "dep:prost", + "dep:alloy-sol-types", + "dep:alloy-signer", + "dep:alloy-signer-local", + "dep:alloy-primitives", + "dep:tokio", + "dep:ethers", + "dep:reqwest", + "dep:twirp", + "dep:reqwest-middleware", + "dep:tonic", + "dep:aws-sdk-s3", + "dep:aws-config", +] cuda = ["sp1-cuda"] [build-dependencies] diff --git a/crates/sdk/src/artifacts.rs b/crates/sdk/src/artifacts.rs index 5718e45512..26663c146a 100644 --- a/crates/sdk/src/artifacts.rs +++ b/crates/sdk/src/artifacts.rs @@ -2,7 +2,7 @@ use std::path::PathBuf; use anyhow::{Context, Result}; -#[cfg(feature = "network")] +#[cfg(any(feature = "network", feature = "network-v2"))] use { futures::StreamExt, indicatif::{ProgressBar, ProgressStyle}, @@ -72,7 +72,7 @@ pub fn export_solidity_groth16_bn254_verifier(output_dir: impl Into) -> Ok(()) } -#[cfg(feature = "network")] +#[cfg(any(feature = "network", feature = "network-v2"))] pub async fn download_file( client: &Client, url: &str, diff --git a/crates/sdk/src/install.rs b/crates/sdk/src/install.rs index 4b7ed858db..b28ce0ecab 100644 --- a/crates/sdk/src/install.rs +++ b/crates/sdk/src/install.rs @@ -1,7 +1,7 @@ use cfg_if::cfg_if; use std::path::PathBuf; -#[cfg(feature = "network")] +#[cfg(any(feature = "network", feature = "network-v2"))] use { crate::block_on, futures::StreamExt, @@ -31,7 +31,7 @@ pub fn try_install_circuit_artifacts() -> PathBuf { ); } else { cfg_if! { - if #[cfg(feature = "network")] { + if #[cfg(any(feature = "network", feature = "network-v2"))] { println!( "[sp1] circuit artifacts for version {} do not exist at {}. downloading...", SP1_CIRCUIT_VERSION, @@ -48,7 +48,7 @@ pub fn try_install_circuit_artifacts() -> PathBuf { /// /// This function will download the latest circuit artifacts from the S3 bucket and extract them /// to the directory specified by [plonk_bn254_artifacts_dir()]. -#[cfg(feature = "network")] +#[cfg(any(feature = "network", feature = "network-v2"))] pub fn install_circuit_artifacts(build_dir: PathBuf) { // Create the build directory. std::fs::create_dir_all(&build_dir).expect("failed to create build directory"); @@ -77,7 +77,7 @@ pub fn install_circuit_artifacts(build_dir: PathBuf) { } /// Download the file with a progress bar that indicates the progress. -#[cfg(feature = "network")] +#[cfg(any(feature = "network", feature = "network-v2"))] pub async fn download_file( client: &Client, url: &str, diff --git a/crates/sdk/src/lib.rs b/crates/sdk/src/lib.rs index d8b572a88f..477f6653d0 100644 --- a/crates/sdk/src/lib.rs +++ b/crates/sdk/src/lib.rs @@ -5,18 +5,18 @@ //! Visit the [Getting Started](https://succinctlabs.github.io/sp1/getting-started.html) section //! in the official SP1 documentation for a quick start guide. -#[rustfmt::skip] -#[cfg(feature = "network")] -pub mod proto { - pub mod network; -} pub mod action; pub mod artifacts; pub mod install; #[cfg(feature = "network")] pub mod network; +#[cfg(feature = "network-v2")] +#[path = "network-v2/mod.rs"] +pub mod network_v2; #[cfg(feature = "network")] -pub use crate::network::prover::NetworkProver; +pub use crate::network::prover::NetworkProver as NetworkProverV1; +#[cfg(feature = "network-v2")] +pub use crate::network_v2::prover::NetworkProver as NetworkProverV2; #[cfg(feature = "cuda")] pub use crate::provers::CudaProver; @@ -33,7 +33,7 @@ use sp1_prover::components::DefaultProverComponents; use std::env; -#[cfg(feature = "network")] +#[cfg(any(feature = "network", feature = "network-v2"))] use {std::future::Future, tokio::task::block_in_place}; pub use provers::{CpuProver, MockProver, Prover}; @@ -84,9 +84,13 @@ impl ProverClient { }, "network" => { cfg_if! { - if #[cfg(feature = "network")] { + if #[cfg(feature = "network-v2")] { + Self { + prover: Box::new(NetworkProverV2::new()), + } + } else if #[cfg(feature = "network")] { Self { - prover: Box::new(NetworkProver::new()), + prover: Box::new(NetworkProverV1::new()), } } else { panic!("network feature is not enabled") @@ -145,9 +149,13 @@ impl ProverClient { /// ``` pub fn network() -> Self { cfg_if! { - if #[cfg(feature = "network")] { + if #[cfg(feature = "network-v2")] { + Self { + prover: Box::new(NetworkProverV2::new()), + } + } else if #[cfg(feature = "network")] { Self { - prover: Box::new(NetworkProver::new()), + prover: Box::new(NetworkProverV1::new()), } } else { panic!("network feature is not enabled") @@ -277,7 +285,7 @@ impl Default for ProverClient { /// /// If we're already in a tokio runtime, we'll block in place. Otherwise, we'll create a new /// runtime. -#[cfg(feature = "network")] +#[cfg(any(feature = "network", feature = "network-v2"))] pub fn block_on(fut: impl Future) -> T { // Handle case if we're already in an tokio runtime. if let Ok(handle) = tokio::runtime::Handle::try_current() { diff --git a/crates/sdk/src/network-v2/client.rs b/crates/sdk/src/network-v2/client.rs new file mode 100644 index 0000000000..a2ad18a2a8 --- /dev/null +++ b/crates/sdk/src/network-v2/client.rs @@ -0,0 +1,228 @@ +use std::{env, time::Duration}; + +use alloy_signer::SignerSync; +use alloy_signer_local::PrivateKeySigner; +use anyhow::{Context, Ok, Result}; +use aws_config::BehaviorVersion; +use aws_sdk_s3::Client as S3Client; +use reqwest_middleware::ClientWithMiddleware as HttpClientWithMiddleware; +use serde::de::DeserializeOwned; +use serde::Serialize; +use sp1_core_machine::io::SP1Stdin; +use sp1_prover::SP1VerifyingKey; +use std::str::FromStr; +use std::time::{SystemTime, UNIX_EPOCH}; +use tokio::sync::OnceCell; +use tokio::try_join; +use tonic::transport::Channel; + +use crate::network_v2::proto::artifact::{ + artifact_store_client::ArtifactStoreClient, CreateArtifactRequest, +}; +use crate::network_v2::proto::network::{ + prover_network_client::ProverNetworkClient, GetFilteredProofRequestsRequest, + GetFilteredProofRequestsResponse, GetNonceRequest, GetProofRequestStatusRequest, + GetProofRequestStatusResponse, ProofMode, ProofStatus, ProofStrategy, RequestProofRequest, + RequestProofRequestBody, RequestProofResponse, +}; +use crate::network_v2::Signable; + +/// The default RPC endpoint for the Succinct prover network. +pub const DEFAULT_PROVER_NETWORK_RPC: &str = "http://127.0.0.1:50051"; + +pub struct NetworkClient { + signer: PrivateKeySigner, + http: HttpClientWithMiddleware, + s3: OnceCell, +} + +impl NetworkClient { + /// Create a new network client with the given private key. + pub fn new(private_key: &str) -> Self { + let signer = PrivateKeySigner::from_str(private_key).unwrap(); + + let http_client = reqwest::Client::builder() + .pool_max_idle_per_host(0) + .pool_idle_timeout(Duration::from_secs(240)) + .build() + .unwrap(); + + Self { signer, http: http_client.into(), s3: OnceCell::new() } + } + + /// Returns the currently configured RPC endpoint for the Succinct prover network. + pub fn rpc_url() -> String { + env::var("PROVER_NETWORK_RPC").unwrap_or_else(|_| DEFAULT_PROVER_NETWORK_RPC.to_string()) + } + + /// Get a connected RPC client. + async fn get_rpc(&self) -> Result> { + let rpc_url = Self::rpc_url(); + let channel = Channel::from_shared(rpc_url)?.connect().await?; + Ok(ProverNetworkClient::new(channel.clone())) + } + + /// Get a connected artifact store client. + async fn get_store(&self) -> Result> { + let rpc_url = Self::rpc_url(); + let channel = Channel::from_shared(rpc_url)?.connect().await?; + Ok(ArtifactStoreClient::new(channel.clone())) + } + + /// Get the S3 client. + async fn get_s3_client(&self) -> &S3Client { + self.s3 + .get_or_init(|| async { + let config = aws_config::load_defaults(BehaviorVersion::latest()).await; + S3Client::new(&config) + }) + .await + } + + /// Get the latest nonce for this account's address. + pub async fn get_nonce(&self) -> Result { + let mut rpc = self.get_rpc().await?; + let res = + rpc.get_nonce(GetNonceRequest { address: self.signer.address().to_vec() }).await?; + Ok(res.into_inner().nonce) + } + + /// Get the status of a given proof. If the status is Fulfilled, the proof is also returned. + pub async fn get_proof_request_status( + &self, + request_id: &[u8], + ) -> Result<(GetProofRequestStatusResponse, Option

)> { + let mut rpc = self.get_rpc().await?; + let res = rpc + .get_proof_request_status(GetProofRequestStatusRequest { + request_id: request_id.to_vec(), + }) + .await? + .into_inner(); + let status = ProofStatus::try_from(res.status)?; + let proof = match status { + ProofStatus::Fulfilled => { + log::info!("Proof request fulfilled"); + let proof_uri = res + .proof_uri + .as_ref() + .ok_or_else(|| anyhow::anyhow!("No proof URL provided"))?; + let proof_bytes = self.download_artifact(proof_uri).await?; + Some(bincode::deserialize(&proof_bytes).context("Failed to deserialize proof")?) + } + _ => None, + }; + + Ok((res, proof)) + } + + /// Get all the proof requests for a given status. Also filter by version if provided. + pub async fn get_filtered_proof_requests( + &self, + status: ProofStatus, + version: Option<&str>, + ) -> Result { + let mut rpc = self.get_rpc().await?; + let res = rpc + .get_filtered_proof_requests(GetFilteredProofRequestsRequest { + status: status.into(), + version: version.map(|v| v.to_string()).unwrap_or_default(), + }) + .await? + .into_inner(); + + Ok(res) + } + + /// Creates a proof request with the given ELF and stdin. + #[allow(clippy::too_many_arguments)] + pub async fn request_proof( + &self, + elf: &[u8], + stdin: &SP1Stdin, + vk: &SP1VerifyingKey, + mode: ProofMode, + version: &str, + strategy: ProofStrategy, + timeout_secs: u64, + cycle_limit: u64, + ) -> Result { + // Calculate the deadline. + let start = SystemTime::now(); + let since_the_epoch = start.duration_since(UNIX_EPOCH).expect("Invalid start time"); + let deadline = since_the_epoch.as_secs() + timeout_secs; + + // Create the program and stdin artifacts. + let mut store = self.get_store().await?; + let mut store_clone = store.clone(); + let program_promise = self.create_artifact_with_content(&mut store, &elf); + let stdin_promise = self.create_artifact_with_content(&mut store_clone, &stdin); + let (program_uri, stdin_uri) = try_join!(program_promise, stdin_promise)?; + + // Serialize the vkey. + let vkey = bincode::serialize(&vk)?; + + // Send the request. + let mut rpc = self.get_rpc().await?; + let nonce = self.get_nonce().await?; + let request_body = RequestProofRequestBody { + nonce, + version: format!("sp1-{}", version), + vkey, + mode: mode.into(), + strategy: strategy.into(), + program_uri, + stdin_uri, + deadline, + cycle_limit, + }; + let request_response = rpc + .request_proof(RequestProofRequest { + signature: request_body.sign(&self.signer).into(), + body: Some(request_body), + }) + .await? + .into_inner(); + + Ok(request_response) + } + + /// Uses the artifact store to to create an artifact, upload the content, and return the URI. + async fn create_artifact_with_content( + &self, + store: &mut ArtifactStoreClient, + item: &T, + ) -> Result { + let signature = self.signer.sign_message_sync("create_artifact".as_bytes())?; + let request = CreateArtifactRequest { signature: signature.as_bytes().to_vec() }; + let response = store.create_artifact(request).await?.into_inner(); + + let presigned_url = response.artifact_presigned_url; + let uri = response.artifact_uri; + + let response = + self.http.put(&presigned_url).body(bincode::serialize::(item)?).send().await?; + + assert!(response.status().is_success()); + + Ok(uri) + } + + /// Download an artifact from S3. + async fn download_artifact(&self, uri: &str) -> Result> { + let s3_client = self.get_s3_client().await; + let uri = uri.strip_prefix("s3://").context("Invalid S3 URI")?; + let (bucket, key) = uri.split_once('/').context("Invalid S3 URI format")?; + + let resp = s3_client + .get_object() + .bucket(bucket) + .key(key) + .send() + .await + .context("Failed to get object from S3")?; + + let data = resp.body.collect().await.context("Failed to read S3 object body")?; + Ok(data.into_bytes().to_vec()) + } +} diff --git a/crates/sdk/src/network-v2/mod.rs b/crates/sdk/src/network-v2/mod.rs new file mode 100644 index 0000000000..e6444357b2 --- /dev/null +++ b/crates/sdk/src/network-v2/mod.rs @@ -0,0 +1,19 @@ +pub mod client; +pub mod prover; +mod sign_message; +#[rustfmt::skip] +pub mod proto; + +use alloy_signer::{Signature, SignerSync}; +use prost::Message; +pub use serde::{Deserialize, Serialize}; + +pub trait Signable: Message { + fn sign(&self, signer: &S) -> Signature; +} + +impl Signable for T { + fn sign(&self, signer: &S) -> Signature { + signer.sign_message_sync(&self.encode_to_vec()).unwrap() + } +} diff --git a/crates/sdk/src/network-v2/proto/artifact.rs b/crates/sdk/src/network-v2/proto/artifact.rs new file mode 100644 index 0000000000..f35dcdf8e3 --- /dev/null +++ b/crates/sdk/src/network-v2/proto/artifact.rs @@ -0,0 +1,278 @@ +// This file is @generated by prost-build. +#[derive(serde::Serialize, serde::Deserialize, Clone, PartialEq, ::prost::Message)] +pub struct CreateArtifactRequest { + /// The signature of the user on a pre-defined message. Used for authentication. + #[prost(bytes = "vec", tag = "1")] + pub signature: ::prost::alloc::vec::Vec, +} +#[derive(serde::Serialize, serde::Deserialize, Clone, PartialEq, ::prost::Message)] +pub struct CreateArtifactResponse { + /// The unique resource identifier of the artifact. + #[prost(string, tag = "1")] + pub artifact_uri: ::prost::alloc::string::String, + /// The presigned url to upload the artifact. + #[prost(string, tag = "2")] + pub artifact_presigned_url: ::prost::alloc::string::String, +} +/// Generated client implementations. +pub mod artifact_store_client { + #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)] + use tonic::codegen::http::Uri; + use tonic::codegen::*; + #[derive(Debug, Clone)] + pub struct ArtifactStoreClient { + inner: tonic::client::Grpc, + } + impl ArtifactStoreClient { + /// Attempt to create a new client by connecting to a given endpoint. + pub async fn connect(dst: D) -> Result + where + D: TryInto, + D::Error: Into, + { + let conn = tonic::transport::Endpoint::new(dst)?.connect().await?; + Ok(Self::new(conn)) + } + } + impl ArtifactStoreClient + where + T: tonic::client::GrpcService, + T::Error: Into, + T::ResponseBody: Body + std::marker::Send + 'static, + ::Error: Into + std::marker::Send, + { + pub fn new(inner: T) -> Self { + let inner = tonic::client::Grpc::new(inner); + Self { inner } + } + pub fn with_origin(inner: T, origin: Uri) -> Self { + let inner = tonic::client::Grpc::with_origin(inner, origin); + Self { inner } + } + pub fn with_interceptor( + inner: T, + interceptor: F, + ) -> ArtifactStoreClient> + where + F: tonic::service::Interceptor, + T::ResponseBody: Default, + T: tonic::codegen::Service< + http::Request, + Response = http::Response< + >::ResponseBody, + >, + >, + >>::Error: + Into + std::marker::Send + std::marker::Sync, + { + ArtifactStoreClient::new(InterceptedService::new(inner, interceptor)) + } + /// Compress requests with the given encoding. + /// + /// This requires the server to support it otherwise it might respond with an + /// error. + #[must_use] + pub fn send_compressed(mut self, encoding: CompressionEncoding) -> Self { + self.inner = self.inner.send_compressed(encoding); + self + } + /// Enable decompressing responses. + #[must_use] + pub fn accept_compressed(mut self, encoding: CompressionEncoding) -> Self { + self.inner = self.inner.accept_compressed(encoding); + self + } + /// Limits the maximum size of a decoded message. + /// + /// Default: `4MB` + #[must_use] + pub fn max_decoding_message_size(mut self, limit: usize) -> Self { + self.inner = self.inner.max_decoding_message_size(limit); + self + } + /// Limits the maximum size of an encoded message. + /// + /// Default: `usize::MAX` + #[must_use] + pub fn max_encoding_message_size(mut self, limit: usize) -> Self { + self.inner = self.inner.max_encoding_message_size(limit); + self + } + /// / Creates an artifact that can be used for proof requests. + pub async fn create_artifact( + &mut self, + request: impl tonic::IntoRequest, + ) -> std::result::Result, tonic::Status> + { + self.inner.ready().await.map_err(|e| { + tonic::Status::new( + tonic::Code::Unknown, + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic::codec::ProstCodec::default(); + let path = + http::uri::PathAndQuery::from_static("/artifact.ArtifactStore/CreateArtifact"); + let mut req = request.into_request(); + req.extensions_mut() + .insert(GrpcMethod::new("artifact.ArtifactStore", "CreateArtifact")); + self.inner.unary(req, path, codec).await + } + } +} +/// Generated server implementations. +pub mod artifact_store_server { + #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)] + use tonic::codegen::*; + /// Generated trait containing gRPC methods that should be implemented for use with ArtifactStoreServer. + #[async_trait] + pub trait ArtifactStore: std::marker::Send + std::marker::Sync + 'static { + /// / Creates an artifact that can be used for proof requests. + async fn create_artifact( + &self, + request: tonic::Request, + ) -> std::result::Result, tonic::Status>; + } + #[derive(Debug)] + pub struct ArtifactStoreServer { + inner: Arc, + accept_compression_encodings: EnabledCompressionEncodings, + send_compression_encodings: EnabledCompressionEncodings, + max_decoding_message_size: Option, + max_encoding_message_size: Option, + } + impl ArtifactStoreServer { + pub fn new(inner: T) -> Self { + Self::from_arc(Arc::new(inner)) + } + pub fn from_arc(inner: Arc) -> Self { + Self { + inner, + accept_compression_encodings: Default::default(), + send_compression_encodings: Default::default(), + max_decoding_message_size: None, + max_encoding_message_size: None, + } + } + pub fn with_interceptor(inner: T, interceptor: F) -> InterceptedService + where + F: tonic::service::Interceptor, + { + InterceptedService::new(Self::new(inner), interceptor) + } + /// Enable decompressing requests with the given encoding. + #[must_use] + pub fn accept_compressed(mut self, encoding: CompressionEncoding) -> Self { + self.accept_compression_encodings.enable(encoding); + self + } + /// Compress responses with the given encoding, if the client supports it. + #[must_use] + pub fn send_compressed(mut self, encoding: CompressionEncoding) -> Self { + self.send_compression_encodings.enable(encoding); + self + } + /// Limits the maximum size of a decoded message. + /// + /// Default: `4MB` + #[must_use] + pub fn max_decoding_message_size(mut self, limit: usize) -> Self { + self.max_decoding_message_size = Some(limit); + self + } + /// Limits the maximum size of an encoded message. + /// + /// Default: `usize::MAX` + #[must_use] + pub fn max_encoding_message_size(mut self, limit: usize) -> Self { + self.max_encoding_message_size = Some(limit); + self + } + } + impl tonic::codegen::Service> for ArtifactStoreServer + where + T: ArtifactStore, + B: Body + std::marker::Send + 'static, + B::Error: Into + std::marker::Send + 'static, + { + type Response = http::Response; + type Error = std::convert::Infallible; + type Future = BoxFuture; + fn poll_ready( + &mut self, + _cx: &mut Context<'_>, + ) -> Poll> { + Poll::Ready(Ok(())) + } + fn call(&mut self, req: http::Request) -> Self::Future { + match req.uri().path() { + "/artifact.ArtifactStore/CreateArtifact" => { + #[allow(non_camel_case_types)] + struct CreateArtifactSvc(pub Arc); + impl tonic::server::UnaryService + for CreateArtifactSvc + { + type Response = super::CreateArtifactResponse; + type Future = BoxFuture, tonic::Status>; + fn call( + &mut self, + request: tonic::Request, + ) -> Self::Future { + let inner = Arc::clone(&self.0); + let fut = async move { + ::create_artifact(&inner, request).await + }; + Box::pin(fut) + } + } + let accept_compression_encodings = self.accept_compression_encodings; + let send_compression_encodings = self.send_compression_encodings; + let max_decoding_message_size = self.max_decoding_message_size; + let max_encoding_message_size = self.max_encoding_message_size; + let inner = self.inner.clone(); + let fut = async move { + let method = CreateArtifactSvc(inner); + let codec = tonic::codec::ProstCodec::default(); + let mut grpc = tonic::server::Grpc::new(codec) + .apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ) + .apply_max_message_size_config( + max_decoding_message_size, + max_encoding_message_size, + ); + let res = grpc.unary(method, req).await; + Ok(res) + }; + Box::pin(fut) + } + _ => Box::pin(async move { + Ok(http::Response::builder() + .status(200) + .header("grpc-status", tonic::Code::Unimplemented as i32) + .header(http::header::CONTENT_TYPE, tonic::metadata::GRPC_CONTENT_TYPE) + .body(empty_body()) + .unwrap()) + }), + } + } + } + impl Clone for ArtifactStoreServer { + fn clone(&self) -> Self { + let inner = self.inner.clone(); + Self { + inner, + accept_compression_encodings: self.accept_compression_encodings, + send_compression_encodings: self.send_compression_encodings, + max_decoding_message_size: self.max_decoding_message_size, + max_encoding_message_size: self.max_encoding_message_size, + } + } + } + /// Generated gRPC service name + pub const SERVICE_NAME: &str = "artifact.ArtifactStore"; + impl tonic::server::NamedService for ArtifactStoreServer { + const NAME: &'static str = SERVICE_NAME; + } +} diff --git a/crates/sdk/src/network-v2/proto/mod.rs b/crates/sdk/src/network-v2/proto/mod.rs new file mode 100644 index 0000000000..48eb63675a --- /dev/null +++ b/crates/sdk/src/network-v2/proto/mod.rs @@ -0,0 +1,2 @@ +pub mod artifact; +pub mod network; diff --git a/crates/sdk/src/network-v2/proto/network.rs b/crates/sdk/src/network-v2/proto/network.rs new file mode 100644 index 0000000000..0ffa73ebf7 --- /dev/null +++ b/crates/sdk/src/network-v2/proto/network.rs @@ -0,0 +1,907 @@ +// This file is @generated by prost-build. +#[derive(serde::Serialize, serde::Deserialize, Clone, PartialEq, ::prost::Message)] +pub struct GetFilteredProofRequestsRequest { + /// The status of the proof requests to filter for. + #[prost(enumeration = "ProofStatus", tag = "1")] + pub status: i32, + /// The version of the proof requests to filter for. + #[prost(string, tag = "2")] + pub version: ::prost::alloc::string::String, +} +#[derive(serde::Serialize, serde::Deserialize, Clone, PartialEq, ::prost::Message)] +pub struct ProofRequest { + /// The request identifier. + #[prost(string, tag = "1")] + pub request_id: ::prost::alloc::string::String, + /// The version of the prover to use. + #[prost(string, tag = "2")] + pub version: ::prost::alloc::string::String, + /// The mode for the proof. + #[prost(enumeration = "ProofMode", tag = "4")] + pub mode: i32, + /// The strategy for prover assignment. + #[prost(enumeration = "ProofStrategy", tag = "5")] + pub strategy: i32, + /// The program resource identifier. + #[prost(string, tag = "6")] + pub program_uri: ::prost::alloc::string::String, + /// The stdin resource identifier. + #[prost(string, tag = "7")] + pub stdin_uri: ::prost::alloc::string::String, + /// The deadline for the proof. + #[prost(uint64, tag = "8")] + pub deadline: u64, + /// The cycle limit for the proof. + #[prost(uint64, tag = "9")] + pub cycle_limit: u64, + /// The status of the proof request. + #[prost(enumeration = "ProofStatus", tag = "10")] + pub status: i32, + /// The requestor address. + #[prost(bytes = "vec", tag = "11")] + pub requester: ::prost::alloc::vec::Vec, +} +#[derive(serde::Serialize, serde::Deserialize, Clone, PartialEq, ::prost::Message)] +pub struct GetFilteredProofRequestsResponse { + /// The proof requests for the given status. + #[prost(message, repeated, tag = "1")] + pub requests: ::prost::alloc::vec::Vec, +} +#[derive(serde::Serialize, serde::Deserialize, Clone, PartialEq, ::prost::Message)] +pub struct RequestProofRequest { + /// The signature of the sender. + #[prost(bytes = "vec", tag = "1")] + pub signature: ::prost::alloc::vec::Vec, + /// The body of the request. + #[prost(message, optional, tag = "3")] + pub body: ::core::option::Option, +} +#[derive(serde::Serialize, serde::Deserialize, Clone, PartialEq, ::prost::Message)] +pub struct RequestProofRequestBody { + /// The nonce of the request. + #[prost(uint64, tag = "1")] + pub nonce: u64, + /// The version of the prover to use. + #[prost(string, tag = "2")] + pub version: ::prost::alloc::string::String, + /// The verification key. + #[prost(bytes = "vec", tag = "3")] + pub vkey: ::prost::alloc::vec::Vec, + /// The mode for the proof. + #[prost(enumeration = "ProofMode", tag = "4")] + pub mode: i32, + /// The strategy for prover assignment. + #[prost(enumeration = "ProofStrategy", tag = "5")] + pub strategy: i32, + /// The program resource identifier. + #[prost(string, tag = "6")] + pub program_uri: ::prost::alloc::string::String, + /// The stdin resource identifier. + #[prost(string, tag = "7")] + pub stdin_uri: ::prost::alloc::string::String, + /// The deadline for the proof. + #[prost(uint64, tag = "8")] + pub deadline: u64, + /// The cycle limit for the proof. + #[prost(uint64, tag = "9")] + pub cycle_limit: u64, +} +#[derive(serde::Serialize, serde::Deserialize, Clone, PartialEq, ::prost::Message)] +pub struct RequestProofResponse { + /// / The transaction hash. + #[prost(bytes = "vec", tag = "1")] + pub tx_hash: ::prost::alloc::vec::Vec, + /// / The body of the response. + #[prost(message, optional, tag = "2")] + pub body: ::core::option::Option, +} +#[derive(serde::Serialize, serde::Deserialize, Clone, PartialEq, ::prost::Message)] +pub struct RequestProofResponseBody { + /// The identifier for the proof. + #[prost(bytes = "vec", tag = "1")] + pub request_id: ::prost::alloc::vec::Vec, +} +#[derive(serde::Serialize, serde::Deserialize, Clone, PartialEq, ::prost::Message)] +pub struct FulfillProofRequest { + /// The signature of the sender. + #[prost(bytes = "vec", tag = "1")] + pub signature: ::prost::alloc::vec::Vec, + /// The body of the request. + #[prost(message, optional, tag = "3")] + pub body: ::core::option::Option, +} +#[derive(serde::Serialize, serde::Deserialize, Clone, PartialEq, ::prost::Message)] +pub struct FulfillProofRequestBody { + /// The nonce of the request. + #[prost(uint64, tag = "1")] + pub nonce: u64, + /// The identifier for the proof. + #[prost(bytes = "vec", tag = "2")] + pub request_id: ::prost::alloc::vec::Vec, + /// The proof bytes. + #[prost(bytes = "vec", tag = "3")] + pub proof: ::prost::alloc::vec::Vec, +} +#[derive(serde::Serialize, serde::Deserialize, Clone, PartialEq, ::prost::Message)] +pub struct FulfillProofResponse { + /// / The transaction hash. + #[prost(bytes = "vec", tag = "1")] + pub tx_hash: ::prost::alloc::vec::Vec, + /// / The body of the response. + #[prost(message, optional, tag = "2")] + pub body: ::core::option::Option, +} +#[derive(serde::Serialize, serde::Deserialize, Clone, Copy, PartialEq, ::prost::Message)] +pub struct FulfillProofResponseBody {} +#[derive(serde::Serialize, serde::Deserialize, Clone, PartialEq, ::prost::Message)] +pub struct GetBalanceRequest { + /// The address of the account. + #[prost(bytes = "vec", tag = "1")] + pub address: ::prost::alloc::vec::Vec, +} +#[derive(serde::Serialize, serde::Deserialize, Clone, PartialEq, ::prost::Message)] +pub struct GetBalanceResponse { + /// The amount of the token owned by the account. + #[prost(string, tag = "1")] + pub amount: ::prost::alloc::string::String, +} +#[derive(serde::Serialize, serde::Deserialize, Clone, PartialEq, ::prost::Message)] +pub struct GetNonceRequest { + /// The address of the account. + #[prost(bytes = "vec", tag = "1")] + pub address: ::prost::alloc::vec::Vec, +} +#[derive(serde::Serialize, serde::Deserialize, Clone, Copy, PartialEq, ::prost::Message)] +pub struct GetNonceResponse { + /// The nonce of the account. + #[prost(uint64, tag = "1")] + pub nonce: u64, +} +#[derive(serde::Serialize, serde::Deserialize, Clone, PartialEq, ::prost::Message)] +pub struct GetProofRequestStatusRequest { + /// The identifier for the proof request. + #[prost(bytes = "vec", tag = "1")] + pub request_id: ::prost::alloc::vec::Vec, +} +#[derive(serde::Serialize, serde::Deserialize, Clone, PartialEq, ::prost::Message)] +pub struct GetProofRequestStatusResponse { + /// The status of the proof request. + #[prost(enumeration = "ProofStatus", tag = "1")] + pub status: i32, + /// The transaction hash of the proof request. + #[prost(bytes = "vec", tag = "2")] + pub request_tx_hash: ::prost::alloc::vec::Vec, + /// The optional transaction hash of the proof fulfill. Only included if the proof request has a + /// status of FULFILLED. + #[prost(bytes = "vec", optional, tag = "3")] + pub fulfill_tx_hash: ::core::option::Option<::prost::alloc::vec::Vec>, + /// The optional proof URI, where you can download the result of the proof request. Only included + /// if the proof has a status of FULFILLED. + #[prost(string, optional, tag = "4")] + pub proof_uri: ::core::option::Option<::prost::alloc::string::String>, + /// The optional error status code, if the request failed. + #[prost(uint32, optional, tag = "5")] + pub error_code: ::core::option::Option, + /// The optional error description details, if the request failed. + #[prost(string, optional, tag = "6")] + pub error_description: ::core::option::Option<::prost::alloc::string::String>, +} +#[derive( + serde::Serialize, + serde::Deserialize, + Clone, + Copy, + Debug, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, + ::prost::Enumeration, +)] +#[repr(i32)] +pub enum ProofMode { + UnspecifiedMode = 0, + Core = 1, + Compressed = 2, + Plonk = 3, + Groth16 = 4, +} +impl ProofMode { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + Self::UnspecifiedMode => "UNSPECIFIED_MODE", + Self::Core => "CORE", + Self::Compressed => "COMPRESSED", + Self::Plonk => "PLONK", + Self::Groth16 => "GROTH16", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "UNSPECIFIED_MODE" => Some(Self::UnspecifiedMode), + "CORE" => Some(Self::Core), + "COMPRESSED" => Some(Self::Compressed), + "PLONK" => Some(Self::Plonk), + "GROTH16" => Some(Self::Groth16), + _ => None, + } + } +} +#[derive( + serde::Serialize, + serde::Deserialize, + Clone, + Copy, + Debug, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, + ::prost::Enumeration, +)] +#[repr(i32)] +pub enum ProofStrategy { + UnspecifiedStrategy = 0, + Hosted = 1, +} +impl ProofStrategy { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + Self::UnspecifiedStrategy => "UNSPECIFIED_STRATEGY", + Self::Hosted => "HOSTED", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "UNSPECIFIED_STRATEGY" => Some(Self::UnspecifiedStrategy), + "HOSTED" => Some(Self::Hosted), + _ => None, + } + } +} +#[derive( + serde::Serialize, + serde::Deserialize, + Clone, + Copy, + Debug, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, + ::prost::Enumeration, +)] +#[repr(i32)] +pub enum ProofStatus { + UnspecifiedStatus = 0, + Requested = 1, + Assigned = 2, + Fulfilled = 3, +} +impl ProofStatus { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + Self::UnspecifiedStatus => "UNSPECIFIED_STATUS", + Self::Requested => "REQUESTED", + Self::Assigned => "ASSIGNED", + Self::Fulfilled => "FULFILLED", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "UNSPECIFIED_STATUS" => Some(Self::UnspecifiedStatus), + "REQUESTED" => Some(Self::Requested), + "ASSIGNED" => Some(Self::Assigned), + "FULFILLED" => Some(Self::Fulfilled), + _ => None, + } + } +} +/// Generated client implementations. +pub mod prover_network_client { + #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)] + use tonic::codegen::http::Uri; + use tonic::codegen::*; + #[derive(Debug, Clone)] + pub struct ProverNetworkClient { + inner: tonic::client::Grpc, + } + impl ProverNetworkClient { + /// Attempt to create a new client by connecting to a given endpoint. + pub async fn connect(dst: D) -> Result + where + D: TryInto, + D::Error: Into, + { + let conn = tonic::transport::Endpoint::new(dst)?.connect().await?; + Ok(Self::new(conn)) + } + } + impl ProverNetworkClient + where + T: tonic::client::GrpcService, + T::Error: Into, + T::ResponseBody: Body + std::marker::Send + 'static, + ::Error: Into + std::marker::Send, + { + pub fn new(inner: T) -> Self { + let inner = tonic::client::Grpc::new(inner); + Self { inner } + } + pub fn with_origin(inner: T, origin: Uri) -> Self { + let inner = tonic::client::Grpc::with_origin(inner, origin); + Self { inner } + } + pub fn with_interceptor( + inner: T, + interceptor: F, + ) -> ProverNetworkClient> + where + F: tonic::service::Interceptor, + T::ResponseBody: Default, + T: tonic::codegen::Service< + http::Request, + Response = http::Response< + >::ResponseBody, + >, + >, + >>::Error: + Into + std::marker::Send + std::marker::Sync, + { + ProverNetworkClient::new(InterceptedService::new(inner, interceptor)) + } + /// Compress requests with the given encoding. + /// + /// This requires the server to support it otherwise it might respond with an + /// error. + #[must_use] + pub fn send_compressed(mut self, encoding: CompressionEncoding) -> Self { + self.inner = self.inner.send_compressed(encoding); + self + } + /// Enable decompressing responses. + #[must_use] + pub fn accept_compressed(mut self, encoding: CompressionEncoding) -> Self { + self.inner = self.inner.accept_compressed(encoding); + self + } + /// Limits the maximum size of a decoded message. + /// + /// Default: `4MB` + #[must_use] + pub fn max_decoding_message_size(mut self, limit: usize) -> Self { + self.inner = self.inner.max_decoding_message_size(limit); + self + } + /// Limits the maximum size of an encoded message. + /// + /// Default: `usize::MAX` + #[must_use] + pub fn max_encoding_message_size(mut self, limit: usize) -> Self { + self.inner = self.inner.max_encoding_message_size(limit); + self + } + /// Creates a proof. + pub async fn request_proof( + &mut self, + request: impl tonic::IntoRequest, + ) -> std::result::Result, tonic::Status> + { + self.inner.ready().await.map_err(|e| { + tonic::Status::new( + tonic::Code::Unknown, + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic::codec::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static("/network.ProverNetwork/RequestProof"); + let mut req = request.into_request(); + req.extensions_mut().insert(GrpcMethod::new("network.ProverNetwork", "RequestProof")); + self.inner.unary(req, path, codec).await + } + /// Fulfills a proof. + pub async fn fulfill_proof( + &mut self, + request: impl tonic::IntoRequest, + ) -> std::result::Result, tonic::Status> + { + self.inner.ready().await.map_err(|e| { + tonic::Status::new( + tonic::Code::Unknown, + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic::codec::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static("/network.ProverNetwork/FulfillProof"); + let mut req = request.into_request(); + req.extensions_mut().insert(GrpcMethod::new("network.ProverNetwork", "FulfillProof")); + self.inner.unary(req, path, codec).await + } + /// Get the proof requests the meet the filter criteria. + pub async fn get_filtered_proof_requests( + &mut self, + request: impl tonic::IntoRequest, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + > { + self.inner.ready().await.map_err(|e| { + tonic::Status::new( + tonic::Code::Unknown, + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic::codec::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static( + "/network.ProverNetwork/GetFilteredProofRequests", + ); + let mut req = request.into_request(); + req.extensions_mut() + .insert(GrpcMethod::new("network.ProverNetwork", "GetFilteredProofRequests")); + self.inner.unary(req, path, codec).await + } + /// Get the status of a proof request. + pub async fn get_proof_request_status( + &mut self, + request: impl tonic::IntoRequest, + ) -> std::result::Result, tonic::Status> + { + self.inner.ready().await.map_err(|e| { + tonic::Status::new( + tonic::Code::Unknown, + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic::codec::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static( + "/network.ProverNetwork/GetProofRequestStatus", + ); + let mut req = request.into_request(); + req.extensions_mut() + .insert(GrpcMethod::new("network.ProverNetwork", "GetProofRequestStatus")); + self.inner.unary(req, path, codec).await + } + /// Get the balance of the account. + pub async fn get_balance( + &mut self, + request: impl tonic::IntoRequest, + ) -> std::result::Result, tonic::Status> + { + self.inner.ready().await.map_err(|e| { + tonic::Status::new( + tonic::Code::Unknown, + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic::codec::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static("/network.ProverNetwork/GetBalance"); + let mut req = request.into_request(); + req.extensions_mut().insert(GrpcMethod::new("network.ProverNetwork", "GetBalance")); + self.inner.unary(req, path, codec).await + } + /// Get the nonce of the account. + pub async fn get_nonce( + &mut self, + request: impl tonic::IntoRequest, + ) -> std::result::Result, tonic::Status> { + self.inner.ready().await.map_err(|e| { + tonic::Status::new( + tonic::Code::Unknown, + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic::codec::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static("/network.ProverNetwork/GetNonce"); + let mut req = request.into_request(); + req.extensions_mut().insert(GrpcMethod::new("network.ProverNetwork", "GetNonce")); + self.inner.unary(req, path, codec).await + } + } +} +/// Generated server implementations. +pub mod prover_network_server { + #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)] + use tonic::codegen::*; + /// Generated trait containing gRPC methods that should be implemented for use with ProverNetworkServer. + #[async_trait] + pub trait ProverNetwork: std::marker::Send + std::marker::Sync + 'static { + /// Creates a proof. + async fn request_proof( + &self, + request: tonic::Request, + ) -> std::result::Result, tonic::Status>; + /// Fulfills a proof. + async fn fulfill_proof( + &self, + request: tonic::Request, + ) -> std::result::Result, tonic::Status>; + /// Get the proof requests the meet the filter criteria. + async fn get_filtered_proof_requests( + &self, + request: tonic::Request, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + >; + /// Get the status of a proof request. + async fn get_proof_request_status( + &self, + request: tonic::Request, + ) -> std::result::Result, tonic::Status>; + /// Get the balance of the account. + async fn get_balance( + &self, + request: tonic::Request, + ) -> std::result::Result, tonic::Status>; + /// Get the nonce of the account. + async fn get_nonce( + &self, + request: tonic::Request, + ) -> std::result::Result, tonic::Status>; + } + #[derive(Debug)] + pub struct ProverNetworkServer { + inner: Arc, + accept_compression_encodings: EnabledCompressionEncodings, + send_compression_encodings: EnabledCompressionEncodings, + max_decoding_message_size: Option, + max_encoding_message_size: Option, + } + impl ProverNetworkServer { + pub fn new(inner: T) -> Self { + Self::from_arc(Arc::new(inner)) + } + pub fn from_arc(inner: Arc) -> Self { + Self { + inner, + accept_compression_encodings: Default::default(), + send_compression_encodings: Default::default(), + max_decoding_message_size: None, + max_encoding_message_size: None, + } + } + pub fn with_interceptor(inner: T, interceptor: F) -> InterceptedService + where + F: tonic::service::Interceptor, + { + InterceptedService::new(Self::new(inner), interceptor) + } + /// Enable decompressing requests with the given encoding. + #[must_use] + pub fn accept_compressed(mut self, encoding: CompressionEncoding) -> Self { + self.accept_compression_encodings.enable(encoding); + self + } + /// Compress responses with the given encoding, if the client supports it. + #[must_use] + pub fn send_compressed(mut self, encoding: CompressionEncoding) -> Self { + self.send_compression_encodings.enable(encoding); + self + } + /// Limits the maximum size of a decoded message. + /// + /// Default: `4MB` + #[must_use] + pub fn max_decoding_message_size(mut self, limit: usize) -> Self { + self.max_decoding_message_size = Some(limit); + self + } + /// Limits the maximum size of an encoded message. + /// + /// Default: `usize::MAX` + #[must_use] + pub fn max_encoding_message_size(mut self, limit: usize) -> Self { + self.max_encoding_message_size = Some(limit); + self + } + } + impl tonic::codegen::Service> for ProverNetworkServer + where + T: ProverNetwork, + B: Body + std::marker::Send + 'static, + B::Error: Into + std::marker::Send + 'static, + { + type Response = http::Response; + type Error = std::convert::Infallible; + type Future = BoxFuture; + fn poll_ready( + &mut self, + _cx: &mut Context<'_>, + ) -> Poll> { + Poll::Ready(Ok(())) + } + fn call(&mut self, req: http::Request) -> Self::Future { + match req.uri().path() { + "/network.ProverNetwork/RequestProof" => { + #[allow(non_camel_case_types)] + struct RequestProofSvc(pub Arc); + impl tonic::server::UnaryService + for RequestProofSvc + { + type Response = super::RequestProofResponse; + type Future = BoxFuture, tonic::Status>; + fn call( + &mut self, + request: tonic::Request, + ) -> Self::Future { + let inner = Arc::clone(&self.0); + let fut = async move { + ::request_proof(&inner, request).await + }; + Box::pin(fut) + } + } + let accept_compression_encodings = self.accept_compression_encodings; + let send_compression_encodings = self.send_compression_encodings; + let max_decoding_message_size = self.max_decoding_message_size; + let max_encoding_message_size = self.max_encoding_message_size; + let inner = self.inner.clone(); + let fut = async move { + let method = RequestProofSvc(inner); + let codec = tonic::codec::ProstCodec::default(); + let mut grpc = tonic::server::Grpc::new(codec) + .apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ) + .apply_max_message_size_config( + max_decoding_message_size, + max_encoding_message_size, + ); + let res = grpc.unary(method, req).await; + Ok(res) + }; + Box::pin(fut) + } + "/network.ProverNetwork/FulfillProof" => { + #[allow(non_camel_case_types)] + struct FulfillProofSvc(pub Arc); + impl tonic::server::UnaryService + for FulfillProofSvc + { + type Response = super::FulfillProofResponse; + type Future = BoxFuture, tonic::Status>; + fn call( + &mut self, + request: tonic::Request, + ) -> Self::Future { + let inner = Arc::clone(&self.0); + let fut = async move { + ::fulfill_proof(&inner, request).await + }; + Box::pin(fut) + } + } + let accept_compression_encodings = self.accept_compression_encodings; + let send_compression_encodings = self.send_compression_encodings; + let max_decoding_message_size = self.max_decoding_message_size; + let max_encoding_message_size = self.max_encoding_message_size; + let inner = self.inner.clone(); + let fut = async move { + let method = FulfillProofSvc(inner); + let codec = tonic::codec::ProstCodec::default(); + let mut grpc = tonic::server::Grpc::new(codec) + .apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ) + .apply_max_message_size_config( + max_decoding_message_size, + max_encoding_message_size, + ); + let res = grpc.unary(method, req).await; + Ok(res) + }; + Box::pin(fut) + } + "/network.ProverNetwork/GetFilteredProofRequests" => { + #[allow(non_camel_case_types)] + struct GetFilteredProofRequestsSvc(pub Arc); + impl + tonic::server::UnaryService + for GetFilteredProofRequestsSvc + { + type Response = super::GetFilteredProofRequestsResponse; + type Future = BoxFuture, tonic::Status>; + fn call( + &mut self, + request: tonic::Request, + ) -> Self::Future { + let inner = Arc::clone(&self.0); + let fut = async move { + ::get_filtered_proof_requests(&inner, request) + .await + }; + Box::pin(fut) + } + } + let accept_compression_encodings = self.accept_compression_encodings; + let send_compression_encodings = self.send_compression_encodings; + let max_decoding_message_size = self.max_decoding_message_size; + let max_encoding_message_size = self.max_encoding_message_size; + let inner = self.inner.clone(); + let fut = async move { + let method = GetFilteredProofRequestsSvc(inner); + let codec = tonic::codec::ProstCodec::default(); + let mut grpc = tonic::server::Grpc::new(codec) + .apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ) + .apply_max_message_size_config( + max_decoding_message_size, + max_encoding_message_size, + ); + let res = grpc.unary(method, req).await; + Ok(res) + }; + Box::pin(fut) + } + "/network.ProverNetwork/GetProofRequestStatus" => { + #[allow(non_camel_case_types)] + struct GetProofRequestStatusSvc(pub Arc); + impl + tonic::server::UnaryService + for GetProofRequestStatusSvc + { + type Response = super::GetProofRequestStatusResponse; + type Future = BoxFuture, tonic::Status>; + fn call( + &mut self, + request: tonic::Request, + ) -> Self::Future { + let inner = Arc::clone(&self.0); + let fut = async move { + ::get_proof_request_status(&inner, request) + .await + }; + Box::pin(fut) + } + } + let accept_compression_encodings = self.accept_compression_encodings; + let send_compression_encodings = self.send_compression_encodings; + let max_decoding_message_size = self.max_decoding_message_size; + let max_encoding_message_size = self.max_encoding_message_size; + let inner = self.inner.clone(); + let fut = async move { + let method = GetProofRequestStatusSvc(inner); + let codec = tonic::codec::ProstCodec::default(); + let mut grpc = tonic::server::Grpc::new(codec) + .apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ) + .apply_max_message_size_config( + max_decoding_message_size, + max_encoding_message_size, + ); + let res = grpc.unary(method, req).await; + Ok(res) + }; + Box::pin(fut) + } + "/network.ProverNetwork/GetBalance" => { + #[allow(non_camel_case_types)] + struct GetBalanceSvc(pub Arc); + impl tonic::server::UnaryService for GetBalanceSvc { + type Response = super::GetBalanceResponse; + type Future = BoxFuture, tonic::Status>; + fn call( + &mut self, + request: tonic::Request, + ) -> Self::Future { + let inner = Arc::clone(&self.0); + let fut = async move { + ::get_balance(&inner, request).await + }; + Box::pin(fut) + } + } + let accept_compression_encodings = self.accept_compression_encodings; + let send_compression_encodings = self.send_compression_encodings; + let max_decoding_message_size = self.max_decoding_message_size; + let max_encoding_message_size = self.max_encoding_message_size; + let inner = self.inner.clone(); + let fut = async move { + let method = GetBalanceSvc(inner); + let codec = tonic::codec::ProstCodec::default(); + let mut grpc = tonic::server::Grpc::new(codec) + .apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ) + .apply_max_message_size_config( + max_decoding_message_size, + max_encoding_message_size, + ); + let res = grpc.unary(method, req).await; + Ok(res) + }; + Box::pin(fut) + } + "/network.ProverNetwork/GetNonce" => { + #[allow(non_camel_case_types)] + struct GetNonceSvc(pub Arc); + impl tonic::server::UnaryService for GetNonceSvc { + type Response = super::GetNonceResponse; + type Future = BoxFuture, tonic::Status>; + fn call( + &mut self, + request: tonic::Request, + ) -> Self::Future { + let inner = Arc::clone(&self.0); + let fut = async move { + ::get_nonce(&inner, request).await + }; + Box::pin(fut) + } + } + let accept_compression_encodings = self.accept_compression_encodings; + let send_compression_encodings = self.send_compression_encodings; + let max_decoding_message_size = self.max_decoding_message_size; + let max_encoding_message_size = self.max_encoding_message_size; + let inner = self.inner.clone(); + let fut = async move { + let method = GetNonceSvc(inner); + let codec = tonic::codec::ProstCodec::default(); + let mut grpc = tonic::server::Grpc::new(codec) + .apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ) + .apply_max_message_size_config( + max_decoding_message_size, + max_encoding_message_size, + ); + let res = grpc.unary(method, req).await; + Ok(res) + }; + Box::pin(fut) + } + _ => Box::pin(async move { + Ok(http::Response::builder() + .status(200) + .header("grpc-status", tonic::Code::Unimplemented as i32) + .header(http::header::CONTENT_TYPE, tonic::metadata::GRPC_CONTENT_TYPE) + .body(empty_body()) + .unwrap()) + }), + } + } + } + impl Clone for ProverNetworkServer { + fn clone(&self) -> Self { + let inner = self.inner.clone(); + Self { + inner, + accept_compression_encodings: self.accept_compression_encodings, + send_compression_encodings: self.send_compression_encodings, + max_decoding_message_size: self.max_decoding_message_size, + max_encoding_message_size: self.max_encoding_message_size, + } + } + } + /// Generated gRPC service name + pub const SERVICE_NAME: &str = "network.ProverNetwork"; + impl tonic::server::NamedService for ProverNetworkServer { + const NAME: &'static str = SERVICE_NAME; + } +} diff --git a/crates/sdk/src/network-v2/prover.rs b/crates/sdk/src/network-v2/prover.rs new file mode 100644 index 0000000000..19746b71bb --- /dev/null +++ b/crates/sdk/src/network-v2/prover.rs @@ -0,0 +1,216 @@ +use std::{ + env, + time::{Duration, Instant}, +}; + +use crate::{ + network_v2::client::{NetworkClient, DEFAULT_PROVER_NETWORK_RPC}, + network_v2::proto::network::{ProofMode, ProofStatus, ProofStrategy}, + Prover, SP1Context, SP1ProofKind, SP1ProofWithPublicValues, SP1ProvingKey, SP1VerifyingKey, +}; +use anyhow::Result; +use serde::de::DeserializeOwned; +use sp1_core_machine::io::SP1Stdin; +use sp1_prover::{components::DefaultProverComponents, SP1Prover, SP1_CIRCUIT_VERSION}; +use sp1_stark::SP1ProverOpts; + +use {crate::block_on, tokio::time::sleep}; + +use crate::provers::{CpuProver, ProofOpts, ProverType}; + +/// The timeout for a proof request to be fulfilled. +const TIMEOUT_SECS: u64 = 3600; + +/// The default cycle limit for a proof request. +const DEFAULT_CYCLE_LIMIT: u64 = 1_000_000_000; + +/// An implementation of [crate::ProverClient] that can generate proofs on a remote RPC server. +pub struct NetworkProver { + client: NetworkClient, + local_prover: CpuProver, +} + +impl NetworkProver { + /// Creates a new [NetworkProver] with the private key set in `SP1_PRIVATE_KEY`. + pub fn new() -> Self { + let private_key = env::var("SP1_PRIVATE_KEY") + .unwrap_or_else(|_| panic!("SP1_PRIVATE_KEY must be set for remote proving")); + Self::new_from_key(&private_key) + } + + /// Creates a new [NetworkProver] with the given private key. + pub fn new_from_key(private_key: &str) -> Self { + let version = SP1_CIRCUIT_VERSION; + log::info!("Client circuit version: {}", version); + let local_prover = CpuProver::new(); + let client = NetworkClient::new(private_key); + Self { client, local_prover } + } + + /// Requests a proof from the prover network, returning the request ID. + pub async fn request_proof( + &self, + elf: &[u8], + stdin: SP1Stdin, + mode: ProofMode, + timeout: Option, + ) -> Result> { + // Simulate and get the cycle limit. + let skip_simulation = env::var("SKIP_SIMULATION").map(|val| val == "true").unwrap_or(false); + let cycle_limit = if !skip_simulation { + let (_, report) = + self.local_prover.sp1_prover().execute(elf, &stdin, Default::default())?; + let cycles = report.total_instruction_count(); + log::info!("Simulation complete, cycles: {}", cycles); + cycles + } else { + log::info!("Skipping simulation"); + DEFAULT_CYCLE_LIMIT + }; + + // Get the verifying key. + let (_, vk) = self.setup(elf); + + // Get the timeout. + let timeout_secs = timeout.map(|dur| dur.as_secs()).unwrap_or(TIMEOUT_SECS); + + log::info!("Requesting proof with cycle limit: {}", cycle_limit); + + // Request the proof. + let response = self + .client + .request_proof( + elf, + &stdin, + &vk, + mode, + SP1_CIRCUIT_VERSION, + ProofStrategy::Hosted, + timeout_secs, + cycle_limit, + ) + .await?; + + // Log the request ID and transaction hash. + let tx_hash_hex = "0x".to_string() + &hex::encode(response.tx_hash); + let request_id = response.body.unwrap().request_id; + let request_id_hex = "0x".to_string() + &hex::encode(request_id.clone()); + log::info!("Created request {} in transaction {}", request_id_hex, tx_hash_hex); + + if NetworkClient::rpc_url() == DEFAULT_PROVER_NETWORK_RPC { + log::info!("View in explorer: https://explorer-v2.succinct.xyz/{}", request_id_hex); + } + + Ok(request_id) + } + + /// Waits for a proof to be generated and returns the proof. If a timeout is supplied, the + /// function will return an error if the proof is not generated within the timeout. + pub async fn wait_proof( + &self, + request_id: &[u8], + timeout: Option, + ) -> Result

{ + let mut is_assigned = false; + let start_time = Instant::now(); + loop { + if let Some(timeout) = timeout { + if start_time.elapsed() > timeout { + return Err(anyhow::anyhow!("Proof request timed out.")); + } + } + + let (status, maybe_proof) = + self.client.get_proof_request_status::

(request_id).await?; + + match status.status() { + ProofStatus::Fulfilled => { + return Ok(maybe_proof.unwrap()); + } + ProofStatus::Assigned => { + if !is_assigned { + log::info!("Proof request assigned, proving..."); + is_assigned = true; + } + } + _ => {} + } + sleep(Duration::from_secs(2)).await; + } + } + + /// Requests a proof from the prover network and waits for it to be generated. + pub async fn prove( + &self, + elf: &[u8], + stdin: SP1Stdin, + mode: ProofMode, + timeout: Option, + ) -> Result { + let request_id = self.request_proof(elf, stdin, mode, timeout).await?; + self.wait_proof(&request_id, timeout).await + } +} + +impl Prover for NetworkProver { + fn id(&self) -> ProverType { + ProverType::Network + } + + fn setup(&self, elf: &[u8]) -> (SP1ProvingKey, SP1VerifyingKey) { + self.local_prover.setup(elf) + } + + fn sp1_prover(&self) -> &SP1Prover { + self.local_prover.sp1_prover() + } + + fn prove<'a>( + &'a self, + pk: &SP1ProvingKey, + stdin: SP1Stdin, + opts: ProofOpts, + context: SP1Context<'a>, + kind: SP1ProofKind, + ) -> Result { + warn_if_not_default(&opts.sp1_prover_opts, &context); + block_on(self.prove(&pk.elf, stdin, kind.into(), opts.timeout)) + } +} + +impl Default for NetworkProver { + fn default() -> Self { + Self::new() + } +} + +/// Warns if `opts` or `context` are not default values, since they are currently unsupported. +fn warn_if_not_default(opts: &SP1ProverOpts, context: &SP1Context) { + let _guard = tracing::warn_span!("network_prover").entered(); + if opts != &SP1ProverOpts::default() { + tracing::warn!("non-default opts will be ignored: {:?}", opts.core_opts); + tracing::warn!("custom SP1ProverOpts are currently unsupported by the network prover"); + } + // Exhaustive match is done to ensure we update the warnings if the types change. + let SP1Context { hook_registry, subproof_verifier, .. } = context; + if hook_registry.is_some() { + tracing::warn!("non-default context.hook_registry will be ignored: {:?}", hook_registry); + tracing::warn!("custom runtime hooks are currently unsupported by the network prover"); + tracing::warn!("proving may fail due to missing hooks"); + } + if subproof_verifier.is_some() { + tracing::warn!("non-default context.subproof_verifier will be ignored"); + tracing::warn!("custom subproof verifiers are currently unsupported by the network prover"); + } +} + +impl From for ProofMode { + fn from(value: SP1ProofKind) -> Self { + match value { + SP1ProofKind::Core => Self::Core, + SP1ProofKind::Compressed => Self::Compressed, + SP1ProofKind::Plonk => Self::Plonk, + SP1ProofKind::Groth16 => Self::Groth16, + } + } +} diff --git a/crates/sdk/src/network-v2/sign_message.rs b/crates/sdk/src/network-v2/sign_message.rs new file mode 100644 index 0000000000..f8b794a5cb --- /dev/null +++ b/crates/sdk/src/network-v2/sign_message.rs @@ -0,0 +1,73 @@ +use alloy_primitives::{Address, Signature}; +use prost::Message; +use thiserror::Error; + +use crate::network_v2::proto::network::{FulfillProofRequest, RequestProofRequest}; + +#[allow(dead_code)] +pub trait SignedMessage { + fn signature(&self) -> Vec; + fn nonce(&self) -> Result; + fn message(&self) -> Result, MessageError>; + fn recover_sender(&self) -> Result; +} + +#[derive(Error, Debug)] +pub enum MessageError { + #[error("Empty message")] + EmptyMessage, +} + +#[derive(Error, Debug)] +pub enum RecoverSenderError { + #[error("Failed to deserialize signature: {0}")] + SignatureDeserializationError(String), + #[error("Empty message")] + EmptyMessage, + #[error("Failed to recover address: {0}")] + AddressRecoveryError(String), +} + +macro_rules! impl_signed_message { + ($type:ty) => { + impl SignedMessage for $type { + fn signature(&self) -> Vec { + self.signature.clone() + } + + fn nonce(&self) -> Result { + match &self.body { + Some(body) => Ok(body.nonce as u64), + None => Err(MessageError::EmptyMessage), + } + } + + fn message(&self) -> Result, MessageError> { + match &self.body { + Some(body) => Ok(body.encode_to_vec()), + None => Err(MessageError::EmptyMessage), + } + } + + fn recover_sender(&self) -> Result { + let message = self.message().map_err(|_| RecoverSenderError::EmptyMessage)?; + recover_sender_raw(self.signature.clone(), message) + } + } + }; +} + +impl_signed_message!(RequestProofRequest); +impl_signed_message!(FulfillProofRequest); + +pub fn recover_sender_raw( + signature: Vec, + message: Vec, +) -> Result { + let signature = Signature::try_from(signature.as_slice()) + .map_err(|e| RecoverSenderError::SignatureDeserializationError(e.to_string()))?; + + signature + .recover_address_from_msg(message) + .map_err(|e| RecoverSenderError::AddressRecoveryError(e.to_string())) +} diff --git a/crates/sdk/src/network/auth.rs b/crates/sdk/src/network/auth.rs index 7cb2c2ef7d..dbce5bb3e0 100644 --- a/crates/sdk/src/network/auth.rs +++ b/crates/sdk/src/network/auth.rs @@ -7,7 +7,7 @@ use ethers::{ types::H256, }; -use crate::proto::network::UnclaimReason; +use crate::network::proto::network::UnclaimReason; sol! { struct CreateProof { diff --git a/crates/sdk/src/network/client.rs b/crates/sdk/src/network/client.rs index f9bdd94ccd..893b5e6cca 100644 --- a/crates/sdk/src/network/client.rs +++ b/crates/sdk/src/network/client.rs @@ -2,7 +2,7 @@ use std::{env, time::Duration}; use crate::{ network::auth::NetworkAuth, - proto::network::{ + network::proto::network::{ ModifyCpuCyclesRequest, ModifyCpuCyclesResponse, UnclaimProofRequest, UnclaimReason, }, }; @@ -18,7 +18,7 @@ use std::{ }; use twirp::{Client as TwirpClient, ClientError}; -use crate::proto::network::{ +use crate::network::proto::network::{ ClaimProofRequest, ClaimProofResponse, CreateProofRequest, FulfillProofRequest, FulfillProofResponse, GetNonceRequest, GetProofRequestsRequest, GetProofRequestsResponse, GetProofStatusRequest, GetProofStatusResponse, NetworkServiceClient, ProofMode, ProofStatus, diff --git a/crates/sdk/src/network/mod.rs b/crates/sdk/src/network/mod.rs index 950aa10953..12d9b7b352 100644 --- a/crates/sdk/src/network/mod.rs +++ b/crates/sdk/src/network/mod.rs @@ -1,3 +1,6 @@ pub mod auth; pub mod client; pub mod prover; + +#[rustfmt::skip] +pub mod proto; diff --git a/crates/sdk/src/network/proto/mod.rs b/crates/sdk/src/network/proto/mod.rs new file mode 100644 index 0000000000..a61610bd4d --- /dev/null +++ b/crates/sdk/src/network/proto/mod.rs @@ -0,0 +1 @@ +pub mod network; diff --git a/crates/sdk/src/proto/network.rs b/crates/sdk/src/network/proto/network.rs similarity index 100% rename from crates/sdk/src/proto/network.rs rename to crates/sdk/src/network/proto/network.rs diff --git a/crates/sdk/src/network/prover.rs b/crates/sdk/src/network/prover.rs index d7561a123f..df7388d8e3 100644 --- a/crates/sdk/src/network/prover.rs +++ b/crates/sdk/src/network/prover.rs @@ -5,7 +5,7 @@ use std::{ use crate::{ network::client::{NetworkClient, DEFAULT_PROVER_NETWORK_RPC}, - proto::network::{ProofMode, ProofStatus}, + network::proto::network::{ProofMode, ProofStatus}, Prover, SP1Context, SP1ProofKind, SP1ProofWithPublicValues, SP1ProvingKey, SP1VerifyingKey, }; use anyhow::Result; @@ -14,7 +14,6 @@ use sp1_core_machine::io::SP1Stdin; use sp1_prover::{components::DefaultProverComponents, SP1Prover, SP1_CIRCUIT_VERSION}; use sp1_stark::SP1ProverOpts; -#[cfg(feature = "network")] use {crate::block_on, tokio::time::sleep}; use crate::provers::{CpuProver, ProofOpts, ProverType}; From 25ee7f2f7f979abaf2719b8b30b3a613288742c3 Mon Sep 17 00:00:00 2001 From: John Guibas Date: Tue, 8 Oct 2024 23:54:38 -0700 Subject: [PATCH 03/21] hm --- crates/prover/dummy_vk_map.bin | Bin 0 -> 400008 bytes crates/prover/src/lib.rs | 95 ++++++++++++++++++--------------- 2 files changed, 53 insertions(+), 42 deletions(-) create mode 100644 crates/prover/dummy_vk_map.bin diff --git a/crates/prover/dummy_vk_map.bin b/crates/prover/dummy_vk_map.bin new file mode 100644 index 0000000000000000000000000000000000000000..0e1a2eaaa0949271488dee332f44a2d68c128a72 GIT binary patch literal 400008 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 literal 0 HcmV?d00001 diff --git a/crates/prover/src/lib.rs b/crates/prover/src/lib.rs index 2d67042d99..c5cd570ff5 100644 --- a/crates/prover/src/lib.rs +++ b/crates/prover/src/lib.rs @@ -108,11 +108,13 @@ const CORE_CACHE_SIZE: usize = 5; const COMPRESS_CACHE_SIZE: usize = 3; pub const REDUCE_BATCH_SIZE: usize = 2; -const SHAPES_URL_PREFIX: &str = "https://sp1-circuits.s3.us-east-2.amazonaws.com/shapes"; -const SHAPES_VERSION: &str = "146079e0e"; -lazy_static! { - static ref SHAPES_INIT: Once = Once::new(); -} +// TODO: FIX +// +// const SHAPES_URL_PREFIX: &str = "https://sp1-circuits.s3.us-east-2.amazonaws.com/shapes"; +// const SHAPES_VERSION: &str = "146079e0e"; +// lazy_static! { +// static ref SHAPES_INIT: Once = Once::new(); +// } pub type CompressAir = RecursionAir; pub type ShrinkAir = RecursionAir; @@ -162,42 +164,46 @@ impl SP1Prover { /// Initializes a new [SP1Prover]. #[instrument(name = "initialize prover", level = "debug", skip_all)] pub fn new() -> Self { + // TODO: Enable + // // Initialize the shapes (only once). - SHAPES_INIT.call_once(|| { - let shapes_dir = Self::shapes_dir(); - if !shapes_dir.exists() { - std::fs::create_dir_all(&shapes_dir).expect("failed to create shapes directory"); - - let url = format!("{}-{}/allowed_vk_map.bin", SHAPES_URL_PREFIX, SHAPES_VERSION); - let allowed_vk_map_bytes = reqwest::blocking::get(url) - .expect("failed to download allowed_vk_map.bin") - .bytes() - .expect("failed to read response body"); - let allowed_vk_map_bytes = allowed_vk_map_bytes.as_ref().to_vec(); - std::fs::write(shapes_dir.join("allowed_vk_map.bin"), allowed_vk_map_bytes) - .unwrap(); - - let url = format!("{}-{}/dummy_vk_map.bin", SHAPES_URL_PREFIX, SHAPES_VERSION); - let dummy_vk_map_bytes = reqwest::blocking::get(url) - .expect("failed to download dummy_vk_map.bin") - .bytes() - .expect("failed to read response body"); - let dummy_vk_map_bytes = dummy_vk_map_bytes.as_ref().to_vec(); - std::fs::write(shapes_dir.join("dummy_vk_map.bin"), dummy_vk_map_bytes).unwrap(); - } - }); + // SHAPES_INIT.call_once(|| { + // let shapes_dir = Self::shapes_dir(); + // if !shapes_dir.exists() { + // std::fs::create_dir_all(&shapes_dir).expect("failed to create shapes directory"); + + // let url = format!("{}-{}/allowed_vk_map.bin", SHAPES_URL_PREFIX, SHAPES_VERSION); + // let allowed_vk_map_bytes = reqwest::blocking::get(url) + // .expect("failed to download allowed_vk_map.bin") + // .bytes() + // .expect("failed to read response body"); + // let allowed_vk_map_bytes = allowed_vk_map_bytes.as_ref().to_vec(); + // std::fs::write(shapes_dir.join("allowed_vk_map.bin"), allowed_vk_map_bytes) + // .unwrap(); + + // let url = format!("{}-{}/dummy_vk_map.bin", SHAPES_URL_PREFIX, SHAPES_VERSION); + // let dummy_vk_map_bytes = reqwest::blocking::get(url) + // .expect("failed to download dummy_vk_map.bin") + // .bytes() + // .expect("failed to read response body"); + // let dummy_vk_map_bytes = dummy_vk_map_bytes.as_ref().to_vec(); + // std::fs::write(shapes_dir.join("dummy_vk_map.bin"), dummy_vk_map_bytes).unwrap(); + // } + // }); Self::uninitialized() } - /// Get the shapes directory. - pub fn shapes_dir() -> PathBuf { - dirs::home_dir() - .expect("failed to get home directory") - .join(".sp1") - .join("shapes") - .join(SHAPES_VERSION) - } + // TODO: FIX + // + // Get the shapes directory. + // pub fn shapes_dir() -> PathBuf { + // dirs::home_dir() + // .expect("failed to get home directory") + // .join(".sp1") + // .join("shapes") + // .join(SHAPES_VERSION) + // } /// Creates a new [SP1Prover] with lazily initialized components. pub fn uninitialized() -> Self { @@ -248,13 +254,18 @@ impl SP1Prover { // Read the shapes from the shapes directory and deserialize them into memory. let allowed_vk_map: BTreeMap<[BabyBear; DIGEST_SIZE], usize> = if vk_verification { - let vk_allowed_map_bytes = - std::fs::read(Self::shapes_dir().join("allowed_vk_map.bin")).unwrap(); - bincode::deserialize(&vk_allowed_map_bytes).unwrap() + unreachable!() + // TODO: FIX + // + // let vk_allowed_map_bytes = + // std::fs::read(Self::shapes_dir().join("allowed_vk_map.bin")).unwrap(); + // bincode::deserialize(&vk_allowed_map_bytes).unwrap() } else { - let vk_dummy_map_bytes = - std::fs::read(Self::shapes_dir().join("dummy_vk_map.bin")).unwrap(); - bincode::deserialize(&vk_dummy_map_bytes).unwrap() + // TODO: FIX + // + // let vk_dummy_map_bytes = + // std::fs::read(Self::shapes_dir().join("dummy_vk_map.bin")).unwrap(); + bincode::deserialize(include_bytes!("../dummy_vk_map.bin")).unwrap() }; let (root, merkle_tree) = MerkleTree::commit(allowed_vk_map.keys().copied().collect()); From 3a045093d42c2007af07eb5cf3a4b0ea5a79be50 Mon Sep 17 00:00:00 2001 From: John Guibas Date: Tue, 8 Oct 2024 23:56:01 -0700 Subject: [PATCH 04/21] hm --- crates/prover/src/lib.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/crates/prover/src/lib.rs b/crates/prover/src/lib.rs index b811033e73..71a72ed4cc 100644 --- a/crates/prover/src/lib.rs +++ b/crates/prover/src/lib.rs @@ -18,7 +18,6 @@ pub mod types; pub mod utils; pub mod verify; -use std::path::PathBuf; use std::{ borrow::Borrow, collections::BTreeMap, @@ -39,7 +38,6 @@ use tracing::instrument; use p3_baby_bear::BabyBear; -use lazy_static::lazy_static; use p3_challenger::CanObserve; use p3_field::{AbstractField, PrimeField, PrimeField32}; use p3_matrix::dense::RowMajorMatrix; @@ -82,7 +80,6 @@ use sp1_stark::{ MachineProver, SP1CoreOpts, SP1ProverOpts, ShardProof, StarkGenericConfig, StarkVerifyingKey, Val, Word, DIGEST_SIZE, }; -use std::sync::Once; pub use types::*; use utils::{sp1_commited_values_digest_bn254, sp1_vkey_digest_bn254, words_to_bytes}; From 7952bac485085c794a92ffd81647d24652106411 Mon Sep 17 00:00:00 2001 From: umadayal Date: Wed, 9 Oct 2024 07:02:22 +0000 Subject: [PATCH 05/21] update cuda image --- crates/cuda/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/cuda/src/lib.rs b/crates/cuda/src/lib.rs index ed6e21f566..f08460042b 100644 --- a/crates/cuda/src/lib.rs +++ b/crates/cuda/src/lib.rs @@ -84,7 +84,7 @@ impl SP1CudaProver { /// [SP1ProverClient] that can be used to communicate with the container. pub fn new() -> Result> { let container_name = "sp1-gpu"; - let image_name = "public.ecr.aws/succinct-labs/sp1-gpu:a4e646b"; + let image_name = "public.ecr.aws/succinct-labs/sp1-gpu:8e355ce"; let cleaned_up = Arc::new(AtomicBool::new(false)); let cleanup_name = container_name; From 0dbbb8ddf525762304acdc61f4929e074ae405cb Mon Sep 17 00:00:00 2001 From: umadayal Date: Wed, 9 Oct 2024 07:02:43 +0000 Subject: [PATCH 06/21] hm --- crates/perf/workflow.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/perf/workflow.sh b/crates/perf/workflow.sh index 968a38d77f..e14e08b805 100755 --- a/crates/perf/workflow.sh +++ b/crates/perf/workflow.sh @@ -76,4 +76,4 @@ WORKLOADS=$(jq -n \ '{cpu_workloads: $cpu, cuda_workloads: $cuda, network_workloads: $network}') # Run the workflow with the list of workloads. -echo $WORKLOADS | gh workflow run suite.yml --ref $GIT_REF --json \ No newline at end of file +echo $WORKLOADS | gh workflow run suite.yml --ref $GIT_REF --json From e80b093ec6425d99d63055b2467641e3387ccd55 Mon Sep 17 00:00:00 2001 From: John Guibas Date: Wed, 9 Oct 2024 00:31:19 -0700 Subject: [PATCH 07/21] hmmm --- .github/workflows/suite.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/suite.yml b/.github/workflows/suite.yml index a394243103..4ff3e7fd15 100644 --- a/.github/workflows/suite.yml +++ b/.github/workflows/suite.yml @@ -138,4 +138,4 @@ jobs: RUST_BACKTRACE: 1 SP1_PROVER: network SP1_PRIVATE_KEY: ${{ secrets.SP1_PRIVATE_KEY }} - PROVER_NETWORK_RPC: https://rpc-staging.succinct.xyz \ No newline at end of file + PROVER_NETWORK_RPC: https://rpc-taiko.succinct.xyz \ No newline at end of file From 12d7eb22faecee59d68159d395dd556e84a0b1cf Mon Sep 17 00:00:00 2001 From: John Guibas Date: Wed, 9 Oct 2024 01:30:32 -0700 Subject: [PATCH 08/21] rc3 --- Cargo.toml | 2 +- crates/perf/workflow.sh | 54 ++++++++++++++++++++--------------------- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 2f8317616e..d9da3ac499 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [workspace.package] -version = "2.0.0" +version = "3.0.0-rc3" edition = "2021" license = "MIT OR Apache-2.0" repository = "https://github.com/succinctlabs/sp1" diff --git a/crates/perf/workflow.sh b/crates/perf/workflow.sh index e14e08b805..d9c7cdbde1 100755 --- a/crates/perf/workflow.sh +++ b/crates/perf/workflow.sh @@ -24,26 +24,6 @@ CPU_WORKLOADS=( # Define the list of CUDA workloads. CUDA_WORKLOADS=( - "fibonacci-17k" - "ssz-withdrawals" - "tendermint" - "rsp-20526624" - "rsa" - "regex" - "chess" - "json" - "blobstream-01j6z63fgafrc8jeh0k12gbtvw" - "blobstream-01j6z95bdme9svevmfyc974bja" - "blobstream-01j6z9ak0ke9srsppgywgke6fj" - "vector-01j6xsv35re96tkgyda115320t" - "vector-01j6xzy366ff5tbkzcrs8pma02" - "vector-01j6y06de0fdaafemr8b1t69z3" - "raiko-a7-10" - "op-succinct-op-sepolia-range-17985900-17985905" -) - -# Define the list of network workloads. -NETWORK_WORKLOADS=( # "fibonacci-17k" # "ssz-withdrawals" # "tendermint" @@ -58,14 +38,34 @@ NETWORK_WORKLOADS=( # "vector-01j6xsv35re96tkgyda115320t" # "vector-01j6xzy366ff5tbkzcrs8pma02" # "vector-01j6y06de0fdaafemr8b1t69z3" - # "raiko-a7-10" - # "op-succinct-op-sepolia-1818303090-18303120" - # "op-succinct-op-sepolia-18200000-18200030" - # "op-succinct-op-sepolia-18250000-18250030" - # "op-succinct-op-sepolia-18303044-18303074" - # "op-succinct-op-sepolia-range-17685896-17685897" + # "raiko-a7-10" # "op-succinct-op-sepolia-range-17985900-17985905" - # "op-succinct-op-sepolia-range-18129400-18129401" +) + +# Define the list of network workloads. +NETWORK_WORKLOADS=( + "fibonacci-17k" + "ssz-withdrawals" + "tendermint" + "rsp-20526624" + "rsa" + "regex" + "chess" + "json" + "blobstream-01j6z63fgafrc8jeh0k12gbtvw" + "blobstream-01j6z95bdme9svevmfyc974bja" + "blobstream-01j6z9ak0ke9srsppgywgke6fj" + "vector-01j6xsv35re96tkgyda115320t" + "vector-01j6xzy366ff5tbkzcrs8pma02" + "vector-01j6y06de0fdaafemr8b1t69z3" + "raiko-a7-10" + "op-succinct-op-sepolia-1818303090-18303120" + "op-succinct-op-sepolia-18200000-18200030" + "op-succinct-op-sepolia-18250000-18250030" + "op-succinct-op-sepolia-18303044-18303074" + "op-succinct-op-sepolia-range-17685896-17685897" + "op-succinct-op-sepolia-range-17985900-17985905" + "op-succinct-op-sepolia-range-18129400-18129401" ) # Create a JSON object with the list of workloads. From c9c800bd4850c3401ec083e53e017e3e3a653c4a Mon Sep 17 00:00:00 2001 From: John Guibas Date: Wed, 9 Oct 2024 02:10:52 -0700 Subject: [PATCH 09/21] use faster builder --- .github/workflows/docker-publish-gnark.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/docker-publish-gnark.yml b/.github/workflows/docker-publish-gnark.yml index 34be51d005..74df824a25 100644 --- a/.github/workflows/docker-publish-gnark.yml +++ b/.github/workflows/docker-publish-gnark.yml @@ -21,7 +21,13 @@ env: jobs: container: - runs-on: ubuntu-latest + runs-on: + [ + runs-on, + runner=64cpu-linux-arm64, + spot=false, + "run-id=${{ github.run_id }}", + ] # https://docs.github.com/en/actions/reference/authentication-in-a-workflow permissions: id-token: write From d2610cfe59e0c11a82cfdab77070505aa2f82dba Mon Sep 17 00:00:00 2001 From: John Guibas Date: Wed, 9 Oct 2024 02:14:30 -0700 Subject: [PATCH 10/21] fix sp1 versions --- Cargo.lock | 44 ++++++++++++++++++++++---------------------- Cargo.toml | 40 ++++++++++++++++++++-------------------- 2 files changed, 42 insertions(+), 42 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 25239b5164..a52cca5341 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5693,7 +5693,7 @@ dependencies = [ [[package]] name = "sp1-build" -version = "2.0.0" +version = "3.0.0-rc3" dependencies = [ "anyhow", "cargo_metadata", @@ -5704,7 +5704,7 @@ dependencies = [ [[package]] name = "sp1-cli" -version = "2.0.0" +version = "3.0.0-rc3" dependencies = [ "anstyle", "anyhow", @@ -5732,7 +5732,7 @@ dependencies = [ [[package]] name = "sp1-core-executor" -version = "2.0.0" +version = "3.0.0-rc3" dependencies = [ "bincode", "bytemuck", @@ -5765,7 +5765,7 @@ dependencies = [ [[package]] name = "sp1-core-machine" -version = "2.0.0" +version = "3.0.0-rc3" dependencies = [ "bincode", "cfg-if", @@ -5814,7 +5814,7 @@ dependencies = [ [[package]] name = "sp1-cuda" -version = "2.0.0" +version = "3.0.0-rc3" dependencies = [ "bincode", "ctrlc", @@ -5831,7 +5831,7 @@ dependencies = [ [[package]] name = "sp1-curves" -version = "2.0.0" +version = "3.0.0-rc3" dependencies = [ "cfg-if", "curve25519-dalek", @@ -5853,7 +5853,7 @@ dependencies = [ [[package]] name = "sp1-derive" -version = "2.0.0" +version = "3.0.0-rc3" dependencies = [ "quote", "syn 1.0.109", @@ -5861,7 +5861,7 @@ dependencies = [ [[package]] name = "sp1-eval" -version = "2.0.0" +version = "3.0.0-rc3" dependencies = [ "anyhow", "bincode", @@ -5881,14 +5881,14 @@ dependencies = [ [[package]] name = "sp1-helper" -version = "2.0.0" +version = "3.0.0-rc3" dependencies = [ "sp1-build", ] [[package]] name = "sp1-lib" -version = "2.0.0" +version = "3.0.0-rc3" dependencies = [ "bincode", "serde", @@ -5896,7 +5896,7 @@ dependencies = [ [[package]] name = "sp1-perf" -version = "2.0.0" +version = "3.0.0-rc3" dependencies = [ "anyhow", "bincode", @@ -5917,7 +5917,7 @@ dependencies = [ [[package]] name = "sp1-primitives" -version = "2.0.0" +version = "3.0.0-rc3" dependencies = [ "bincode", "hex", @@ -5933,7 +5933,7 @@ dependencies = [ [[package]] name = "sp1-prover" -version = "2.0.0" +version = "3.0.0-rc3" dependencies = [ "anyhow", "bincode", @@ -5973,7 +5973,7 @@ dependencies = [ [[package]] name = "sp1-recursion-circuit" -version = "2.0.0" +version = "3.0.0-rc3" dependencies = [ "ff 0.13.0", "hashbrown 0.14.5", @@ -6009,7 +6009,7 @@ dependencies = [ [[package]] name = "sp1-recursion-compiler" -version = "2.0.0" +version = "3.0.0-rc3" dependencies = [ "backtrace", "criterion", @@ -6034,7 +6034,7 @@ dependencies = [ [[package]] name = "sp1-recursion-core" -version = "2.0.0" +version = "3.0.0-rc3" dependencies = [ "backtrace", "ff 0.13.0", @@ -6069,7 +6069,7 @@ dependencies = [ [[package]] name = "sp1-recursion-derive" -version = "2.0.0" +version = "3.0.0-rc3" dependencies = [ "quote", "syn 1.0.109", @@ -6077,7 +6077,7 @@ dependencies = [ [[package]] name = "sp1-recursion-gnark-cli" -version = "2.0.0" +version = "3.0.0-rc3" dependencies = [ "bincode", "clap", @@ -6086,7 +6086,7 @@ dependencies = [ [[package]] name = "sp1-recursion-gnark-ffi" -version = "2.0.0" +version = "3.0.0-rc3" dependencies = [ "anyhow", "bincode", @@ -6110,7 +6110,7 @@ dependencies = [ [[package]] name = "sp1-sdk" -version = "2.0.0" +version = "3.0.0-rc3" dependencies = [ "alloy-sol-types", "anyhow", @@ -6150,7 +6150,7 @@ dependencies = [ [[package]] name = "sp1-stark" -version = "2.0.0" +version = "3.0.0-rc3" dependencies = [ "arrayref", "getrandom 0.2.15", @@ -6185,7 +6185,7 @@ dependencies = [ [[package]] name = "sp1-zkvm" -version = "2.0.0" +version = "3.0.0-rc3" dependencies = [ "cfg-if", "getrandom 0.2.15", diff --git a/Cargo.toml b/Cargo.toml index d9da3ac499..4c6d44ef34 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -46,26 +46,26 @@ debug-assertions = true [workspace.dependencies] # sp1 -sp1-build = { path = "crates/build", version = "2.0.0" } -sp1-cli = { path = "crates/cli", version = "2.0.0", default-features = false } -sp1-core-machine = { path = "crates/core/machine", version = "2.0.0" } -sp1-core-executor = { path = "crates/core/executor", version = "2.0.0" } -sp1-curves = { path = "crates/curves", version = "2.0.0" } -sp1-derive = { path = "crates/derive", version = "2.0.0" } -sp1-eval = { path = "crates/eval", version = "2.0.0" } -sp1-helper = { path = "crates/helper", version = "2.0.0", default-features = false } -sp1-primitives = { path = "crates/primitives", version = "2.0.0" } -sp1-prover = { path = "crates/prover", version = "2.0.0" } -sp1-recursion-compiler = { path = "crates/recursion/compiler", version = "2.0.0" } -sp1-recursion-core = { path = "crates/recursion/core", version = "2.0.0", default-features = false } -sp1-recursion-derive = { path = "crates/recursion/derive", version = "2.0.0", default-features = false } -sp1-recursion-gnark-ffi = { path = "crates/recursion/gnark-ffi", version = "2.0.0", default-features = false } -sp1-recursion-circuit = { path = "crates/recursion/circuit", version = "2.0.0", default-features = false } -sp1-sdk = { path = "crates/sdk", version = "2.0.0" } -sp1-cuda = { path = "crates/cuda", version = "2.0.0" } -sp1-stark = { path = "crates/stark", version = "2.0.0" } -sp1-lib = { path = "crates/zkvm/lib", version = "2.0.0", default-features = false } -sp1-zkvm = { path = "crates/zkvm/entrypoint", version = "2.0.0", default-features = false } +sp1-build = { path = "crates/build", version = "3.0.0-rc3" } +sp1-cli = { path = "crates/cli", version = "3.0.0-rc3", default-features = false } +sp1-core-machine = { path = "crates/core/machine", version = "3.0.0-rc3" } +sp1-core-executor = { path = "crates/core/executor", version = "3.0.0-rc3" } +sp1-curves = { path = "crates/curves", version = "3.0.0-rc3" } +sp1-derive = { path = "crates/derive", version = "3.0.0-rc3" } +sp1-eval = { path = "crates/eval", version = "3.0.0-rc3" } +sp1-helper = { path = "crates/helper", version = "3.0.0-rc3", default-features = false } +sp1-primitives = { path = "crates/primitives", version = "3.0.0-rc3" } +sp1-prover = { path = "crates/prover", version = "3.0.0-rc3" } +sp1-recursion-compiler = { path = "crates/recursion/compiler", version = "3.0.0-rc3" } +sp1-recursion-core = { path = "crates/recursion/core", version = "3.0.0-rc3", default-features = false } +sp1-recursion-derive = { path = "crates/recursion/derive", version = "3.0.0-rc3", default-features = false } +sp1-recursion-gnark-ffi = { path = "crates/recursion/gnark-ffi", version = "3.0.0-rc3", default-features = false } +sp1-recursion-circuit = { path = "crates/recursion/circuit", version = "3.0.0-rc3", default-features = false } +sp1-sdk = { path = "crates/sdk", version = "3.0.0-rc3" } +sp1-cuda = { path = "crates/cuda", version = "3.0.0-rc3" } +sp1-stark = { path = "crates/stark", version = "3.0.0-rc3" } +sp1-lib = { path = "crates/zkvm/lib", version = "3.0.0-rc3", default-features = false } +sp1-zkvm = { path = "crates/zkvm/entrypoint", version = "3.0.0-rc3", default-features = false } # p3 p3-air = "0.1.4-succinct" From e2cc4bc0c5030c35a59bada8670e34b9ed358d3b Mon Sep 17 00:00:00 2001 From: John Guibas Date: Wed, 9 Oct 2024 02:22:02 -0700 Subject: [PATCH 11/21] x86 --- .github/workflows/docker-publish-gnark.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docker-publish-gnark.yml b/.github/workflows/docker-publish-gnark.yml index 74df824a25..3d4185b9ab 100644 --- a/.github/workflows/docker-publish-gnark.yml +++ b/.github/workflows/docker-publish-gnark.yml @@ -24,7 +24,7 @@ jobs: runs-on: [ runs-on, - runner=64cpu-linux-arm64, + runner=64cpu-linux-x64, spot=false, "run-id=${{ github.run_id }}", ] @@ -96,7 +96,7 @@ jobs: with: context: . file: ./Dockerfile.gnark-ffi - platforms: linux/amd64,linux/arm64 + platforms: linux/amd64 push: true tags: ${{ steps.docker_tagging.outputs.docker_tags }} labels: ${{ steps.meta.outputs.labels }} From 254c5354f45c7dfe7c23b41bd77a51379fe333f4 Mon Sep 17 00:00:00 2001 From: John Guibas Date: Wed, 9 Oct 2024 02:22:14 -0700 Subject: [PATCH 12/21] simulate arm in x86 --- .github/workflows/docker-publish-gnark.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker-publish-gnark.yml b/.github/workflows/docker-publish-gnark.yml index 3d4185b9ab..f3f24d2b4e 100644 --- a/.github/workflows/docker-publish-gnark.yml +++ b/.github/workflows/docker-publish-gnark.yml @@ -96,7 +96,7 @@ jobs: with: context: . file: ./Dockerfile.gnark-ffi - platforms: linux/amd64 + platforms: linux/amd64,linux/arm64 push: true tags: ${{ steps.docker_tagging.outputs.docker_tags }} labels: ${{ steps.meta.outputs.labels }} From 456c1eec05a467e06bee9d5845334d2502b179f7 Mon Sep 17 00:00:00 2001 From: John Guibas Date: Wed, 9 Oct 2024 03:13:48 -0700 Subject: [PATCH 13/21] remove arm --- .github/workflows/docker-publish-gnark.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker-publish-gnark.yml b/.github/workflows/docker-publish-gnark.yml index f3f24d2b4e..3d4185b9ab 100644 --- a/.github/workflows/docker-publish-gnark.yml +++ b/.github/workflows/docker-publish-gnark.yml @@ -96,7 +96,7 @@ jobs: with: context: . file: ./Dockerfile.gnark-ffi - platforms: linux/amd64,linux/arm64 + platforms: linux/amd64 push: true tags: ${{ steps.docker_tagging.outputs.docker_tags }} labels: ${{ steps.meta.outputs.labels }} From c69208d303cef85dfa6a6a01f81ef93a8f796e42 Mon Sep 17 00:00:00 2001 From: John Guibas Date: Wed, 9 Oct 2024 03:19:04 -0700 Subject: [PATCH 14/21] run main ci on branch --- .github/workflows/main.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 251c44d529..2afe4bdb4f 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -4,6 +4,7 @@ on: pull_request: branches: - main + - tamir/v1.3.0-rc2 paths: - "crates/**" - "Cargo.toml" From cc255844565f78bd7903916a4e8be2e06722ad9d Mon Sep 17 00:00:00 2001 From: John Guibas Date: Wed, 9 Oct 2024 11:55:25 -0700 Subject: [PATCH 15/21] update docker build system --- .github/workflows/docker-publish-gnark.yml | 89 +++++++++++++++++++++- 1 file changed, 88 insertions(+), 1 deletion(-) diff --git a/.github/workflows/docker-publish-gnark.yml b/.github/workflows/docker-publish-gnark.yml index 3d4185b9ab..e6f32e127b 100644 --- a/.github/workflows/docker-publish-gnark.yml +++ b/.github/workflows/docker-publish-gnark.yml @@ -20,7 +20,7 @@ env: IMAGE_NAME: succinctlabs/sp1-gnark jobs: - container: + build-amd64: runs-on: [ runs-on, @@ -106,3 +106,90 @@ jobs: BUILDTIME=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.created'] }} VERSION=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.version'] }} REVISION=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.revision'] }} + + build-arm64: + runs-on: + [ + runs-on, + runner=64cpu-linux-arm64, + spot=false, + "run-id=${{ github.run_id }}", + ] + # https://docs.github.com/en/actions/reference/authentication-in-a-workflow + permissions: + id-token: write + packages: write + contents: read + timeout-minutes: 120 + steps: + - name: Checkout repository + id: checkout + uses: actions/checkout@v4 + + - name: Install Docker BuildX + uses: docker/setup-buildx-action@v3 + id: buildx + with: + install: true + + # Login against a Docker registry except on PR + # https://github.com/docker/login-action + - name: Log into registry ${{ env.REGISTRY }} + # Ensure this doesn't trigger on PR's + if: github.event_name != 'pull_request' + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + # Extract metadata (tags, labels) for Docker + # https://github.com/docker/metadata-action + - name: Extract Docker metadata + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + + # Creates an additional 'latest' or 'nightly' tag + # If the job is triggered via cron schedule, tag nightly and nightly-{SHA} + # If the job is triggered via workflow dispatch and on a master branch, tag branch and latest + # Otherwise, just tag as the branch name + - name: Finalize Docker Metadata + id: docker_tagging + run: | + if [[ "${{ github.event_name }}" == 'workflow_dispatch' ]]; then + echo "manual trigger from workflow_dispatch, assigning tag ${{ github.event.inputs.tags }}" + echo "docker_tags=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.event.inputs.tags }}" >> $GITHUB_OUTPUT + elif [[ "${{ github.event_name }}" == 'schedule' ]]; then + echo "cron trigger, assigning nightly tag" + echo "docker_tags=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:nightly,${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:nightly-${GITHUB_SHA}" >> $GITHUB_OUTPUT + else + echo "Neither scheduled nor manual release from main branch. Just tagging as branch name" + echo "docker_tags=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${GITHUB_REF##*/}" >> $GITHUB_OUTPUT + fi + + # Log docker metadata to explicitly know what is being pushed + - name: Inspect Docker Metadata + run: | + echo "TAGS -> ${{ steps.docker_tagging.outputs.docker_tags }}" + echo "LABELS -> ${{ steps.meta.outputs.labels }}" + + # Build and push Docker image + # https://github.com/docker/build-push-action + # https://github.com/docker/build-push-action/blob/master/docs/advanced/cache.md + - name: Build and push Docker image + uses: docker/build-push-action@v6 + with: + context: . + file: ./Dockerfile.gnark-ffi + platforms: linux/arm64 + push: true + tags: ${{ steps.docker_tagging.outputs.docker_tags }} + labels: ${{ steps.meta.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max + build-args: | + BUILDTIME=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.created'] }} + VERSION=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.version'] }} + REVISION=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.revision'] }} From ae65e880af02e4a9971e7dae56ff3bcb97bc42cc Mon Sep 17 00:00:00 2001 From: John Guibas Date: Wed, 9 Oct 2024 12:11:36 -0700 Subject: [PATCH 16/21] new workflow --- .github/workflows/docker-publish-gnark.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/docker-publish-gnark.yml b/.github/workflows/docker-publish-gnark.yml index e6f32e127b..d6f08b4e16 100644 --- a/.github/workflows/docker-publish-gnark.yml +++ b/.github/workflows/docker-publish-gnark.yml @@ -96,7 +96,6 @@ jobs: with: context: . file: ./Dockerfile.gnark-ffi - platforms: linux/amd64 push: true tags: ${{ steps.docker_tagging.outputs.docker_tags }} labels: ${{ steps.meta.outputs.labels }} @@ -183,7 +182,6 @@ jobs: with: context: . file: ./Dockerfile.gnark-ffi - platforms: linux/arm64 push: true tags: ${{ steps.docker_tagging.outputs.docker_tags }} labels: ${{ steps.meta.outputs.labels }} From c587ac5c3fd9229b831b7a05b59fbbccf8bf93b9 Mon Sep 17 00:00:00 2001 From: John Guibas Date: Wed, 9 Oct 2024 12:16:39 -0700 Subject: [PATCH 17/21] specific platform --- .github/workflows/docker-publish-gnark.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/docker-publish-gnark.yml b/.github/workflows/docker-publish-gnark.yml index d6f08b4e16..e6f32e127b 100644 --- a/.github/workflows/docker-publish-gnark.yml +++ b/.github/workflows/docker-publish-gnark.yml @@ -96,6 +96,7 @@ jobs: with: context: . file: ./Dockerfile.gnark-ffi + platforms: linux/amd64 push: true tags: ${{ steps.docker_tagging.outputs.docker_tags }} labels: ${{ steps.meta.outputs.labels }} @@ -182,6 +183,7 @@ jobs: with: context: . file: ./Dockerfile.gnark-ffi + platforms: linux/arm64 push: true tags: ${{ steps.docker_tagging.outputs.docker_tags }} labels: ${{ steps.meta.outputs.labels }} From ffdcb606bdbab468510f5cbe350d0a9ba1d01f17 Mon Sep 17 00:00:00 2001 From: John Guibas Date: Wed, 9 Oct 2024 12:42:12 -0700 Subject: [PATCH 18/21] create manifest --- .github/workflows/docker-publish-gnark.yml | 169 +++++---------------- 1 file changed, 38 insertions(+), 131 deletions(-) diff --git a/.github/workflows/docker-publish-gnark.yml b/.github/workflows/docker-publish-gnark.yml index e6f32e127b..75dfaee566 100644 --- a/.github/workflows/docker-publish-gnark.yml +++ b/.github/workflows/docker-publish-gnark.yml @@ -1,5 +1,4 @@ -# Source: https://raw.githubusercontent.com/foundry-rs/foundry/master/.github/workflows/docker-publish.yml -name: docker-gnark +ame: docker-gnark on: push: @@ -7,7 +6,6 @@ on: - "v*.*.*" schedule: - cron: "0 0 * * *" - # Trigger without any parameters a proactive rebuild workflow_dispatch: inputs: tags: @@ -21,175 +19,84 @@ env: jobs: build-amd64: - runs-on: - [ - runs-on, - runner=64cpu-linux-x64, - spot=false, - "run-id=${{ github.run_id }}", - ] - # https://docs.github.com/en/actions/reference/authentication-in-a-workflow + runs-on: [runs-on, runner=64cpu-linux-x64, spot=false, "run-id=${{ github.run_id }}"] permissions: id-token: write packages: write contents: read - timeout-minutes: 120 steps: - name: Checkout repository - id: checkout uses: actions/checkout@v4 - - - name: Install Docker BuildX + - name: Set up Docker BuildX uses: docker/setup-buildx-action@v3 - id: buildx - with: - install: true - - # Login against a Docker registry except on PR - # https://github.com/docker/login-action - name: Log into registry ${{ env.REGISTRY }} - # Ensure this doesn't trigger on PR's - if: github.event_name != 'pull_request' uses: docker/login-action@v3 with: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - # Extract metadata (tags, labels) for Docker - # https://github.com/docker/metadata-action - - name: Extract Docker metadata - id: meta - uses: docker/metadata-action@v5 - with: - images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} - - # Creates an additional 'latest' or 'nightly' tag - # If the job is triggered via cron schedule, tag nightly and nightly-{SHA} - # If the job is triggered via workflow dispatch and on a master branch, tag branch and latest - # Otherwise, just tag as the branch name - - name: Finalize Docker Metadata - id: docker_tagging - run: | - if [[ "${{ github.event_name }}" == 'workflow_dispatch' ]]; then - echo "manual trigger from workflow_dispatch, assigning tag ${{ github.event.inputs.tags }}" - echo "docker_tags=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.event.inputs.tags }}" >> $GITHUB_OUTPUT - elif [[ "${{ github.event_name }}" == 'schedule' ]]; then - echo "cron trigger, assigning nightly tag" - echo "docker_tags=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:nightly,${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:nightly-${GITHUB_SHA}" >> $GITHUB_OUTPUT - else - echo "Neither scheduled nor manual release from main branch. Just tagging as branch name" - echo "docker_tags=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${GITHUB_REF##*/}" >> $GITHUB_OUTPUT - fi - - # Log docker metadata to explicitly know what is being pushed - - name: Inspect Docker Metadata - run: | - echo "TAGS -> ${{ steps.docker_tagging.outputs.docker_tags }}" - echo "LABELS -> ${{ steps.meta.outputs.labels }}" - - # Build and push Docker image - # https://github.com/docker/build-push-action - # https://github.com/docker/build-push-action/blob/master/docs/advanced/cache.md - - name: Build and push Docker image - uses: docker/build-push-action@v6 + - name: Build and push AMD64 image + uses: docker/build-push-action@v5 with: context: . file: ./Dockerfile.gnark-ffi platforms: linux/amd64 push: true - tags: ${{ steps.docker_tagging.outputs.docker_tags }} - labels: ${{ steps.meta.outputs.labels }} + tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }}-amd64 cache-from: type=gha cache-to: type=gha,mode=max - build-args: | - BUILDTIME=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.created'] }} - VERSION=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.version'] }} - REVISION=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.revision'] }} build-arm64: - runs-on: - [ - runs-on, - runner=64cpu-linux-arm64, - spot=false, - "run-id=${{ github.run_id }}", - ] - # https://docs.github.com/en/actions/reference/authentication-in-a-workflow + runs-on: [runs-on, runner=64cpu-linux-arm64, spot=false, "run-id=${{ github.run_id }}"] permissions: id-token: write packages: write contents: read - timeout-minutes: 120 steps: - name: Checkout repository - id: checkout uses: actions/checkout@v4 - - - name: Install Docker BuildX + - name: Set up Docker BuildX uses: docker/setup-buildx-action@v3 - id: buildx - with: - install: true - - # Login against a Docker registry except on PR - # https://github.com/docker/login-action - name: Log into registry ${{ env.REGISTRY }} - # Ensure this doesn't trigger on PR's - if: github.event_name != 'pull_request' uses: docker/login-action@v3 with: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - # Extract metadata (tags, labels) for Docker - # https://github.com/docker/metadata-action - - name: Extract Docker metadata - id: meta - uses: docker/metadata-action@v5 - with: - images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} - - # Creates an additional 'latest' or 'nightly' tag - # If the job is triggered via cron schedule, tag nightly and nightly-{SHA} - # If the job is triggered via workflow dispatch and on a master branch, tag branch and latest - # Otherwise, just tag as the branch name - - name: Finalize Docker Metadata - id: docker_tagging - run: | - if [[ "${{ github.event_name }}" == 'workflow_dispatch' ]]; then - echo "manual trigger from workflow_dispatch, assigning tag ${{ github.event.inputs.tags }}" - echo "docker_tags=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.event.inputs.tags }}" >> $GITHUB_OUTPUT - elif [[ "${{ github.event_name }}" == 'schedule' ]]; then - echo "cron trigger, assigning nightly tag" - echo "docker_tags=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:nightly,${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:nightly-${GITHUB_SHA}" >> $GITHUB_OUTPUT - else - echo "Neither scheduled nor manual release from main branch. Just tagging as branch name" - echo "docker_tags=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${GITHUB_REF##*/}" >> $GITHUB_OUTPUT - fi - - # Log docker metadata to explicitly know what is being pushed - - name: Inspect Docker Metadata - run: | - echo "TAGS -> ${{ steps.docker_tagging.outputs.docker_tags }}" - echo "LABELS -> ${{ steps.meta.outputs.labels }}" - - # Build and push Docker image - # https://github.com/docker/build-push-action - # https://github.com/docker/build-push-action/blob/master/docs/advanced/cache.md - - name: Build and push Docker image - uses: docker/build-push-action@v6 + - name: Build and push ARM64 image + uses: docker/build-push-action@v5 with: context: . file: ./Dockerfile.gnark-ffi platforms: linux/arm64 push: true - tags: ${{ steps.docker_tagging.outputs.docker_tags }} - labels: ${{ steps.meta.outputs.labels }} + tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }}-arm64 cache-from: type=gha cache-to: type=gha,mode=max - build-args: | - BUILDTIME=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.created'] }} - VERSION=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.version'] }} - REVISION=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.revision'] }} + + create-manifest: + needs: [build-amd64, build-arm64] + runs-on: ubuntu-latest + steps: + - name: Log into registry ${{ env.REGISTRY }} + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + - name: Create and push manifest + run: | + TAGS="" + if [[ "${{ github.event_name }}" == 'workflow_dispatch' ]]; then + TAGS="${{ github.event.inputs.tags }}" + elif [[ "${{ github.event_name }}" == 'schedule' ]]; then + TAGS="nightly nightly-${{ github.sha }}" + else + TAGS="${GITHUB_REF##*/}" + fi + + for TAG in $TAGS; do + docker buildx imagetools create -t ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:$TAG \ + ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }}-amd64 \ + ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }}-arm64 + done \ No newline at end of file From 1fc5916eab806b53e19845d0ca785e7c0daf11f6 Mon Sep 17 00:00:00 2001 From: John Guibas Date: Wed, 9 Oct 2024 12:42:56 -0700 Subject: [PATCH 19/21] fix ci --- .github/workflows/docker-publish-gnark.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker-publish-gnark.yml b/.github/workflows/docker-publish-gnark.yml index 75dfaee566..5386c91107 100644 --- a/.github/workflows/docker-publish-gnark.yml +++ b/.github/workflows/docker-publish-gnark.yml @@ -1,4 +1,4 @@ -ame: docker-gnark +name: docker-gnark on: push: From 8b92d5446f019c1355ae005dc008c38d15fcc1f9 Mon Sep 17 00:00:00 2001 From: John Guibas Date: Wed, 9 Oct 2024 13:11:18 -0700 Subject: [PATCH 20/21] add print statement --- crates/recursion/gnark-ffi/go/sp1/prove.go | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/recursion/gnark-ffi/go/sp1/prove.go b/crates/recursion/gnark-ffi/go/sp1/prove.go index 723c9ab599..2ead9db55b 100644 --- a/crates/recursion/gnark-ffi/go/sp1/prove.go +++ b/crates/recursion/gnark-ffi/go/sp1/prove.go @@ -167,6 +167,7 @@ func ProveGroth16(dataDir string, witnessPath string) Proof { // Generate the proof. proof, err := groth16.Prove(globalR1cs, globalPk, witness) if err != nil { + fmt.Printf("Error: %v\n", err) panic(err) } fmt.Printf("Generating proof took %s\n", time.Since(start)) From 4834f5cd7a199467445947ff61834e59842831c7 Mon Sep 17 00:00:00 2001 From: umadayal Date: Wed, 9 Oct 2024 21:53:17 +0000 Subject: [PATCH 21/21] cargo lock --- Cargo.lock | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2893d67379..fa259aa98a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1207,9 +1207,9 @@ dependencies = [ [[package]] name = "aws-smithy-runtime" -version = "1.7.1" +version = "1.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1ce695746394772e7000b39fe073095db6d45a862d0767dd5ad0ac0d7f8eb87" +checksum = "a065c0fe6fdbdf9f11817eb68582b2ab4aff9e9c39e986ae48f7ec576c6322db" dependencies = [ "aws-smithy-async", "aws-smithy-http", @@ -4070,9 +4070,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.70" +version = "0.3.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a" +checksum = "0cb94a0ffd3f3ee755c20f7d8752f45cac88605a4dcf808abcff72873296ec7b" dependencies = [ "wasm-bindgen", ] @@ -8315,9 +8315,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.93" +version = "0.2.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5" +checksum = "ef073ced962d62984fb38a36e5fdc1a2b23c9e0e1fa0689bb97afa4202ef6887" dependencies = [ "cfg-if", "once_cell", @@ -8326,9 +8326,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.93" +version = "0.2.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b" +checksum = "c4bfab14ef75323f4eb75fa52ee0a3fb59611977fd3240da19b2cf36ff85030e" dependencies = [ "bumpalo", "log", @@ -8341,9 +8341,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.43" +version = "0.4.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61e9300f63a621e96ed275155c108eb6f843b6a26d053f122ab69724559dc8ed" +checksum = "65471f79c1022ffa5291d33520cbbb53b7687b01c2f8e83b57d102eed7ed479d" dependencies = [ "cfg-if", "js-sys", @@ -8353,9 +8353,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.93" +version = "0.2.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf" +checksum = "a7bec9830f60924d9ceb3ef99d55c155be8afa76954edffbb5936ff4509474e7" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -8363,9 +8363,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.93" +version = "0.2.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" +checksum = "4c74f6e152a76a2ad448e223b0fc0b6b5747649c3d769cc6bf45737bf97d0ed6" dependencies = [ "proc-macro2", "quote", @@ -8376,9 +8376,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.93" +version = "0.2.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" +checksum = "a42f6c679374623f295a8623adfe63d9284091245c3504bde47c17a3ce2777d9" [[package]] name = "wasm-streams" @@ -8395,9 +8395,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.70" +version = "0.3.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26fdeaafd9bd129f65e7c031593c24d62186301e0c72c8978fa1678be7d532c0" +checksum = "44188d185b5bdcae1052d08bcbcf9091a5524038d4572cc4f4f2bb9d5554ddd9" dependencies = [ "js-sys", "wasm-bindgen",