diff --git a/Cargo.lock b/Cargo.lock index 55de795a21..6e10c5bfee 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -836,7 +836,7 @@ dependencies = [ "bitflags 2.5.0", "cexpr", "clang-sys", - "itertools 0.12.1", + "itertools 0.10.5", "lazy_static", "lazycell", "log", @@ -2936,7 +2936,7 @@ checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" [[package]] name = "p3-air" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#04d4c6e15a0296798331db82e696d29c455bafe1" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#da0489b75025ec17f1100952694d8b7879c2b43e" dependencies = [ "p3-field", "p3-matrix", @@ -2945,7 +2945,7 @@ dependencies = [ [[package]] name = "p3-baby-bear" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#04d4c6e15a0296798331db82e696d29c455bafe1" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#da0489b75025ec17f1100952694d8b7879c2b43e" dependencies = [ "num-bigint 0.4.5", "p3-field", @@ -2959,7 +2959,7 @@ dependencies = [ [[package]] name = "p3-blake3" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#04d4c6e15a0296798331db82e696d29c455bafe1" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#da0489b75025ec17f1100952694d8b7879c2b43e" dependencies = [ "blake3", "p3-symmetric", @@ -2968,7 +2968,7 @@ dependencies = [ [[package]] name = "p3-bn254-fr" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#04d4c6e15a0296798331db82e696d29c455bafe1" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#da0489b75025ec17f1100952694d8b7879c2b43e" dependencies = [ "ff 0.13.0", "num-bigint 0.4.5", @@ -2982,7 +2982,7 @@ dependencies = [ [[package]] name = "p3-challenger" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#04d4c6e15a0296798331db82e696d29c455bafe1" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#da0489b75025ec17f1100952694d8b7879c2b43e" dependencies = [ "p3-field", "p3-maybe-rayon", @@ -2994,7 +2994,7 @@ dependencies = [ [[package]] name = "p3-commit" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#04d4c6e15a0296798331db82e696d29c455bafe1" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#da0489b75025ec17f1100952694d8b7879c2b43e" dependencies = [ "itertools 0.12.1", "p3-challenger", @@ -3007,7 +3007,7 @@ dependencies = [ [[package]] name = "p3-dft" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#04d4c6e15a0296798331db82e696d29c455bafe1" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#da0489b75025ec17f1100952694d8b7879c2b43e" dependencies = [ "p3-field", "p3-matrix", @@ -3019,7 +3019,7 @@ dependencies = [ [[package]] name = "p3-field" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#04d4c6e15a0296798331db82e696d29c455bafe1" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#da0489b75025ec17f1100952694d8b7879c2b43e" dependencies = [ "itertools 0.12.1", "num-bigint 0.4.5", @@ -3032,7 +3032,7 @@ dependencies = [ [[package]] name = "p3-fri" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#04d4c6e15a0296798331db82e696d29c455bafe1" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#da0489b75025ec17f1100952694d8b7879c2b43e" dependencies = [ "itertools 0.12.1", "p3-challenger", @@ -3050,7 +3050,7 @@ dependencies = [ [[package]] name = "p3-interpolation" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#04d4c6e15a0296798331db82e696d29c455bafe1" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#da0489b75025ec17f1100952694d8b7879c2b43e" dependencies = [ "p3-field", "p3-matrix", @@ -3060,7 +3060,7 @@ dependencies = [ [[package]] name = "p3-keccak" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#04d4c6e15a0296798331db82e696d29c455bafe1" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#da0489b75025ec17f1100952694d8b7879c2b43e" dependencies = [ "p3-symmetric", "tiny-keccak", @@ -3069,7 +3069,7 @@ dependencies = [ [[package]] name = "p3-keccak-air" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#04d4c6e15a0296798331db82e696d29c455bafe1" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#da0489b75025ec17f1100952694d8b7879c2b43e" dependencies = [ "p3-air", "p3-field", @@ -3082,7 +3082,7 @@ dependencies = [ [[package]] name = "p3-matrix" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#04d4c6e15a0296798331db82e696d29c455bafe1" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#da0489b75025ec17f1100952694d8b7879c2b43e" dependencies = [ "itertools 0.12.1", "p3-field", @@ -3096,7 +3096,7 @@ dependencies = [ [[package]] name = "p3-maybe-rayon" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#04d4c6e15a0296798331db82e696d29c455bafe1" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#da0489b75025ec17f1100952694d8b7879c2b43e" dependencies = [ "rayon", ] @@ -3104,7 +3104,7 @@ dependencies = [ [[package]] name = "p3-mds" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#04d4c6e15a0296798331db82e696d29c455bafe1" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#da0489b75025ec17f1100952694d8b7879c2b43e" dependencies = [ "itertools 0.12.1", "p3-dft", @@ -3118,7 +3118,7 @@ dependencies = [ [[package]] name = "p3-merkle-tree" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#04d4c6e15a0296798331db82e696d29c455bafe1" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#da0489b75025ec17f1100952694d8b7879c2b43e" dependencies = [ "itertools 0.12.1", "p3-commit", @@ -3134,7 +3134,7 @@ dependencies = [ [[package]] name = "p3-poseidon2" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#04d4c6e15a0296798331db82e696d29c455bafe1" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#da0489b75025ec17f1100952694d8b7879c2b43e" dependencies = [ "gcd", "p3-field", @@ -3146,7 +3146,7 @@ dependencies = [ [[package]] name = "p3-symmetric" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#04d4c6e15a0296798331db82e696d29c455bafe1" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#da0489b75025ec17f1100952694d8b7879c2b43e" dependencies = [ "itertools 0.12.1", "p3-field", @@ -3156,7 +3156,7 @@ dependencies = [ [[package]] name = "p3-uni-stark" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#04d4c6e15a0296798331db82e696d29c455bafe1" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#da0489b75025ec17f1100952694d8b7879c2b43e" dependencies = [ "itertools 0.12.1", "p3-air", @@ -3174,7 +3174,7 @@ dependencies = [ [[package]] name = "p3-util" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#04d4c6e15a0296798331db82e696d29c455bafe1" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#da0489b75025ec17f1100952694d8b7879c2b43e" dependencies = [ "serde", ] @@ -3500,7 +3500,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9554e3ab233f0a932403704f1a1d08c30d5ccd931adfdfa1e8b5a19b52c1d55a" dependencies = [ "anyhow", - "itertools 0.12.1", + "itertools 0.10.5", "proc-macro2", "quote", "syn 2.0.61", diff --git a/core/src/stark/machine.rs b/core/src/stark/machine.rs index 948ceca9ab..8616915586 100644 --- a/core/src/stark/machine.rs +++ b/core/src/stark/machine.rs @@ -10,6 +10,7 @@ use p3_matrix::dense::RowMajorMatrix; use p3_matrix::Dimensions; use p3_matrix::Matrix; use p3_maybe_rayon::prelude::*; +use serde::de::DeserializeOwned; use serde::Deserialize; use serde::Serialize; use std::cmp::Reverse; @@ -63,6 +64,9 @@ impl StarkMachine { } } +#[derive(Clone, Serialize, Deserialize)] +#[serde(bound(serialize = "PcsProverData: Serialize"))] +#[serde(bound(deserialize = "PcsProverData: DeserializeOwned"))] pub struct StarkProvingKey { pub commit: Com, pub pc_start: Val, @@ -79,11 +83,11 @@ impl StarkProvingKey { } #[derive(Clone, Serialize, Deserialize)] -#[serde(bound = "SC: StarkGenericConfig")] +#[serde(bound(serialize = "Dom: Serialize"))] +#[serde(bound(deserialize = "Dom: DeserializeOwned"))] pub struct StarkVerifyingKey { pub commit: Com, pub pc_start: Val, - #[serde(skip)] pub chip_information: Vec<(String, Dom, Dimensions)>, pub chip_ordering: HashMap, } @@ -517,6 +521,9 @@ pub mod tests { use crate::runtime::Instruction; use crate::runtime::Opcode; use crate::runtime::Program; + use crate::stark::RiscvAir; + use crate::stark::StarkProvingKey; + use crate::stark::StarkVerifyingKey; use crate::utils; use crate::utils::prove; use crate::utils::run_test; @@ -684,4 +691,43 @@ pub mod tests { let program = ssz_withdrawals_program(); run_test(program).unwrap(); } + + #[test] + fn test_key_serde() { + let program = ssz_withdrawals_program(); + let config = BabyBearPoseidon2::new(); + let machine = RiscvAir::machine(config); + let (pk, vk) = machine.setup(&program); + + let serialized_pk = bincode::serialize(&pk).unwrap(); + let deserialized_pk: StarkProvingKey = + bincode::deserialize(&serialized_pk).unwrap(); + assert_eq!(pk.commit, deserialized_pk.commit); + assert_eq!(pk.pc_start, deserialized_pk.pc_start); + assert_eq!(pk.traces, deserialized_pk.traces); + assert_eq!(pk.data.root(), deserialized_pk.data.root()); + assert_eq!(pk.chip_ordering, deserialized_pk.chip_ordering); + + let serialized_vk = bincode::serialize(&vk).unwrap(); + let deserialized_vk: StarkVerifyingKey = + bincode::deserialize(&serialized_vk).unwrap(); + assert_eq!(vk.commit, deserialized_vk.commit); + assert_eq!(vk.pc_start, deserialized_vk.pc_start); + assert_eq!( + vk.chip_information.len(), + deserialized_vk.chip_information.len() + ); + for (a, b) in vk + .chip_information + .iter() + .zip(deserialized_vk.chip_information.iter()) + { + assert_eq!(a.0, b.0); + assert_eq!(a.1.log_n, b.1.log_n); + assert_eq!(a.1.shift, b.1.shift); + assert_eq!(a.2.height, b.2.height); + assert_eq!(a.2.width, b.2.width); + } + assert_eq!(vk.chip_ordering, deserialized_vk.chip_ordering); + } } diff --git a/examples/Cargo.lock b/examples/Cargo.lock index ce377df651..c6684b3326 100644 --- a/examples/Cargo.lock +++ b/examples/Cargo.lock @@ -827,7 +827,7 @@ dependencies = [ "bitflags 2.5.0", "cexpr", "clang-sys", - "itertools 0.12.1", + "itertools 0.10.5", "lazy_static", "lazycell", "log", @@ -2930,7 +2930,7 @@ checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" [[package]] name = "p3-air" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#04d4c6e15a0296798331db82e696d29c455bafe1" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#da0489b75025ec17f1100952694d8b7879c2b43e" dependencies = [ "p3-field", "p3-matrix", @@ -2939,7 +2939,7 @@ dependencies = [ [[package]] name = "p3-baby-bear" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#04d4c6e15a0296798331db82e696d29c455bafe1" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#da0489b75025ec17f1100952694d8b7879c2b43e" dependencies = [ "num-bigint 0.4.5", "p3-field", @@ -2953,7 +2953,7 @@ dependencies = [ [[package]] name = "p3-blake3" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#04d4c6e15a0296798331db82e696d29c455bafe1" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#da0489b75025ec17f1100952694d8b7879c2b43e" dependencies = [ "blake3", "p3-symmetric", @@ -2962,7 +2962,7 @@ dependencies = [ [[package]] name = "p3-bn254-fr" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#04d4c6e15a0296798331db82e696d29c455bafe1" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#da0489b75025ec17f1100952694d8b7879c2b43e" dependencies = [ "ff 0.13.0", "num-bigint 0.4.5", @@ -2976,7 +2976,7 @@ dependencies = [ [[package]] name = "p3-challenger" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#04d4c6e15a0296798331db82e696d29c455bafe1" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#da0489b75025ec17f1100952694d8b7879c2b43e" dependencies = [ "p3-field", "p3-maybe-rayon", @@ -2988,7 +2988,7 @@ dependencies = [ [[package]] name = "p3-commit" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#04d4c6e15a0296798331db82e696d29c455bafe1" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#da0489b75025ec17f1100952694d8b7879c2b43e" dependencies = [ "itertools 0.12.1", "p3-challenger", @@ -3001,7 +3001,7 @@ dependencies = [ [[package]] name = "p3-dft" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#04d4c6e15a0296798331db82e696d29c455bafe1" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#da0489b75025ec17f1100952694d8b7879c2b43e" dependencies = [ "p3-field", "p3-matrix", @@ -3013,7 +3013,7 @@ dependencies = [ [[package]] name = "p3-field" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#04d4c6e15a0296798331db82e696d29c455bafe1" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#da0489b75025ec17f1100952694d8b7879c2b43e" dependencies = [ "itertools 0.12.1", "num-bigint 0.4.5", @@ -3026,7 +3026,7 @@ dependencies = [ [[package]] name = "p3-fri" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#04d4c6e15a0296798331db82e696d29c455bafe1" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#da0489b75025ec17f1100952694d8b7879c2b43e" dependencies = [ "itertools 0.12.1", "p3-challenger", @@ -3044,7 +3044,7 @@ dependencies = [ [[package]] name = "p3-interpolation" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#04d4c6e15a0296798331db82e696d29c455bafe1" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#da0489b75025ec17f1100952694d8b7879c2b43e" dependencies = [ "p3-field", "p3-matrix", @@ -3054,7 +3054,7 @@ dependencies = [ [[package]] name = "p3-keccak" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#04d4c6e15a0296798331db82e696d29c455bafe1" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#da0489b75025ec17f1100952694d8b7879c2b43e" dependencies = [ "p3-symmetric", "tiny-keccak", @@ -3063,7 +3063,7 @@ dependencies = [ [[package]] name = "p3-keccak-air" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#04d4c6e15a0296798331db82e696d29c455bafe1" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#da0489b75025ec17f1100952694d8b7879c2b43e" dependencies = [ "p3-air", "p3-field", @@ -3076,7 +3076,7 @@ dependencies = [ [[package]] name = "p3-matrix" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#04d4c6e15a0296798331db82e696d29c455bafe1" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#da0489b75025ec17f1100952694d8b7879c2b43e" dependencies = [ "itertools 0.12.1", "p3-field", @@ -3090,7 +3090,7 @@ dependencies = [ [[package]] name = "p3-maybe-rayon" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#04d4c6e15a0296798331db82e696d29c455bafe1" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#da0489b75025ec17f1100952694d8b7879c2b43e" dependencies = [ "rayon", ] @@ -3098,7 +3098,7 @@ dependencies = [ [[package]] name = "p3-mds" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#04d4c6e15a0296798331db82e696d29c455bafe1" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#da0489b75025ec17f1100952694d8b7879c2b43e" dependencies = [ "itertools 0.12.1", "p3-dft", @@ -3112,7 +3112,7 @@ dependencies = [ [[package]] name = "p3-merkle-tree" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#04d4c6e15a0296798331db82e696d29c455bafe1" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#da0489b75025ec17f1100952694d8b7879c2b43e" dependencies = [ "itertools 0.12.1", "p3-commit", @@ -3128,7 +3128,7 @@ dependencies = [ [[package]] name = "p3-poseidon2" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#04d4c6e15a0296798331db82e696d29c455bafe1" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#da0489b75025ec17f1100952694d8b7879c2b43e" dependencies = [ "gcd", "p3-field", @@ -3140,7 +3140,7 @@ dependencies = [ [[package]] name = "p3-symmetric" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#04d4c6e15a0296798331db82e696d29c455bafe1" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#da0489b75025ec17f1100952694d8b7879c2b43e" dependencies = [ "itertools 0.12.1", "p3-field", @@ -3150,7 +3150,7 @@ dependencies = [ [[package]] name = "p3-uni-stark" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#04d4c6e15a0296798331db82e696d29c455bafe1" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#da0489b75025ec17f1100952694d8b7879c2b43e" dependencies = [ "itertools 0.12.1", "p3-air", @@ -3168,7 +3168,7 @@ dependencies = [ [[package]] name = "p3-util" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#04d4c6e15a0296798331db82e696d29c455bafe1" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#da0489b75025ec17f1100952694d8b7879c2b43e" dependencies = [ "serde", ] @@ -3497,7 +3497,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9554e3ab233f0a932403704f1a1d08c30d5ccd931adfdfa1e8b5a19b52c1d55a" dependencies = [ "anyhow", - "itertools 0.12.1", + "itertools 0.10.5", "proc-macro2", "quote", "syn 2.0.61", @@ -4491,6 +4491,7 @@ dependencies = [ "hex", "indicatif", "itertools 0.12.1", + "num-bigint 0.4.5", "p3-baby-bear", "p3-bn254-fr", "p3-challenger", @@ -4615,6 +4616,7 @@ dependencies = [ "cc", "crossbeam", "log", + "num-bigint 0.4.5", "p3-baby-bear", "p3-field", "rand", @@ -4668,6 +4670,7 @@ dependencies = [ "hex", "indicatif", "log", + "num-bigint 0.4.5", "p3-commit", "p3-field", "p3-matrix", diff --git a/examples/fibonacci/script/bin/execute.rs b/examples/fibonacci/script/bin/execute.rs index e01d5667e6..be8776b414 100644 --- a/examples/fibonacci/script/bin/execute.rs +++ b/examples/fibonacci/script/bin/execute.rs @@ -15,7 +15,7 @@ fn main() { // Only execute the program and get a `SP1PublicValues` object. let client = ProverClient::new(); - let mut public_values = client.execute(&ELF, stdin).unwrap(); + let mut public_values = client.execute(ELF, stdin).unwrap(); println!("generated proof"); diff --git a/prover/src/types.rs b/prover/src/types.rs index e3aa597bd9..198dc62660 100644 --- a/prover/src/types.rs +++ b/prover/src/types.rs @@ -23,6 +23,7 @@ use crate::{utils::babybear_bytes_to_bn254, words_to_bytes}; use crate::{utils::babybears_to_bn254, CoreSC, InnerSC}; /// The information necessary to generate a proof for a given RISC-V program. +#[derive(Clone, Serialize, Deserialize)] pub struct SP1ProvingKey { pub pk: StarkProvingKey, pub elf: Vec, diff --git a/sdk/src/auth.rs b/sdk/src/auth.rs index 44878a0c1d..5ff49393eb 100644 --- a/sdk/src/auth.rs +++ b/sdk/src/auth.rs @@ -6,6 +6,8 @@ use alloy::sol; use alloy::sol_types::{Eip712Domain, SolStruct}; use anyhow::Result; +use crate::proto::network::UnclaimReason; + sol! { struct CreateProof { uint64 nonce; @@ -23,6 +25,13 @@ sol! { string proof_id; } + struct UnclaimProof { + uint64 nonce; + string proof_id; + uint8 reason; + string description; + } + struct FulfillProof { uint64 nonce; string proof_id; @@ -110,6 +119,23 @@ impl NetworkAuth { self.sign_message(type_struct).await } + /// Signs a message to unclaim a proof that was previously claimed. + pub async fn sign_unclaim_proof_message( + &self, + nonce: u64, + proof_id: String, + reason: UnclaimReason, + description: String, + ) -> Result> { + let type_struct = UnclaimProof { + nonce, + proof_id, + reason: reason as u8, + description, + }; + self.sign_message(type_struct).await + } + /// Signs a message to fulfill a proof. The proof must have been previously claimed by the /// signer first. pub async fn sign_fulfill_proof_message(&self, nonce: u64, proof_id: &str) -> Result> { diff --git a/sdk/src/client.rs b/sdk/src/client.rs index 00e332f2e3..87403dbde7 100644 --- a/sdk/src/client.rs +++ b/sdk/src/client.rs @@ -1,6 +1,9 @@ use std::{env, time::Duration}; -use crate::auth::NetworkAuth; +use crate::{ + auth::NetworkAuth, + proto::network::{UnclaimProofRequest, UnclaimReason}, +}; use anyhow::{Context, Ok, Result}; use futures::future::join_all; use reqwest::{Client as HttpClient, Url}; @@ -73,15 +76,14 @@ impl NetworkClient { } /// Gets the latest nonce for this auth's account. - pub async fn get_nonce(&self) -> u64 { + pub async fn get_nonce(&self) -> Result { let res = self .rpc .get_nonce(GetNonceRequest { address: self.auth.get_address().to_vec(), }) - .await - .unwrap(); - res.nonce + .await?; + Ok(res.nonce) } // Upload a file to the specified url. @@ -105,10 +107,10 @@ impl NetworkClient { let proof = match res.status() { ProofStatus::ProofFulfilled => { - println!("Proof request fulfilled"); + log::info!("Proof request fulfilled"); let proof_bytes = self .http - .get(res.proof_url.clone()) + .get(res.proof_url.as_ref().expect("no proof url")) .send() .await .context("Failed to send HTTP request for proof")? @@ -177,7 +179,7 @@ impl NetworkClient { .expect("Invalid start time"); let deadline = since_the_epoch.as_secs() + 1000; - let nonce = self.get_nonce().await; + let nonce = self.get_nonce().await?; let create_proof_signature = self .auth .sign_create_proof_message(nonce, deadline, mode.into()) @@ -201,7 +203,7 @@ impl NetworkClient { results.pop().expect("Failed to upload stdin")?; results.pop().expect("Failed to upload program")?; - let nonce = self.get_nonce().await; + let nonce = self.get_nonce().await?; let submit_proof_signature = self .auth .sign_submit_proof_message(nonce, &res.proof_id) @@ -220,7 +222,7 @@ impl NetworkClient { // Claim a proof that was requested. This commits to generating a proof and fulfilling it. // Returns an error if the proof is not in a PROOF_REQUESTED state. pub async fn claim_proof(&self, proof_id: &str) -> Result { - let nonce = self.get_nonce().await; + let nonce = self.get_nonce().await?; let signature = self.auth.sign_claim_proof_message(nonce, proof_id).await?; let res = self .rpc @@ -234,10 +236,37 @@ impl NetworkClient { Ok(res) } + // Unclaim a proof that was claimed. This should only be called if the proof has not been + // fulfilled yet. Returns an error if the proof is not in a PROOF_CLAIMED state or if the caller + // is not the claimer. + pub async fn unclaim_proof( + &self, + proof_id: String, + reason: UnclaimReason, + description: String, + ) -> Result<()> { + let nonce = self.get_nonce().await?; + let signature = self + .auth + .sign_unclaim_proof_message(nonce, proof_id.clone(), reason, description.clone()) + .await?; + self.rpc + .unclaim_proof(UnclaimProofRequest { + signature, + nonce, + proof_id, + reason: reason.into(), + description, + }) + .await?; + + Ok(()) + } + // Fulfill a proof. Should only be called after the proof has been uploaded. Returns an error // if the proof is not in a PROOF_CLAIMED state or if the caller is not the claimer. pub async fn fulfill_proof(&self, proof_id: &str) -> Result { - let nonce = self.get_nonce().await; + let nonce = self.get_nonce().await?; let signature = self .auth .sign_fulfill_proof_message(nonce, proof_id) @@ -263,7 +292,7 @@ impl NetworkClient { callback: [u8; 20], callback_data: &[u8], ) -> Result { - let nonce = self.get_nonce().await; + let nonce = self.get_nonce().await?; let signature = self .auth .sign_relay_proof_message(nonce, proof_id, chain_id, verifier, callback, callback_data) diff --git a/sdk/src/proto/network.rs b/sdk/src/proto/network.rs index 2dd9b39d84..52bb125647 100644 --- a/sdk/src/proto/network.rs +++ b/sdk/src/proto/network.rs @@ -86,6 +86,33 @@ pub struct ClaimProofResponse { #[prost(string, tag = "3")] pub proof_artifact_id: ::prost::alloc::string::String, } +/// The request to unclaim a proof, which cancels the claim to fulfill the proof. MUST be called +/// when the proof is in a PROOF_CLAIMED state and MUST be called by the prover who claimed it. +#[derive(serde::Serialize, serde::Deserialize)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct UnclaimProofRequest { + /// The signature of the message. + #[prost(bytes = "vec", tag = "1")] + pub signature: ::prost::alloc::vec::Vec, + /// The nonce for the account. + #[prost(uint64, tag = "2")] + pub nonce: u64, + /// The proof identifier. + #[prost(string, tag = "3")] + pub proof_id: ::prost::alloc::string::String, + /// The reason for unclaiming the proof. + #[prost(enumeration = "UnclaimReason", tag = "4")] + pub reason: i32, + /// The description for the reason. + #[prost(string, tag = "5")] + pub description: ::prost::alloc::string::String, +} +/// The response for unclaiming a proof, empty on success. +#[derive(serde::Serialize, serde::Deserialize)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct UnclaimProofResponse {} /// The request to fulfill a proof. MUST be called after the proof has been uploaded and MUST be called /// when the proof is in a PROOF_CLAIMED state. #[derive(serde::Serialize, serde::Deserialize)] @@ -185,8 +212,14 @@ pub struct GetProofStatusResponse { pub status: i32, /// Optional proof URL, where you can download the result of the proof request. Only included if /// the proof has been fulfilled. - #[prost(string, tag = "2")] - pub proof_url: ::prost::alloc::string::String, + #[prost(string, optional, tag = "2")] + pub proof_url: ::core::option::Option<::prost::alloc::string::String>, + /// If the proof was unclaimed, the reason why. + #[prost(enumeration = "UnclaimReason", optional, tag = "3")] + pub unclaim_reason: ::core::option::Option, + /// If the proof was unclaimed, the description detailing why. + #[prost(string, optional, tag = "4")] + pub unclaim_description: ::core::option::Option<::prost::alloc::string::String>, } /// The request to get proof requests by a given status. #[derive(serde::Serialize, serde::Deserialize)] @@ -320,10 +353,10 @@ pub enum ProofStatus { ProofRequested = 2, /// The proof request has been claimed and is awaiting a prover to fulfill it. ProofClaimed = 3, + /// The proof request was previously claimed but has now been unclaimed. + ProofUnclaimed = 4, /// The proof request has been fulfilled and is available for download. - ProofFulfilled = 4, - /// The proof request failed and will need to be re-created. - ProofFailed = 5, + ProofFulfilled = 5, } impl ProofStatus { /// String value of the enum field names used in the ProtoBuf definition. @@ -336,8 +369,8 @@ impl ProofStatus { ProofStatus::ProofPreparing => "PROOF_PREPARING", ProofStatus::ProofRequested => "PROOF_REQUESTED", ProofStatus::ProofClaimed => "PROOF_CLAIMED", + ProofStatus::ProofUnclaimed => "PROOF_UNCLAIMED", ProofStatus::ProofFulfilled => "PROOF_FULFILLED", - ProofStatus::ProofFailed => "PROOF_FAILED", } } /// Creates an enum from field names used in the ProtoBuf definition. @@ -347,8 +380,8 @@ impl ProofStatus { "PROOF_PREPARING" => Some(Self::ProofPreparing), "PROOF_REQUESTED" => Some(Self::ProofRequested), "PROOF_CLAIMED" => Some(Self::ProofClaimed), + "PROOF_UNCLAIMED" => Some(Self::ProofUnclaimed), "PROOF_FULFILLED" => Some(Self::ProofFulfilled), - "PROOF_FAILED" => Some(Self::ProofFailed), _ => None, } } @@ -410,6 +443,50 @@ impl TransactionStatus { } } } +#[derive( + serde::Serialize, + serde::Deserialize, + Clone, + Copy, + Debug, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, + ::prost::Enumeration, +)] +#[repr(i32)] +pub enum UnclaimReason { + /// Unspecified reason. + Unspecified = 0, + /// The prover claims the request is invalid and cannot be fulfilled. + Invalid = 1, + /// The prover is unable to fulfill the proof due to any other reason. + Abandoned = 2, +} +impl UnclaimReason { + /// 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 { + UnclaimReason::Unspecified => "UNCLAIM_REASON_UNSPECIFIED", + UnclaimReason::Invalid => "UNCLAIM_REASON_INVALID", + UnclaimReason::Abandoned => "UNCLAIM_REASON_ABANDONED", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "UNCLAIM_REASON_UNSPECIFIED" => Some(Self::Unspecified), + "UNCLAIM_REASON_INVALID" => Some(Self::Invalid), + "UNCLAIM_REASON_ABANDONED" => Some(Self::Abandoned), + _ => None, + } + } +} pub const SERVICE_FQN: &str = "/network.NetworkService"; #[twirp::async_trait::async_trait] pub trait NetworkService { @@ -428,6 +505,11 @@ pub trait NetworkService { ctx: twirp::Context, req: ClaimProofRequest, ) -> Result; + async fn unclaim_proof( + &self, + ctx: twirp::Context, + req: UnclaimProofRequest, + ) -> Result; async fn fulfill_proof( &self, ctx: twirp::Context, @@ -482,6 +564,12 @@ where api.claim_proof(ctx, req).await }, ) + .route( + "/UnclaimProof", + |api: std::sync::Arc, ctx: twirp::Context, req: UnclaimProofRequest| async move { + api.unclaim_proof(ctx, req).await + }, + ) .route( "/FulfillProof", |api: std::sync::Arc, ctx: twirp::Context, req: FulfillProofRequest| async move { @@ -534,6 +622,10 @@ pub trait NetworkServiceClient: Send + Sync + std::fmt::Debug { &self, req: ClaimProofRequest, ) -> Result; + async fn unclaim_proof( + &self, + req: UnclaimProofRequest, + ) -> Result; async fn fulfill_proof( &self, req: FulfillProofRequest, @@ -580,6 +672,13 @@ impl NetworkServiceClient for twirp::client::Client { let url = self.base_url.join("network.NetworkService/ClaimProof")?; self.request(url, req).await } + async fn unclaim_proof( + &self, + req: UnclaimProofRequest, + ) -> Result { + let url = self.base_url.join("network.NetworkService/UnclaimProof")?; + self.request(url, req).await + } async fn fulfill_proof( &self, req: FulfillProofRequest, diff --git a/sdk/src/provers/network.rs b/sdk/src/provers/network.rs index a5b2e58e3c..4e9dc0f9c0 100644 --- a/sdk/src/provers/network.rs +++ b/sdk/src/provers/network.rs @@ -11,6 +11,7 @@ use crate::{ }; use anyhow::{Context, Result}; use serde::de::DeserializeOwned; +use sp1_core::runtime::{Program, Runtime}; use sp1_prover::utils::block_on; use sp1_prover::{SP1Prover, SP1Stdin}; use tokio::{runtime, time::sleep}; @@ -43,13 +44,19 @@ impl NetworkProver { ) -> Result

{ let client = &self.client; // Execute the runtime before creating the proof request. - // TODO: Maybe we don't want to always do this locally, with large programs. Or we may want - // to disable events at least. - let _public_values = SP1Prover::execute(elf, &stdin); - println!("Simulation complete"); + let program = Program::from(elf); + let mut runtime = Runtime::new(program); + runtime.write_vecs(&stdin.buffer); + for (proof, vkey) in stdin.proofs.iter() { + runtime.write_proof(proof.clone(), vkey.clone()); + } + runtime + .run_untraced() + .context("Failed to execute program")?; + log::info!("Simulation complete, cycles: {}", runtime.state.global_clk); let proof_id = client.create_proof(elf, &stdin, mode).await?; - println!("Proof request ID: {:?}", proof_id); + log::info!("Created {}", proof_id); let mut is_claimed = false; loop { @@ -61,12 +68,15 @@ impl NetworkProver { } ProofStatus::ProofClaimed => { if !is_claimed { - println!("Proof request claimed, proving..."); + log::info!("Proof request claimed, proving..."); is_claimed = true; } } - ProofStatus::ProofFailed => { - return Err(anyhow::anyhow!("Proof generation failed")); + ProofStatus::ProofUnclaimed => { + return Err(anyhow::anyhow!( + "Proof generation failed: {}", + status.unclaim_description() + )); } _ => { sleep(Duration::from_secs(1)).await;