mina_tree/generators/
zkapp_command_builder.rs

1use std::collections::HashMap;
2
3use mina_signer::{Keypair, Signature};
4
5use crate::scan_state::transaction_logic::{
6    for_tests::HashableCompressedPubKey,
7    zkapp_command::{AccountUpdate, Control, ZkAppCommand},
8    zkapp_statement::TransactionCommitment,
9};
10
11pub fn get_transaction_commitments(
12    zkapp_command: &ZkAppCommand,
13) -> (TransactionCommitment, TransactionCommitment) {
14    let memo_hash = zkapp_command.memo.hash();
15    let account_updates_hash = zkapp_command.account_updates_hash();
16    let fee_payer_hash = AccountUpdate::of_fee_payer(zkapp_command.fee_payer.clone()).digest();
17
18    let txn_commitment = TransactionCommitment::create(account_updates_hash);
19    let full_txn_commitment = txn_commitment.create_complete(memo_hash, fee_payer_hash);
20
21    (txn_commitment, full_txn_commitment)
22}
23
24/// Replace dummy signatures, proofs with valid ones for fee payer, other zkapp_command
25/// `keymap` maps compressed public keys to private keys
26///
27/// <https://github.com/MinaProtocol/mina/blob/f7f6700332bdfca77d9f3303e9cf3bc25f997e09/src/lib/zkapp_command_builder/zkapp_command_builder.ml#L94>
28pub fn replace_authorizations(
29    prover: Option<()>, // TODO: We don't support that yet
30    keymap: &HashMap<HashableCompressedPubKey, Keypair>,
31    zkapp_command: &mut ZkAppCommand,
32) {
33    let (txn_commitment, full_txn_commitment) = get_transaction_commitments(zkapp_command);
34
35    let sign_for_account_update = |use_full_commitment: bool, _kp: &Keypair| {
36        let _commitment = if use_full_commitment {
37            full_txn_commitment
38        } else {
39            txn_commitment
40        };
41
42        // TODO: Really sign the zkapp
43        Signature::dummy()
44    };
45
46    let fee_payer_kp = keymap
47        .get(&HashableCompressedPubKey(
48            zkapp_command.fee_payer.body.public_key.clone(),
49        ))
50        .unwrap();
51
52    let fee_payer_signature = sign_for_account_update(true, fee_payer_kp);
53
54    zkapp_command.fee_payer.authorization = fee_payer_signature;
55
56    let account_updates_with_valid_signatures =
57        zkapp_command.account_updates.map_to(|account_update| {
58            let AccountUpdate {
59                body,
60                authorization,
61            } = account_update;
62
63            let authorization_with_valid_signature = match authorization {
64                Control::Signature(_dummy) => {
65                    let pk = &body.public_key;
66                    let kp = keymap
67                        .get(&HashableCompressedPubKey(pk.clone()))
68                        .expect("Could not find private key for public key in keymap");
69
70                    let use_full_commitment = body.use_full_commitment;
71                    let signature = sign_for_account_update(use_full_commitment, kp);
72                    Control::Signature(signature)
73                }
74                Control::Proof(_) => match prover {
75                    None => authorization.clone(),
76                    Some(_prover) => todo!(), // TODO
77                },
78                Control::NoneGiven => authorization.clone(),
79            };
80
81            AccountUpdate {
82                authorization: authorization_with_valid_signature,
83                ..account_update.clone()
84            }
85        });
86
87    zkapp_command.account_updates = account_updates_with_valid_signatures;
88}