1use std::collections::BTreeMap;
2
3use bincode::serialize;
4use sha2::{Digest, Sha256};
5use solana_program::pubkey::Pubkey;
6use solana_sdk::{account::Account, transaction::Transaction};
7
8use crate::{
9 merkle::{merkelize_accounts_root, merkelize_transactions_root},
10 Privacy,
11};
12
13impl Privacy {
14 pub fn commit_inputs(
15 &self,
16 genesis_accounts: &BTreeMap<Pubkey, Account>,
17 transactions: &Vec<Transaction>,
18 ) {
19 match self {
20 Privacy::Transparent => {
21 sp1_zkvm::io::commit::<BTreeMap<Pubkey, Account>>(genesis_accounts);
22 sp1_zkvm::io::commit::<Vec<Transaction>>(transactions);
23 }
24 Privacy::Simple => {
25 let hash = hash_accounts(genesis_accounts);
26 sp1_zkvm::io::commit_slice(&hash);
27
28 let hash = hash_transactions(transactions);
29 sp1_zkvm::io::commit_slice(&hash);
30 }
31 Privacy::Merkle => {
32 let hash = merkelize_accounts_root(genesis_accounts);
33 sp1_zkvm::io::commit_slice(&hash);
34
35 let hash = merkelize_transactions_root(transactions);
36 sp1_zkvm::io::commit_slice(&hash);
37 }
38 };
39 }
40
41 pub fn commit_outputs(&self, accounts: &BTreeMap<Pubkey, Account>) {
42 match self {
43 Privacy::Transparent => {
44 sp1_zkvm::io::commit::<BTreeMap<Pubkey, Account>>(accounts);
45 }
46 Privacy::Simple => {
47 sp1_zkvm::io::commit_slice(&hash_accounts(accounts));
48 }
49 Privacy::Merkle => {
50 sp1_zkvm::io::commit_slice(&merkelize_accounts_root(accounts));
51 }
52 }
53 }
54}
55
56fn hash_accounts(accounts: &BTreeMap<Pubkey, Account>) -> [u8; 32] {
58 let mut account_bytes = Vec::new();
59 for (pubkey, acc) in accounts {
60 account_bytes.extend(pubkey.as_ref());
61 account_bytes.extend(serialize(acc).expect("Failed to serialize account"));
62 }
63
64 let mut hasher = Sha256::new();
65 hasher.update(account_bytes);
66 hasher.finalize().into()
67}
68
69fn hash_transactions(transactions: &Vec<Transaction>) -> [u8; 32] {
70 let mut bytes = Vec::new();
71 for tx in transactions {
72 bytes.extend(serialize(tx).expect("Failed to serialize transaction"));
73 }
74 let mut hasher = Sha256::new();
75 hasher.update(bytes);
76 hasher.finalize().into()
77}