1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
use decaf377_rdsa::{Signature, SpendAuth};

use penumbra_proto::{core::transaction::v1 as pb, DomainType};
use penumbra_txhash::EffectHash;

/// Authorization data returned in response to a
/// [`TransactionDescription`](crate::TransactionDescription).
#[derive(Clone, Debug)]
pub struct AuthorizationData {
    /// The computed authorization hash for the approved transaction.
    pub effect_hash: Option<EffectHash>,
    /// The required spend authorization signatures, returned in the same order as the Spend actions
    /// in the original request.
    pub spend_auths: Vec<Signature<SpendAuth>>,
    /// The required delegator vote authorization signatures, returned in the same order as the
    /// DelegatorVote actions in the original request.
    pub delegator_vote_auths: Vec<Signature<SpendAuth>>,
}

impl DomainType for AuthorizationData {
    type Proto = pb::AuthorizationData;
}

impl From<AuthorizationData> for pb::AuthorizationData {
    fn from(msg: AuthorizationData) -> Self {
        Self {
            effect_hash: msg.effect_hash.map(Into::into),
            spend_auths: msg.spend_auths.into_iter().map(Into::into).collect(),
            delegator_vote_auths: msg
                .delegator_vote_auths
                .into_iter()
                .map(Into::into)
                .collect(),
        }
    }
}

impl TryFrom<pb::AuthorizationData> for AuthorizationData {
    type Error = anyhow::Error;
    fn try_from(value: pb::AuthorizationData) -> Result<Self, Self::Error> {
        Ok(Self {
            effect_hash: value.effect_hash.map(TryInto::try_into).transpose()?,
            spend_auths: value
                .spend_auths
                .into_iter()
                .map(TryInto::try_into)
                .collect::<Result<_, _>>()?,
            delegator_vote_auths: value
                .delegator_vote_auths
                .into_iter()
                .map(TryInto::try_into)
                .collect::<Result<_, _>>()?,
        })
    }
}