From 9a1a5134d59b6a9b254102f9968369a28e4ce801 Mon Sep 17 00:00:00 2001 From: mattstam Date: Fri, 20 Dec 2024 12:21:30 -0800 Subject: [PATCH] feat: update SDK for network --- crates/perf/src/main.rs | 4 +- crates/sdk/src/cpu/builder.rs | 6 +- crates/sdk/src/network/client.rs | 60 ++++++- crates/sdk/src/network/error.rs | 39 +++++ crates/sdk/src/network/mod.rs | 3 + crates/sdk/src/network/proto/artifact.rs | 62 ++++++- crates/sdk/src/network/proto/network.rs | 204 ++++++++++++++++++----- crates/sdk/src/network/prover.rs | 44 +++-- 8 files changed, 348 insertions(+), 74 deletions(-) create mode 100644 crates/sdk/src/network/error.rs diff --git a/crates/perf/src/main.rs b/crates/perf/src/main.rs index 04ca61317..7449d67c7 100644 --- a/crates/perf/src/main.rs +++ b/crates/perf/src/main.rs @@ -177,13 +177,13 @@ fn main() { let (_, _) = time_operation(|| prover.execute(&elf, &stdin)); let (proof, _) = time_operation(|| { - prover.prove(&pk, stdin.clone()).groth16().skip_simulation(true).run().unwrap() + prover.prove(&pk, &stdin).groth16().skip_simulation(true).run().unwrap() }); let (_, _) = time_operation(|| prover.verify(&proof, &vk)); let (proof, _) = time_operation(|| { - prover.prove(&pk, stdin).plonk().skip_simulation(true).run().unwrap() + prover.prove(&pk, &stdin).plonk().skip_simulation(true).run().unwrap() }); let (_, _) = time_operation(|| prover.verify(&proof, &vk)); diff --git a/crates/sdk/src/cpu/builder.rs b/crates/sdk/src/cpu/builder.rs index 3bd17ebc2..6cdcf3b38 100644 --- a/crates/sdk/src/cpu/builder.rs +++ b/crates/sdk/src/cpu/builder.rs @@ -26,6 +26,10 @@ impl CpuProverBuilder { /// ``` #[must_use] pub fn build(self) -> CpuProver { - if self.mock { CpuProver::mock() } else { CpuProver::new() } + if self.mock { + CpuProver::mock() + } else { + CpuProver::new() + } } } diff --git a/crates/sdk/src/network/client.rs b/crates/sdk/src/network/client.rs index 880352c5c..6758ffa3d 100644 --- a/crates/sdk/src/network/client.rs +++ b/crates/sdk/src/network/client.rs @@ -20,14 +20,14 @@ use tonic::{ use super::utils::Signable; use crate::network::proto::artifact::{ - artifact_store_client::ArtifactStoreClient, CreateArtifactRequest, + artifact_store_client::ArtifactStoreClient, ArtifactType, CreateArtifactRequest, }; use crate::network::proto::network::{ prover_network_client::ProverNetworkClient, CreateProgramRequest, CreateProgramRequestBody, - CreateProgramResponse, FulfillmentStatus, FulfillmentStrategy, GetNonceRequest, - GetProgramRequest, GetProgramResponse, GetProofRequestStatusRequest, - GetProofRequestStatusResponse, MessageFormat, ProofMode, RequestProofRequest, - RequestProofRequestBody, RequestProofResponse, + CreateProgramResponse, FulfillmentStatus, FulfillmentStrategy, GetFilteredProofRequestsRequest, + GetFilteredProofRequestsResponse, GetNonceRequest, GetProgramRequest, GetProgramResponse, + GetProofRequestStatusRequest, GetProofRequestStatusResponse, MessageFormat, ProofMode, + RequestProofRequest, RequestProofRequestBody, RequestProofResponse, }; /// A client for interacting with the network. @@ -105,7 +105,8 @@ impl NetworkClient { ) -> Result { // Create the program artifact. let mut store = self.artifact_store_client().await?; - let program_uri = self.create_artifact_with_content(&mut store, &elf).await?; + let program_uri = + self.create_artifact_with_content(&mut store, ArtifactType::Program, &elf).await?; // Serialize the verifying key. let vk_encoded = bincode::serialize(&vk)?; @@ -130,6 +131,44 @@ impl NetworkClient { .into_inner()) } + /// Get all the proof requests that meet the filter criteria. + #[allow(clippy::too_many_arguments)] + pub async fn get_filtered_proof_requests( + &self, + version: Option, + fulfillment_status: Option, + execution_status: Option, + minimum_deadline: Option, + vk_hash: Option>, + requester: Option>, + fulfiller: Option>, + from: Option, + to: Option, + limit: Option, + page: Option, + mode: Option, + ) -> Result { + let mut rpc = self.prover_network_client().await?; + let res = rpc + .get_filtered_proof_requests(GetFilteredProofRequestsRequest { + version, + fulfillment_status, + execution_status, + minimum_deadline, + vk_hash, + requester, + fulfiller, + from, + to, + limit, + page, + mode, + }) + .await? + .into_inner(); + Ok(res) + } + /// Get the status of a given proof. /// /// # Details @@ -190,7 +229,8 @@ impl NetworkClient { // Create the stdin artifact. let mut store = self.artifact_store_client().await?; - let stdin_uri = self.create_artifact_with_content(&mut store, &stdin).await?; + let stdin_uri = + self.create_artifact_with_content(&mut store, ArtifactType::Stdin, &stdin).await?; // Send the request. let mut rpc = self.prover_network_client().await?; @@ -248,10 +288,14 @@ impl NetworkClient { pub(crate) async fn create_artifact_with_content( &self, store: &mut ArtifactStoreClient, + artifact_type: ArtifactType, item: &T, ) -> Result { let signature = self.signer.sign_message_sync("create_artifact".as_bytes())?; - let request = CreateArtifactRequest { signature: signature.as_bytes().to_vec() }; + let request = CreateArtifactRequest { + artifact_type: artifact_type.into(), + signature: signature.as_bytes().to_vec(), + }; let response = store.create_artifact(request).await?.into_inner(); let presigned_url = response.artifact_presigned_url; diff --git a/crates/sdk/src/network/error.rs b/crates/sdk/src/network/error.rs new file mode 100644 index 000000000..3cde6d604 --- /dev/null +++ b/crates/sdk/src/network/error.rs @@ -0,0 +1,39 @@ +use thiserror::Error; +use tonic::Status; + +/// An error that can occur when interacting with the prover network. +#[derive(Error, Debug)] +pub enum Error { + /// The program execution failed. + #[error("Program simulation failed")] + SimulationFailed, + + /// The proof request is unexecutable. + #[error("Proof request 0x{} is unexecutable", hex::encode(.request_id))] + RequestUnexecutable { + /// The ID of the request that cannot be executed. + request_id: Vec, + }, + + /// The proof request is unfulfillable. + #[error("Proof request 0x{} is unfulfillable", hex::encode(.request_id))] + RequestUnfulfillable { + /// The ID of the request that cannot be fulfilled. + request_id: Vec, + }, + + /// The proof request timed out. + #[error("Proof request 0x{} timed out", hex::encode(.request_id))] + RequestTimedOut { + /// The ID of the request that timed out. + request_id: Vec, + }, + + /// An error occurred while interacting with the RPC server. + #[error("RPC error")] + RpcError(#[from] Status), + + /// An unknown error occurred. + #[error("Other error: {0}")] + Other(#[from] anyhow::Error), +} diff --git a/crates/sdk/src/network/mod.rs b/crates/sdk/src/network/mod.rs index 6cc201f32..2ad3585be 100644 --- a/crates/sdk/src/network/mod.rs +++ b/crates/sdk/src/network/mod.rs @@ -11,9 +11,12 @@ mod sign_message; #[allow(clippy::too_many_lines)] pub mod proto; pub mod builder; +mod error; pub mod prove; pub mod utils; +pub use error::*; + pub use crate::network::client::NetworkClient; pub use crate::network::proto::network::FulfillmentStrategy; diff --git a/crates/sdk/src/network/proto/artifact.rs b/crates/sdk/src/network/proto/artifact.rs index e1ff3ad03..bda90769e 100644 --- a/crates/sdk/src/network/proto/artifact.rs +++ b/crates/sdk/src/network/proto/artifact.rs @@ -4,6 +4,9 @@ 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, + /// The type of artifact to create. + #[prost(enumeration = "ArtifactType", tag = "2")] + pub artifact_type: i32, } #[derive(serde::Serialize, serde::Deserialize, Clone, PartialEq, ::prost::Message)] pub struct CreateArtifactResponse { @@ -14,11 +17,58 @@ pub struct CreateArtifactResponse { #[prost(string, tag = "2")] pub artifact_presigned_url: ::prost::alloc::string::String, } +#[derive( + serde::Serialize, + serde::Deserialize, + Clone, + Copy, + Debug, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, + ::prost::Enumeration, +)] +#[repr(i32)] +pub enum ArtifactType { + UnspecifiedArtifactType = 0, + /// A program artifact. + Program = 1, + /// A stdin artifact. + Stdin = 2, + /// A proof artifact. + Proof = 3, +} +impl ArtifactType { + /// 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::UnspecifiedArtifactType => "UNSPECIFIED_ARTIFACT_TYPE", + Self::Program => "PROGRAM", + Self::Stdin => "STDIN", + Self::Proof => "PROOF", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "UNSPECIFIED_ARTIFACT_TYPE" => Some(Self::UnspecifiedArtifactType), + "PROGRAM" => Some(Self::Program), + "STDIN" => Some(Self::Stdin), + "PROOF" => Some(Self::Proof), + _ => None, + } + } +} /// 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::{Body, Bytes, CompressionEncoding, GrpcMethod, InterceptedService, StdError, http}; + use tonic::codegen::*; #[derive(Debug, Clone)] pub struct ArtifactStoreClient { inner: tonic::client::Grpc, @@ -57,11 +107,11 @@ pub mod artifact_store_client { F: tonic::service::Interceptor, T::ResponseBody: Default, T: tonic::codegen::Service< - http::Request, - Response = http::Response< - >::ResponseBody, - >, + http::Request, + Response = http::Response< + >::ResponseBody, >, + >, >>::Error: Into + std::marker::Send + std::marker::Sync, { @@ -123,7 +173,7 @@ pub mod artifact_store_client { /// Generated server implementations. pub mod artifact_store_server { #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)] - use tonic::codegen::{Arc, Body, BoxFuture, CompressionEncoding, Context, EnabledCompressionEncodings, InterceptedService, Poll, StdError, async_trait, empty_body, http}; + 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 { diff --git a/crates/sdk/src/network/proto/network.rs b/crates/sdk/src/network/proto/network.rs index 52691b93a..6c411f84a 100644 --- a/crates/sdk/src/network/proto/network.rs +++ b/crates/sdk/src/network/proto/network.rs @@ -254,20 +254,28 @@ pub struct ProofRequest { /// The unix timestamp of when the request was updated. #[prost(uint64, tag = "19")] pub updated_at: u64, - /// The unix timestamp of when the request was fulfilled. + /// The unix timestamp of when the request was fulfilled. Only included if + /// the request has a fulfillment status of FULFILLED. #[prost(uint64, optional, tag = "20")] pub fulfilled_at: ::core::option::Option, /// The transaction hash of the request. #[prost(bytes = "vec", tag = "21")] pub tx_hash: ::prost::alloc::vec::Vec, - /// The cycle count for the request. + /// The cycle used during the execution of the request. Only included if the + /// request has an execution status of EXECUTED. #[prost(uint64, optional, tag = "22")] pub cycles: ::core::option::Option, - /// The amount deducted from the fulfiller's balance. - #[prost(string, optional, tag = "23")] - pub deduction_amount: ::core::option::Option<::prost::alloc::string::String>, - /// The amount refunded to the fulfiller's balance. + /// The public values hash from the execution of the request. Only included if + /// the request has an execution status of EXECUTED. + #[prost(bytes = "vec", optional, tag = "23")] + pub public_values_hash: ::core::option::Option<::prost::alloc::vec::Vec>, + /// The amount deducted from the fulfiller's balance. Only included if the + /// request has a fulfillment status of ASSIGNED. #[prost(string, optional, tag = "24")] + pub deduction_amount: ::core::option::Option<::prost::alloc::string::String>, + /// The amount refunded to the fulfiller's balance. Only included if the + /// request has a fulfillment status of EXECUTED. + #[prost(string, optional, tag = "25")] pub refund_amount: ::core::option::Option<::prost::alloc::string::String>, } #[derive(serde::Serialize, serde::Deserialize, Clone, PartialEq, ::prost::Message)] @@ -287,14 +295,22 @@ pub struct GetProofRequestStatusResponse { /// The transaction hash of the request. #[prost(bytes = "vec", tag = "3")] pub request_tx_hash: ::prost::alloc::vec::Vec, + /// The deadline of the request. A request should be ignored if it is past + /// its deadline. + #[prost(uint64, tag = "4")] + pub deadline: u64, /// The optional transaction hash of the proof fulfill. Only included if the /// request has a fulfillment status of FULFILLED. - #[prost(bytes = "vec", optional, tag = "4")] + #[prost(bytes = "vec", optional, tag = "5")] pub fulfill_tx_hash: ::core::option::Option<::prost::alloc::vec::Vec>, /// The optional proof URI, where you can download the result of the request. /// Only included if the request has a fulfillment status of FULFILLED. - #[prost(string, optional, tag = "5")] + #[prost(string, optional, tag = "6")] pub proof_uri: ::core::option::Option<::prost::alloc::string::String>, + /// The optional public values hash from the execution of the request. Only + /// included if the request has an execution status of EXECUTED. + #[prost(bytes = "vec", optional, tag = "7")] + pub public_values_hash: ::core::option::Option<::prost::alloc::vec::Vec>, } #[derive(serde::Serialize, serde::Deserialize, Clone, PartialEq, ::prost::Message)] pub struct GetProofRequestDetailsRequest { @@ -557,6 +573,38 @@ pub struct RemoveDelegationResponse { #[derive(serde::Serialize, serde::Deserialize, Clone, Copy, PartialEq, ::prost::Message)] pub struct RemoveDelegationResponseBody {} #[derive(serde::Serialize, serde::Deserialize, Clone, PartialEq, ::prost::Message)] +pub struct TerminateDelegationRequest { + /// The message format of the body. + #[prost(enumeration = "MessageFormat", tag = "1")] + pub format: i32, + /// The signature of the sender. + #[prost(bytes = "vec", tag = "2")] + 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 TerminateDelegationRequestBody { + /// The account nonce of the sender. + #[prost(uint64, tag = "1")] + pub nonce: u64, + /// The address of the owner whose delegation to terminate. + #[prost(bytes = "vec", tag = "2")] + pub owner: ::prost::alloc::vec::Vec, +} +#[derive(serde::Serialize, serde::Deserialize, Clone, PartialEq, ::prost::Message)] +pub struct TerminateDelegationResponse { + /// 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 TerminateDelegationResponseBody {} +#[derive(serde::Serialize, serde::Deserialize, Clone, PartialEq, ::prost::Message)] pub struct AcceptDelegationRequest { /// The message format of the body. #[prost(enumeration = "MessageFormat", tag = "1")] @@ -949,14 +997,17 @@ pub struct Reservation { #[prost(uint64, tag = "5")] pub created_at: u64, } -#[derive(serde::Serialize, serde::Deserialize, Clone, Copy, PartialEq, ::prost::Message)] +#[derive(serde::Serialize, serde::Deserialize, Clone, PartialEq, ::prost::Message)] pub struct GetFilteredReservationsRequest { + /// Requester address to filter for. + #[prost(bytes = "vec", optional, tag = "1")] + pub requester: ::core::option::Option<::prost::alloc::vec::Vec>, /// The optional maximum number of reservations to return (default is 10, /// maximum is 100). - #[prost(uint32, optional, tag = "1")] + #[prost(uint32, optional, tag = "2")] pub limit: ::core::option::Option, /// The optional page number to return (default is 1). - #[prost(uint32, optional, tag = "2")] + #[prost(uint32, optional, tag = "3")] pub page: ::core::option::Option, } #[derive(serde::Serialize, serde::Deserialize, Clone, PartialEq, ::prost::Message)] @@ -1120,19 +1171,19 @@ pub enum MessageFormat { Json = 2, } impl MessageFormat { - /// String value of the enum field names used in the `ProtoBuf` definition. + /// 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. - #[must_use] pub fn as_str_name(&self) -> &'static str { + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { match self { Self::UnspecifiedMessageFormat => "UNSPECIFIED_MESSAGE_FORMAT", Self::Binary => "BINARY", Self::Json => "JSON", } } - /// Creates an enum from field names used in the `ProtoBuf` definition. - #[must_use] pub fn from_str_name(value: &str) -> ::core::option::Option { + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { match value { "UNSPECIFIED_MESSAGE_FORMAT" => Some(Self::UnspecifiedMessageFormat), "BINARY" => Some(Self::Binary), @@ -1167,11 +1218,11 @@ pub enum ProofMode { Groth16 = 4, } impl ProofMode { - /// String value of the enum field names used in the `ProtoBuf` definition. + /// 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. - #[must_use] pub fn as_str_name(&self) -> &'static str { + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { match self { Self::UnspecifiedProofMode => "UNSPECIFIED_PROOF_MODE", Self::Core => "CORE", @@ -1180,8 +1231,8 @@ impl ProofMode { Self::Groth16 => "GROTH16", } } - /// Creates an enum from field names used in the `ProtoBuf` definition. - #[must_use] pub fn from_str_name(value: &str) -> ::core::option::Option { + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { match value { "UNSPECIFIED_PROOF_MODE" => Some(Self::UnspecifiedProofMode), "CORE" => Some(Self::Core), @@ -1219,11 +1270,11 @@ pub enum FulfillmentStrategy { Auction = 3, } impl FulfillmentStrategy { - /// String value of the enum field names used in the `ProtoBuf` definition. + /// 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. - #[must_use] pub fn as_str_name(&self) -> &'static str { + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { match self { Self::UnspecifiedFulfillmentStrategy => "UNSPECIFIED_FULFILLMENT_STRATEGY", Self::Hosted => "HOSTED", @@ -1231,8 +1282,8 @@ impl FulfillmentStrategy { Self::Auction => "AUCTION", } } - /// Creates an enum from field names used in the `ProtoBuf` definition. - #[must_use] pub fn from_str_name(value: &str) -> ::core::option::Option { + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { match value { "UNSPECIFIED_FULFILLMENT_STRATEGY" => Some(Self::UnspecifiedFulfillmentStrategy), "HOSTED" => Some(Self::Hosted), @@ -1269,11 +1320,11 @@ pub enum FulfillmentStatus { Unfulfillable = 4, } impl FulfillmentStatus { - /// String value of the enum field names used in the `ProtoBuf` definition. + /// 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. - #[must_use] pub fn as_str_name(&self) -> &'static str { + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { match self { Self::UnspecifiedFulfillmentStatus => "UNSPECIFIED_FULFILLMENT_STATUS", Self::Requested => "REQUESTED", @@ -1282,8 +1333,8 @@ impl FulfillmentStatus { Self::Unfulfillable => "UNFULFILLABLE", } } - /// Creates an enum from field names used in the `ProtoBuf` definition. - #[must_use] pub fn from_str_name(value: &str) -> ::core::option::Option { + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { match value { "UNSPECIFIED_FULFILLMENT_STATUS" => Some(Self::UnspecifiedFulfillmentStatus), "REQUESTED" => Some(Self::Requested), @@ -1319,11 +1370,11 @@ pub enum ExecutionStatus { Unexecutable = 3, } impl ExecutionStatus { - /// String value of the enum field names used in the `ProtoBuf` definition. + /// 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. - #[must_use] pub fn as_str_name(&self) -> &'static str { + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { match self { Self::UnspecifiedExecutionStatus => "UNSPECIFIED_EXECUTION_STATUS", Self::Unexecuted => "UNEXECUTED", @@ -1331,8 +1382,8 @@ impl ExecutionStatus { Self::Unexecutable => "UNEXECUTABLE", } } - /// Creates an enum from field names used in the `ProtoBuf` definition. - #[must_use] pub fn from_str_name(value: &str) -> ::core::option::Option { + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { match value { "UNSPECIFIED_EXECUTION_STATUS" => Some(Self::UnspecifiedExecutionStatus), "UNEXECUTED" => Some(Self::Unexecuted), @@ -1373,11 +1424,11 @@ pub enum BalanceOperation { Bid = 6, } impl BalanceOperation { - /// String value of the enum field names used in the `ProtoBuf` definition. + /// 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. - #[must_use] pub fn as_str_name(&self) -> &'static str { + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { match self { Self::UnspecifiedBalanceChangeOperation => "UNSPECIFIED_BALANCE_CHANGE_OPERATION", Self::Deposit => "DEPOSIT", @@ -1388,8 +1439,8 @@ impl BalanceOperation { Self::Bid => "BID", } } - /// Creates an enum from field names used in the `ProtoBuf` definition. - #[must_use] pub fn from_str_name(value: &str) -> ::core::option::Option { + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { match value { "UNSPECIFIED_BALANCE_CHANGE_OPERATION" => Some(Self::UnspecifiedBalanceChangeOperation), "DEPOSIT" => Some(Self::Deposit), @@ -1406,7 +1457,7 @@ impl BalanceOperation { pub mod prover_network_client { #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)] use tonic::codegen::http::Uri; - use tonic::codegen::{Body, Bytes, CompressionEncoding, GrpcMethod, InterceptedService, StdError, http}; + use tonic::codegen::*; #[derive(Debug, Clone)] pub struct ProverNetworkClient { inner: tonic::client::Grpc, @@ -1806,6 +1857,26 @@ pub mod prover_network_client { .insert(GrpcMethod::new("network.ProverNetwork", "RemoveDelegation")); self.inner.unary(req, path, codec).await } + /// Terminate a delegation. Only callable by the delegate of a delegation. + pub async fn terminate_delegation( + &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/TerminateDelegation"); + let mut req = request.into_request(); + req.extensions_mut() + .insert(GrpcMethod::new("network.ProverNetwork", "TerminateDelegation")); + self.inner.unary(req, path, codec).await + } /// Accept a delegation. Only callable by the delegate of a delegation. pub async fn accept_delegation( &mut self, @@ -2181,7 +2252,7 @@ pub mod prover_network_client { /// Generated server implementations. pub mod prover_network_server { #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)] - use tonic::codegen::{Arc, Body, BoxFuture, CompressionEncoding, Context, EnabledCompressionEncodings, InterceptedService, Poll, StdError, async_trait, empty_body, http}; + 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 { @@ -2277,6 +2348,11 @@ pub mod prover_network_server { &self, request: tonic::Request, ) -> std::result::Result, tonic::Status>; + /// Terminate a delegation. Only callable by the delegate of a delegation. + async fn terminate_delegation( + &self, + request: tonic::Request, + ) -> std::result::Result, tonic::Status>; /// Accept a delegation. Only callable by the delegate of a delegation. async fn accept_delegation( &self, @@ -3123,6 +3199,48 @@ pub mod prover_network_server { }; Box::pin(fut) } + "/network.ProverNetwork/TerminateDelegation" => { + #[allow(non_camel_case_types)] + struct TerminateDelegationSvc(pub Arc); + impl + tonic::server::UnaryService + for TerminateDelegationSvc + { + type Response = super::TerminateDelegationResponse; + type Future = BoxFuture, tonic::Status>; + fn call( + &mut self, + request: tonic::Request, + ) -> Self::Future { + let inner = Arc::clone(&self.0); + let fut = async move { + ::terminate_delegation(&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 = TerminateDelegationSvc(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/AcceptDelegation" => { #[allow(non_camel_case_types)] struct AcceptDelegationSvc(pub Arc); diff --git a/crates/sdk/src/network/prover.rs b/crates/sdk/src/network/prover.rs index 4927acca3..f3be1b04d 100644 --- a/crates/sdk/src/network/prover.rs +++ b/crates/sdk/src/network/prover.rs @@ -5,11 +5,12 @@ use std::time::{Duration, Instant}; +use super::proto::network::GetProofRequestStatusResponse; use super::prove::NetworkProveBuilder; use super::DEFAULT_CYCLE_LIMIT; use crate::cpu::execute::CpuExecuteBuilder; use crate::cpu::CpuProver; -use crate::network::{DEFAULT_PROVER_NETWORK_RPC, DEFAULT_TIMEOUT_SECS}; +use crate::network::{Error, DEFAULT_PROVER_NETWORK_RPC, DEFAULT_TIMEOUT_SECS}; use crate::{ network::client::NetworkClient, network::proto::network::{ExecutionStatus, FulfillmentStatus, FulfillmentStrategy, ProofMode}, @@ -193,7 +194,7 @@ impl NetworkProver { /// 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(crate) async fn wait_proof( + pub async fn wait_proof( &self, request_id: &[u8], timeout: Option, @@ -205,25 +206,36 @@ impl NetworkProver { // Calculate the remaining timeout. if let Some(timeout) = timeout { if start_time.elapsed() > timeout { - return Err(anyhow::anyhow!("proof request timed out.")); + return Err(Error::RequestTimedOut { request_id: request_id.to_vec() }.into()); } } let remaining_timeout = timeout.map(|t| { let elapsed = start_time.elapsed(); - if elapsed < t { t - elapsed } else { Duration::from_secs(0) } + if elapsed < t { + t - elapsed + } else { + Duration::from_secs(0) + } }); - // Get status with retries. + // Get the status with retries. let (status, maybe_proof) = with_retry( - || async { self.client.get_proof_request_status::

(request_id).await }, + || async { self.client.get_proof_request_status(request_id).await }, remaining_timeout, - "getting proof request status", + "getting proof status", ) .await?; + // Check the deadline. + if status.deadline < Instant::now().elapsed().as_secs() { + return Err(Error::RequestTimedOut { request_id: request_id.to_vec() }.into()); + } + // Check the execution status. - if status.execution_status == ExecutionStatus::Unexecutable as i32 { - return Err(anyhow::anyhow!("proof request is unexecutable")); + if let Ok(ExecutionStatus::Unexecutable) = + ExecutionStatus::try_from(status.execution_status) + { + return Err(Error::RequestUnexecutable { request_id: request_id.to_vec() }.into()); } // Check the fulfillment status. @@ -233,12 +245,14 @@ impl NetworkProver { } Ok(FulfillmentStatus::Assigned) => { if !is_assigned { - log::info!("proof request assigned, proving..."); + log::info!("Proof request assigned, proving..."); is_assigned = true; } } Ok(FulfillmentStatus::Unfulfillable) => { - return Err(anyhow::anyhow!("proof request is unfulfillable")); + return Err( + Error::RequestUnfulfillable { request_id: request_id.to_vec() }.into() + ); } _ => {} } @@ -269,9 +283,11 @@ impl NetworkProver { if skip_simulation { Ok(DEFAULT_CYCLE_LIMIT) } else { - let (_, report) = self.prover.inner().execute(elf, stdin, SP1Context::default())?; - let cycles = report.total_instruction_count(); - Ok(cycles) + self.prover + .inner() + .execute(elf, stdin, SP1Context::default()) + .map(|(_, report)| report.total_instruction_count()) + .map_err(|_| Error::SimulationFailed.into()) } } }