Skip to main content

ethrex_common/types/
prover.rs

1use bytes::Bytes;
2use serde::{Deserialize, Serialize};
3use std::fmt::Display;
4
5/// Enum used to identify the different proving systems.
6#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, Serialize, Deserialize)]
7pub enum ProverType {
8    Exec,
9    RISC0,
10    SP1,
11    TDX,
12}
13
14impl From<ProverType> for u32 {
15    fn from(value: ProverType) -> u32 {
16        match value {
17            ProverType::Exec => 0,
18            ProverType::RISC0 => 1,
19            ProverType::SP1 => 2,
20            ProverType::TDX => 3,
21        }
22    }
23}
24
25impl ProverType {
26    /// Used to iterate through all the possible proving systems
27    pub fn all() -> impl Iterator<Item = ProverType> {
28        [
29            ProverType::Exec,
30            ProverType::RISC0,
31            ProverType::SP1,
32            ProverType::TDX,
33        ]
34        .into_iter()
35    }
36}
37
38impl Display for ProverType {
39    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
40        match self {
41            Self::Exec => write!(f, "Exec"),
42            Self::RISC0 => write!(f, "RISC0"),
43            Self::SP1 => write!(f, "SP1"),
44            Self::TDX => write!(f, "TDX"),
45        }
46    }
47}
48
49/// Raw proof bytes with a prover identifier.
50#[derive(PartialEq, Serialize, Deserialize, Clone, Debug)]
51pub struct ProofBytes {
52    pub prover_type: ProverType,
53    pub proof: Vec<u8>,
54}
55
56/// Output produced by a prover backend.
57///
58/// - [`Proof`](ProverOutput::Proof): just the proof bytes — for L1 and L2
59///   on-chain verification where public values are unnecessary or recoverable.
60/// - [`ProofWithPublicValues`](ProverOutput::ProofWithPublicValues): proof
61///   bytes together with public values — needed by the Aligned Layer
62///   verification path.
63#[derive(PartialEq, Serialize, Deserialize, Clone, Debug)]
64pub enum ProverOutput {
65    Proof(ProofBytes),
66    ProofWithPublicValues {
67        proof_bytes: ProofBytes,
68        public_values: Vec<u8>,
69    },
70}
71
72impl ProverOutput {
73    pub fn prover_type(&self) -> ProverType {
74        match self {
75            Self::Proof(p) => p.prover_type,
76            Self::ProofWithPublicValues { proof_bytes, .. } => proof_bytes.prover_type,
77        }
78    }
79
80    pub fn proof_bytes(&self) -> &ProofBytes {
81        match self {
82            Self::Proof(p) => p,
83            Self::ProofWithPublicValues { proof_bytes, .. } => proof_bytes,
84        }
85    }
86
87    pub fn into_proof_bytes(self) -> ProofBytes {
88        match self {
89            Self::Proof(p) => p,
90            Self::ProofWithPublicValues { proof_bytes, .. } => proof_bytes,
91        }
92    }
93
94    pub fn public_values(&self) -> Option<&[u8]> {
95        match self {
96            Self::Proof(_) => None,
97            Self::ProofWithPublicValues { public_values, .. } => Some(public_values),
98        }
99    }
100}
101
102/// Indicates the prover which proof *format* to generate
103#[derive(Serialize, Deserialize, Clone, Copy, Debug, Default)]
104pub enum ProofFormat {
105    #[default]
106    /// A compressed proof wrapped over groth16. EVM friendly.
107    Groth16,
108    /// Fixed size STARK execution proof.
109    Compressed,
110}
111
112/// Generic enum for the ProverServer <--> ProverClient Communication Protocol.
113///
114/// The type parameter `I` represents the input type sent from server to prover:
115/// - L2 uses `ProverInputData`
116/// - L1 uses `ProgramInput`
117#[allow(clippy::large_enum_variant)]
118#[derive(Serialize, Deserialize)]
119pub enum ProofData<I> {
120    /// The client performs any needed setup steps (e.g. key registration).
121    ProverSetup {
122        prover_type: ProverType,
123        payload: Bytes,
124    },
125
126    /// The Server acknowledges the receipt of the setup and its completion.
127    ProverSetupACK,
128
129    /// The Client requests work from the coordinator.
130    /// The commit hash ensures client and server are compatible.
131    /// The prover_type tells the coordinator which backend the client runs,
132    /// so it can skip work items that already have a proof for that type.
133    InputRequest {
134        commit_hash: String,
135        prover_type: ProverType,
136    },
137
138    /// The Server responds with VersionMismatch when the prover's code version
139    /// does not match the version needed to prove the next work item.
140    VersionMismatch,
141
142    /// The Server responds with ProverTypeNotNeeded when the connecting prover's
143    /// backend type is not in the set of required proof types for this deployment.
144    ProverTypeNotNeeded { prover_type: ProverType },
145
146    /// The Server responds with an InputResponse containing the input data.
147    /// If all fields are None, the Client knows no work is available.
148    InputResponse {
149        id: Option<u64>,
150        input: Option<I>,
151        format: Option<ProofFormat>,
152    },
153
154    /// The Client submits the proof generated by the prover for the specified id.
155    ProofSubmit { id: u64, proof: ProverOutput },
156
157    /// The Server acknowledges the receipt of the proof and updates its state.
158    ProofSubmitACK { id: u64 },
159}
160
161impl<I> ProofData<I> {
162    pub fn prover_setup(prover_type: ProverType, payload: Bytes) -> Self {
163        ProofData::ProverSetup {
164            prover_type,
165            payload,
166        }
167    }
168
169    pub fn prover_setup_ack() -> Self {
170        ProofData::ProverSetupACK
171    }
172
173    pub fn input_request(commit_hash: String, prover_type: ProverType) -> Self {
174        ProofData::InputRequest {
175            commit_hash,
176            prover_type,
177        }
178    }
179
180    pub fn version_mismatch() -> Self {
181        ProofData::VersionMismatch
182    }
183
184    pub fn input_response(id: u64, input: I, format: ProofFormat) -> Self {
185        ProofData::InputResponse {
186            id: Some(id),
187            input: Some(input),
188            format: Some(format),
189        }
190    }
191
192    pub fn empty_input_response() -> Self {
193        ProofData::InputResponse {
194            id: None,
195            input: None,
196            format: None,
197        }
198    }
199
200    pub fn proof_submit(id: u64, proof: ProverOutput) -> Self {
201        ProofData::ProofSubmit { id, proof }
202    }
203
204    pub fn proof_submit_ack(id: u64) -> Self {
205        ProofData::ProofSubmitACK { id }
206    }
207}