openmina_core/snark/
snark.rs

1use std::sync::Arc;
2
3use malloc_size_of::MallocSizeOf;
4use mina_p2p_messages::{
5    binprot::macros::{BinProtRead, BinProtWrite},
6    v2::{
7        CurrencyFeeStableV1, MinaBaseFeeWithProverStableV1,
8        MinaStateBlockchainStateValueStableV2LedgerProofStatement,
9        MinaStateSnarkedLedgerStateStableV2, MinaStateSnarkedLedgerStateWithSokStableV2,
10        NetworkPoolSnarkPoolDiffVersionedStableV2AddSolvedWork1, NonZeroCurvePoint,
11        TransactionSnarkWorkStatementStableV2, TransactionSnarkWorkTStableV2,
12        TransactionSnarkWorkTStableV2Proofs,
13    },
14};
15use serde::{Deserialize, Serialize};
16
17use super::{SnarkInfo, SnarkJobId};
18
19#[derive(BinProtRead, BinProtWrite, Serialize, Deserialize, Debug, Clone)]
20pub struct Snark {
21    pub snarker: NonZeroCurvePoint,
22    pub fee: CurrencyFeeStableV1,
23    pub proofs: Arc<TransactionSnarkWorkTStableV2Proofs>,
24}
25
26impl Snark {
27    pub fn job_id(&self) -> SnarkJobId {
28        (&*self.proofs).into()
29    }
30
31    pub fn info(&self) -> SnarkInfo {
32        SnarkInfo {
33            job_id: self.job_id(),
34            fee: self.fee.clone(),
35            prover: self.snarker.clone(),
36        }
37    }
38
39    pub fn statement(&self) -> TransactionSnarkWorkStatementStableV2 {
40        // TODO(binier): move conversion to mina-p2p-messages-rs
41        fn conv_stmt(
42            stmt: &MinaStateSnarkedLedgerStateWithSokStableV2,
43        ) -> MinaStateSnarkedLedgerStateStableV2 {
44            let v = MinaStateBlockchainStateValueStableV2LedgerProofStatement {
45                source: stmt.source.clone(),
46                target: stmt.target.clone(),
47                connecting_ledger_left: stmt.connecting_ledger_left.clone(),
48                connecting_ledger_right: stmt.connecting_ledger_right.clone(),
49                supply_increase: stmt.supply_increase.clone(),
50                fee_excess: stmt.fee_excess.clone(),
51                sok_digest: (),
52            };
53            MinaStateSnarkedLedgerStateStableV2(v)
54        }
55        match &*self.proofs {
56            TransactionSnarkWorkTStableV2Proofs::One(p) => {
57                TransactionSnarkWorkStatementStableV2::One(conv_stmt(&p.0.statement))
58            }
59            TransactionSnarkWorkTStableV2Proofs::Two((p1, p2)) => {
60                let stmt1 = conv_stmt(&p1.0.statement);
61                let stmt2 = conv_stmt(&p2.0.statement);
62                TransactionSnarkWorkStatementStableV2::Two((stmt1, stmt2))
63            }
64        }
65    }
66
67    pub fn tie_breaker_hash(&self) -> [u8; 32] {
68        super::tie_breaker_hash(&self.job_id(), &self.snarker)
69    }
70}
71
72impl From<TransactionSnarkWorkTStableV2> for Snark {
73    fn from(value: TransactionSnarkWorkTStableV2) -> Self {
74        Self {
75            snarker: value.prover,
76            fee: value.fee,
77            proofs: value.proofs.into(),
78        }
79    }
80}
81
82impl From<Snark> for TransactionSnarkWorkTStableV2 {
83    fn from(value: Snark) -> Self {
84        Self {
85            fee: value.fee,
86            proofs: value.proofs.as_ref().clone(),
87            prover: value.snarker,
88        }
89    }
90}
91
92impl From<NetworkPoolSnarkPoolDiffVersionedStableV2AddSolvedWork1> for Snark {
93    fn from(value: NetworkPoolSnarkPoolDiffVersionedStableV2AddSolvedWork1) -> Self {
94        Self {
95            snarker: value.fee.prover,
96            fee: value.fee.fee,
97            proofs: value.proof.into(),
98        }
99    }
100}
101
102impl From<&Snark> for NetworkPoolSnarkPoolDiffVersionedStableV2AddSolvedWork1 {
103    fn from(value: &Snark) -> Self {
104        Self {
105            proof: (*value.proofs).clone(),
106            fee: MinaBaseFeeWithProverStableV1 {
107                fee: value.fee.clone(),
108                prover: value.snarker.clone(),
109            },
110        }
111    }
112}
113
114impl MallocSizeOf for Snark {
115    fn size_of(&self, ops: &mut malloc_size_of::MallocSizeOfOps) -> usize {
116        usize::from(!ops.have_seen_ptr(Arc::as_ptr(&self.proofs)))
117            * (size_of::<TransactionSnarkWorkTStableV2Proofs>() + self.proofs.size_of(ops))
118    }
119}