penumbra_sdk_view/
swap_record.rs

1use penumbra_sdk_dex::{swap::SwapPlaintext, BatchSwapOutputData};
2use penumbra_sdk_proto::{view::v1 as pb, DomainType};
3use penumbra_sdk_sct::{CommitmentSource, Nullifier};
4use penumbra_sdk_tct as tct;
5
6use r2d2_sqlite::rusqlite::Row;
7use serde::{Deserialize, Serialize};
8
9#[derive(Serialize, Deserialize, Debug, Clone)]
10#[serde(try_from = "pb::SwapRecord", into = "pb::SwapRecord")]
11pub struct SwapRecord {
12    pub swap_commitment: tct::StateCommitment,
13    pub swap: SwapPlaintext,
14    pub position: tct::Position,
15    pub nullifier: Nullifier,
16    pub output_data: BatchSwapOutputData,
17    pub height_claimed: Option<u64>,
18    pub source: CommitmentSource,
19}
20impl DomainType for SwapRecord {
21    type Proto = pb::SwapRecord;
22}
23impl From<SwapRecord> for pb::SwapRecord {
24    fn from(msg: SwapRecord) -> Self {
25        pb::SwapRecord {
26            swap_commitment: Some(msg.swap_commitment.into()),
27            swap: Some(msg.swap.into()),
28            position: msg.position.into(),
29            nullifier: Some(msg.nullifier.into()),
30            output_data: Some(msg.output_data.into()),
31            height_claimed: msg.height_claimed.unwrap_or(0),
32            source: Some(msg.source.into()),
33        }
34    }
35}
36
37impl TryFrom<pb::SwapRecord> for SwapRecord {
38    type Error = anyhow::Error;
39    fn try_from(value: pb::SwapRecord) -> Result<Self, Self::Error> {
40        Ok(Self {
41            swap_commitment: value
42                .swap_commitment
43                .ok_or_else(|| anyhow::anyhow!("missing swap_commitment"))?
44                .try_into()?,
45            swap: value
46                .swap
47                .ok_or_else(|| anyhow::anyhow!("missing swap"))?
48                .try_into()?,
49            position: value.position.into(),
50            nullifier: value
51                .nullifier
52                .ok_or_else(|| anyhow::anyhow!("missing nullifier"))?
53                .try_into()?,
54            output_data: value
55                .output_data
56                .ok_or_else(|| anyhow::anyhow!("missing output_data"))?
57                .try_into()?,
58            height_claimed: if value.height_claimed > 0 {
59                Some(value.height_claimed)
60            } else {
61                None
62            },
63            source: value
64                .source
65                .ok_or_else(|| anyhow::anyhow!("missing source"))?
66                .try_into()?,
67        })
68    }
69}
70
71impl TryFrom<&Row<'_>> for SwapRecord {
72    type Error = anyhow::Error;
73
74    fn try_from(row: &Row<'_>) -> Result<Self, Self::Error> {
75        Ok(Self {
76            swap_commitment: row.get::<_, Vec<u8>>("swap_commitment")?[..].try_into()?,
77            height_claimed: row.get("height_claimed")?,
78            position: row.get::<_, u64>("position")?.into(),
79            nullifier: row.get::<_, Vec<u8>>("nullifier")?[..].try_into()?,
80            output_data: BatchSwapOutputData::decode(&row.get::<_, Vec<u8>>("output_data")?[..])?,
81            source: CommitmentSource::decode(&row.get::<_, Vec<u8>>("source")?[..])?,
82            swap: SwapPlaintext::decode(&row.get::<_, Vec<u8>>("swap")?[..])?,
83        })
84    }
85}