openmina_core/snark/
snark_job_id.rs1use std::str::FromStr;
2
3use mina_p2p_messages::{
4 binprot::macros::{BinProtRead, BinProtWrite},
5 v2::{
6 LedgerHash, MinaStateBlockchainStateValueStableV2LedgerProofStatementSource,
7 TransactionSnarkWorkTStableV2Proofs,
8 },
9};
10use serde::{ser::SerializeStruct, Deserialize, Serialize};
11
12pub type SnarkJobId = LedgerHashTransition;
13
14#[derive(BinProtWrite, BinProtRead, Debug, Ord, PartialOrd, Eq, PartialEq, Clone)]
15pub struct LedgerHashTransition {
16 pub source: LedgerHashTransitionPasses,
17 pub target: LedgerHashTransitionPasses,
18}
19
20#[derive(
21 BinProtWrite, BinProtRead, Serialize, Deserialize, Debug, Ord, PartialOrd, Eq, PartialEq, Clone,
22)]
23pub struct LedgerHashTransitionPasses {
24 pub first_pass_ledger: LedgerHash,
25 pub second_pass_ledger: LedgerHash,
26}
27
28impl std::fmt::Display for LedgerHashTransition {
29 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
30 write!(f, "{}-{}", &self.source, &self.target)
31 }
32}
33
34impl std::str::FromStr for LedgerHashTransition {
35 type Err = ();
36
37 fn from_str(s: &str) -> Result<Self, Self::Err> {
38 let (source, target) = s.split_once('-').ok_or(())?;
39 Ok(Self {
40 source: source.parse()?,
41 target: target.parse()?,
42 })
43 }
44}
45
46impl std::fmt::Display for LedgerHashTransitionPasses {
47 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
48 write!(
49 f,
50 "{}_{}",
51 &self.first_pass_ledger, &self.second_pass_ledger
52 )
53 }
54}
55
56impl FromStr for LedgerHashTransitionPasses {
57 type Err = ();
58
59 fn from_str(s: &str) -> Result<Self, Self::Err> {
60 let (first_pass, second_pass) = s.split_once('_').ok_or(())?;
61 Ok(Self {
62 first_pass_ledger: first_pass.parse().or(Err(()))?,
63 second_pass_ledger: second_pass.parse().or(Err(()))?,
64 })
65 }
66}
67
68impl Serialize for LedgerHashTransition {
69 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
70 where
71 S: serde::Serializer,
72 {
73 if serializer.is_human_readable() {
74 self.to_string().serialize(serializer)
75 } else {
76 let mut s = serializer.serialize_struct("LedgerHashTransition", 2)?;
77 s.serialize_field("source", &self.source)?;
78 s.serialize_field("target", &self.target)?;
79 s.end()
80 }
81 }
82}
83
84impl<'de> Deserialize<'de> for LedgerHashTransition {
85 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
86 where
87 D: serde::Deserializer<'de>,
88 {
89 use serde::de::Error;
90 if deserializer.is_human_readable() {
91 let s: String = Deserialize::deserialize(deserializer)?;
92 Self::from_str(&s).map_err(|_| Error::custom("decode from str failed"))
93 } else {
94 #[derive(Deserialize)]
95 struct LedgerHashTransition {
96 pub source: LedgerHashTransitionPasses,
97 pub target: LedgerHashTransitionPasses,
98 }
99 let v: LedgerHashTransition = Deserialize::deserialize(deserializer)?;
100 Ok(Self {
101 source: v.source,
102 target: v.target,
103 })
104 }
105 }
106}
107
108impl From<&TransactionSnarkWorkTStableV2Proofs> for SnarkJobId {
109 fn from(value: &TransactionSnarkWorkTStableV2Proofs) -> Self {
110 let (first, second) = match value {
111 TransactionSnarkWorkTStableV2Proofs::One(j) => (j, j),
112 TransactionSnarkWorkTStableV2Proofs::Two((j1, j2)) => (j1, j2),
113 };
114
115 (&first.0.statement.source, &second.0.statement.target).into()
116 }
117}
118
119impl
120 From<(
121 &MinaStateBlockchainStateValueStableV2LedgerProofStatementSource,
122 &MinaStateBlockchainStateValueStableV2LedgerProofStatementSource,
123 )> for SnarkJobId
124{
125 fn from(
126 (source, target): (
127 &MinaStateBlockchainStateValueStableV2LedgerProofStatementSource,
128 &MinaStateBlockchainStateValueStableV2LedgerProofStatementSource,
129 ),
130 ) -> Self {
131 let source = LedgerHashTransitionPasses {
132 first_pass_ledger: source.first_pass_ledger.clone(),
133 second_pass_ledger: source.second_pass_ledger.clone(),
134 };
135 let target = LedgerHashTransitionPasses {
136 first_pass_ledger: target.first_pass_ledger.clone(),
137 second_pass_ledger: target.second_pass_ledger.clone(),
138 };
139
140 LedgerHashTransition { source, target }
141 }
142}
143
144#[cfg(test)]
145mod tests {
146 use super::*;
147
148 #[test]
149 fn test_snark_job_id_to_string_from_string() {
150 let s = "jw9nPCs68UNaKaLZwV6QzdswKWomwQxvTgrpmKWmnFJyswnrn4N_jwhHYWzvJG8esmqtYXbUZy3UGbLSjhKvn1FSxBGL1JDFHqbHMJc-jwiLuRrEqNgASgXEqibGs4VqKwSwiuFEtuPD53v8hiTtVuLfmTr_jwhHYWzvJG8esmqtYXbUZy3UGbLSjhKvn1FSxBGL1JDFHqbHMJc";
151 let decoded = SnarkJobId::from_str(s).unwrap();
152 assert_eq!(decoded.to_string(), s);
153 }
154}