From 5dbcbf28fb57f1e6772717330f47403dc78c6fcd Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Thu, 15 Apr 2021 16:14:34 +1200 Subject: [PATCH] Bundle Authorization transformations --- src/bundle.rs | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 67 insertions(+), 1 deletion(-) diff --git a/src/bundle.rs b/src/bundle.rs index 3b6fc933..c6a45bc2 100644 --- a/src/bundle.rs +++ b/src/bundle.rs @@ -34,8 +34,34 @@ pub struct Action { authorization: T, } +impl Action { + /// Transitions this action from one authorization state to another. + pub fn map(self, step: impl FnOnce(T) -> U) -> Action { + Action { + nf_old: self.nf_old, + rk: self.rk, + cm_new: self.cm_new, + encrypted_note: self.encrypted_note, + cv_net: self.cv_net, + authorization: step(self.authorization), + } + } + + /// Transitions this action from one authorization state to another. + pub fn try_map(self, step: impl FnOnce(T) -> Result) -> Result, E> { + Ok(Action { + nf_old: self.nf_old, + rk: self.rk, + cm_new: self.cm_new, + encrypted_note: self.encrypted_note, + cv_net: self.cv_net, + authorization: step(self.authorization)?, + }) + } +} + /// Orchard-specific flags. -#[derive(Debug)] +#[derive(Clone, Copy, Debug)] pub struct Flags { spends_enabled: bool, outputs_enabled: bool, @@ -63,6 +89,46 @@ impl Bundle { pub fn commitment(&self) -> BundleCommitment { todo!() } + + /// Transitions this bundle from one authorization state to another. + pub fn map( + self, + mut spend_auth: impl FnMut(&T, T::SpendAuth) -> U::SpendAuth, + step: impl FnOnce(T) -> U, + ) -> Bundle { + let authorization = self.authorization; + Bundle { + actions: self + .actions + .map(|a| a.map(|a_auth| spend_auth(&authorization, a_auth))), + flag: self.flag, + value_balance: self.value_balance, + anchor: self.anchor, + authorization: step(authorization), + } + } + + /// Transitions this bundle from one authorization state to another. + pub fn try_map( + self, + mut spend_auth: impl FnMut(&T, T::SpendAuth) -> Result, + step: impl FnOnce(T) -> Result, + ) -> Result, E> { + let authorization = self.authorization; + let new_actions = self + .actions + .into_iter() + .map(|a| a.try_map(|a_auth| spend_auth(&authorization, a_auth))) + .collect::, E>>()?; + + Ok(Bundle { + actions: NonEmpty::from_vec(new_actions).unwrap(), + flag: self.flag, + value_balance: self.value_balance, + anchor: self.anchor, + authorization: step(authorization)?, + }) + } } /// Marker for an unauthorized bundle with no proofs or signatures.