penumbra_sdk_transaction/
witness_data.rs1use std::collections::BTreeMap;
2
3use penumbra_sdk_proto::{core::transaction::v1 as pb, DomainType};
4use penumbra_sdk_shielded_pool::note;
5use penumbra_sdk_tct as tct;
6use serde::{Deserialize, Serialize};
7
8#[derive(Clone, Debug, Serialize, Deserialize)]
9#[serde(try_from = "pb::WitnessData", into = "pb::WitnessData")]
10pub struct WitnessData {
11 pub anchor: tct::Root,
12 pub state_commitment_proofs: BTreeMap<note::StateCommitment, tct::Proof>,
13}
14
15impl WitnessData {
16 pub fn add_proof(&mut self, nc: note::StateCommitment, proof: tct::Proof) {
18 self.state_commitment_proofs.insert(nc, proof);
19 }
20}
21
22impl DomainType for WitnessData {
23 type Proto = pb::WitnessData;
24}
25
26impl From<WitnessData> for pb::WitnessData {
27 fn from(msg: WitnessData) -> Self {
28 Self {
29 anchor: Some(msg.anchor.into()),
30 state_commitment_proofs: msg
31 .state_commitment_proofs
32 .into_values()
33 .map(|v| v.into())
34 .collect(),
35 }
36 }
37}
38
39impl TryFrom<pb::WitnessData> for WitnessData {
40 type Error = anyhow::Error;
41
42 fn try_from(msg: pb::WitnessData) -> Result<Self, Self::Error> {
43 let mut state_commitment_proofs = BTreeMap::new();
44 for proof in msg.state_commitment_proofs {
45 let tct_proof: tct::Proof = proof.try_into()?;
46 state_commitment_proofs.insert(tct_proof.commitment(), tct_proof);
47 }
48 Ok(Self {
49 anchor: msg
50 .anchor
51 .ok_or_else(|| anyhow::anyhow!("missing anchor"))?
52 .try_into()?,
53 state_commitment_proofs,
54 })
55 }
56}