mina_tree/scan_state/transaction_logic/
zkapp_statement.rs1use super::zkapp_command::{self, AccountUpdate, CallForest, Tree};
2use ark_ff::Zero;
3use mina_curves::pasta::Fp;
4use mina_hasher::{Hashable, ROInput};
5use mina_signer::NetworkId;
6use poseidon::hash::{hash_with_kimchi, params::MINA_ACCOUNT_UPDATE_CONS};
7
8#[derive(Copy, Clone, Debug, derive_more::Deref, derive_more::From)]
9pub struct TransactionCommitment(pub Fp);
10
11impl TransactionCommitment {
12 pub fn create(account_updates_hash: Fp) -> Self {
14 Self(account_updates_hash)
15 }
16
17 pub fn create_complete(&self, memo_hash: Fp, fee_payer_hash: Fp) -> Self {
19 Self(hash_with_kimchi(
20 &MINA_ACCOUNT_UPDATE_CONS,
21 &[memo_hash, fee_payer_hash, self.0],
22 ))
23 }
24
25 pub fn empty() -> Self {
26 Self(Fp::zero())
27 }
28}
29
30impl Hashable for TransactionCommitment {
31 type D = NetworkId;
32
33 fn to_roinput(&self) -> ROInput {
34 let mut roi = ROInput::new();
35 roi = roi.append_field(self.0);
36 roi
37 }
38
39 fn domain_string(network_id: NetworkId) -> Option<String> {
40 match network_id {
41 NetworkId::MAINNET => mina_core::network::mainnet::SIGNATURE_PREFIX,
42 NetworkId::TESTNET => mina_core::network::devnet::SIGNATURE_PREFIX,
43 }
44 .to_string()
45 .into()
46 }
47}
48
49#[derive(Clone, Debug)]
50pub struct ZkappStatement {
51 pub account_update: TransactionCommitment,
52 pub calls: TransactionCommitment,
53}
54
55impl ZkappStatement {
56 pub fn to_field_elements(&self) -> Vec<Fp> {
57 let Self {
58 account_update,
59 calls,
60 } = self;
61
62 vec![**account_update, **calls]
63 }
64
65 pub fn of_tree<AccUpdate: Clone + zkapp_command::AccountUpdateRef>(
66 tree: &Tree<AccUpdate>,
67 ) -> Self {
68 let Tree {
69 account_update: _,
70 account_update_digest,
71 calls,
72 } = tree;
73
74 Self {
75 account_update: TransactionCommitment(account_update_digest.get().unwrap()),
76 calls: TransactionCommitment(calls.hash()),
77 }
78 }
79
80 pub fn zkapp_statements_of_forest_prime<Data: Clone>(
81 forest: CallForest<(AccountUpdate, Data)>,
82 ) -> CallForest<(AccountUpdate, (Data, Self))> {
83 forest.map_with_trees_to(|(account_update, data), tree| {
84 (account_update.clone(), (data.clone(), Self::of_tree(tree)))
85 })
86 }
87
88 fn zkapp_statements_of_forest(
89 forest: CallForest<AccountUpdate>,
90 ) -> CallForest<(AccountUpdate, Self)> {
91 forest
92 .map_with_trees_to(|account_update, tree| (account_update.clone(), Self::of_tree(tree)))
93 }
94}