penumbra_dex/swap/
payload.rsuse anyhow::anyhow;
use penumbra_keys::FullViewingKey;
use penumbra_proto::penumbra::core::component::dex::v1 as pb;
use serde::{Deserialize, Serialize};
use super::{SwapCiphertext, SwapPlaintext};
#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(try_from = "pb::SwapPayload", into = "pb::SwapPayload")]
pub struct SwapPayload {
pub commitment: penumbra_tct::StateCommitment,
pub encrypted_swap: SwapCiphertext,
}
impl SwapPayload {
pub fn trial_decrypt(&self, fvk: &FullViewingKey) -> Option<SwapPlaintext> {
let swap = self
.encrypted_swap
.decrypt(fvk.outgoing(), self.commitment)
.ok()?;
tracing::debug!(swap_commitment = ?self.commitment, ?swap, "found swap while scanning");
if swap.swap_commitment() != self.commitment {
tracing::warn!("decrypted swap does not match provided swap commitment");
return None;
}
if !fvk.incoming().views_address(&swap.claim_address) {
tracing::warn!("decrypted swap that is not claimable by provided full viewing key");
return None;
}
Some(swap)
}
}
impl From<SwapPayload> for pb::SwapPayload {
fn from(msg: SwapPayload) -> Self {
pb::SwapPayload {
commitment: Some(msg.commitment.into()),
encrypted_swap: msg.encrypted_swap.0.to_vec(),
}
}
}
impl TryFrom<pb::SwapPayload> for SwapPayload {
type Error = anyhow::Error;
fn try_from(msg: pb::SwapPayload) -> Result<Self, Self::Error> {
let commitment = msg
.commitment
.ok_or_else(|| anyhow!("missing commitment"))?
.try_into()?;
let encrypted_swap = SwapCiphertext(
msg.encrypted_swap
.try_into()
.map_err(|_| anyhow!("expected correct length swap ciphertext"))?,
);
Ok(Self {
commitment,
encrypted_swap,
})
}
}