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
use anyhow::Result;
use rand::{CryptoRng, RngCore};

use penumbra_keys::keys::SpendKey;

use crate::{AuthorizationData, TransactionPlan};

impl TransactionPlan {
    /// Authorize this [`TransactionPlan`] with the provided [`SpendKey`].
    ///
    /// The returned [`AuthorizationData`] can be used to build a [`Transaction`](crate::Transaction).
    pub fn authorize<R: RngCore + CryptoRng>(
        &self,
        mut rng: R,
        sk: &SpendKey,
    ) -> Result<AuthorizationData> {
        let effect_hash = self.effect_hash(sk.full_viewing_key())?;
        let mut spend_auths = Vec::new();
        let mut delegator_vote_auths = Vec::new();

        for spend_plan in self.spend_plans() {
            let rsk = sk.spend_auth_key().randomize(&spend_plan.randomizer);
            let auth_sig = rsk.sign(&mut rng, effect_hash.as_ref());
            spend_auths.push(auth_sig);
        }
        for delegator_vote_plan in self.delegator_vote_plans() {
            let rsk = sk
                .spend_auth_key()
                .randomize(&delegator_vote_plan.randomizer);
            let auth_sig = rsk.sign(&mut rng, effect_hash.as_ref());
            delegator_vote_auths.push(auth_sig);
        }
        Ok(AuthorizationData {
            effect_hash: Some(effect_hash),
            spend_auths,
            delegator_vote_auths,
        })
    }
}