@@ -24,7 +24,7 @@ use memuse::DynamicUsage;
2424use crate :: {
2525 action:: Action ,
2626 address:: Address ,
27- bundle:: commitments:: { hash_bundle_auth_data, hash_bundle_txid_data} ,
27+ bundle:: commitments:: { hash_bundle_auth_data, hash_bundle_txid_data, hash_action_group } ,
2828 circuit:: { Instance , Proof , VerifyingKey } ,
2929 keys:: { IncomingViewingKey , OutgoingViewingKey , PreparedIncomingViewingKey } ,
3030 note:: { AssetBase , Note } ,
@@ -35,6 +35,7 @@ use crate::{
3535 value:: { NoteValue , ValueCommitTrapdoor , ValueCommitment , ValueSum } ,
3636 Proof ,
3737} ;
38+ use crate :: orchard_flavor:: OrchardZSA ;
3839
3940#[ cfg( feature = "circuit" ) ]
4041use crate :: circuit:: { Instance , VerifyingKey } ;
@@ -77,60 +78,81 @@ pub struct Flags {
7778 /// If `false`, all notes within [`Action`]s in the transaction's [`Bundle`] are
7879 /// guaranteed to be notes with native asset.
7980 zsa_enabled : bool ,
81+ /// Flag denoting whether Asset Swaps are enabled.
82+ ///
83+ /// If `false`, [`Bundle`] is guaranteed to contain only one ['ActionGroup'].
84+ swaps_enabled : bool ,
8085}
8186
8287const FLAG_SPENDS_ENABLED : u8 = 0b0000_0001 ;
8388const FLAG_OUTPUTS_ENABLED : u8 = 0b0000_0010 ;
8489const FLAG_ZSA_ENABLED : u8 = 0b0000_0100 ;
85- const FLAGS_EXPECTED_UNSET : u8 = !( FLAG_SPENDS_ENABLED | FLAG_OUTPUTS_ENABLED | FLAG_ZSA_ENABLED ) ;
90+ const FLAG_SWAPS_ENABLED : u8 = 0b0000_1000 ;
91+ const FLAGS_EXPECTED_UNSET : u8 =
92+ !( FLAG_SPENDS_ENABLED | FLAG_OUTPUTS_ENABLED | FLAG_ZSA_ENABLED | FLAG_SWAPS_ENABLED ) ;
8693
8794impl Flags {
8895 /// Construct a set of flags from its constituent parts
8996 pub ( crate ) const fn from_parts (
9097 spends_enabled : bool ,
9198 outputs_enabled : bool ,
9299 zsa_enabled : bool ,
100+ swaps_enabled : bool ,
93101 ) -> Self {
94102 Flags {
95103 spends_enabled,
96104 outputs_enabled,
97105 zsa_enabled,
106+ swaps_enabled,
98107 }
99108 }
100109
101- /// The flag set with both spends and outputs enabled and ZSA disabled.
110+ /// The flag set with both spends and outputs enabled. ZSA and swaps are disabled.
102111 pub const ENABLED_WITHOUT_ZSA : Flags = Flags {
103112 spends_enabled : true ,
104113 outputs_enabled : true ,
105114 zsa_enabled : false ,
115+ swaps_enabled : false ,
106116 } ;
107117
108- /// The flags set with spends, outputs and ZSA enabled.
118+ /// The flags set with spends, outputs and ZSA enabled. Swaps are disabled.
109119 pub const ENABLED_WITH_ZSA : Flags = Flags {
110120 spends_enabled : true ,
111121 outputs_enabled : true ,
112122 zsa_enabled : true ,
123+ swaps_enabled : false ,
124+ } ;
125+
126+ /// The flags set with spends, outputs, ZSA and swaps enabled.
127+ pub const ENABLED_WITH_SWAPS : Flags = Flags {
128+ spends_enabled : true ,
129+ outputs_enabled : true ,
130+ zsa_enabled : true ,
131+ swaps_enabled : true ,
113132 } ;
114133
115- /// The flag set with spends and ZSA disabled.
134+ /// The flag set with spends, ZSA and swaps disabled.
116135 pub const SPENDS_DISABLED_WITHOUT_ZSA : Flags = Flags {
117136 spends_enabled : false ,
118137 outputs_enabled : true ,
119138 zsa_enabled : false ,
139+ swaps_enabled : false ,
120140 } ;
121141
122- /// The flag set with spends disabled and ZSA enabled.
142+ /// The flag set with spends disabled and ZSA enabled. Swaps are disabled.
123143 pub const SPENDS_DISABLED_WITH_ZSA : Flags = Flags {
124144 spends_enabled : false ,
125145 outputs_enabled : true ,
126146 zsa_enabled : true ,
147+ swaps_enabled : false ,
127148 } ;
128149
129150 /// The flag set with outputs disabled and ZSA disabled.
130151 pub const OUTPUTS_DISABLED : Flags = Flags {
131152 spends_enabled : true ,
132153 outputs_enabled : false ,
133154 zsa_enabled : false ,
155+ swaps_enabled : false ,
134156 } ;
135157
136158 /// Flag denoting whether Orchard spends are enabled in the transaction.
@@ -190,6 +212,7 @@ impl Flags {
190212 spends_enabled : value & FLAG_SPENDS_ENABLED != 0 ,
191213 outputs_enabled : value & FLAG_OUTPUTS_ENABLED != 0 ,
192214 zsa_enabled : value & FLAG_ZSA_ENABLED != 0 ,
215+ swaps_enabled : value & FLAG_SWAPS_ENABLED != 0 ,
193216 } )
194217 } else {
195218 None
@@ -201,6 +224,9 @@ impl Flags {
201224pub trait Authorization : fmt:: Debug {
202225 /// The authorization type of an Orchard action.
203226 type SpendAuth : fmt:: Debug + Clone ;
227+
228+ /// Return the proof component of the authorizing data.
229+ fn proof ( & self ) -> Option < & Proof > ;
204230}
205231
206232/// A bundle of actions to be applied to the ledger.
@@ -535,6 +561,14 @@ impl Authorization for EffectsOnly {
535561 type SpendAuth = ( ) ;
536562}
537563
564+ impl < A : Authorization , V : Copy + Into < i64 > > Bundle < A , V , OrchardZSA > {
565+ /// Computes a commitment to the effects of this bundle,
566+ /// assuming that the bundle represents an action group inside a swap bundle.
567+ pub fn action_group_commitment ( & self ) -> BundleCommitment {
568+ BundleCommitment ( hash_action_group ( self ) )
569+ }
570+ }
571+
538572/// Authorizing data for a bundle of actions, ready to be committed to the ledger.
539573#[ derive( Debug , Clone ) ]
540574pub struct Authorized {
@@ -544,6 +578,11 @@ pub struct Authorized {
544578
545579impl Authorization for Authorized {
546580 type SpendAuth = VerSpendAuthSig ;
581+
582+ /// Return the proof component of the authorizing data.
583+ fn proof ( & self ) -> Option < & Proof > {
584+ Some ( & self . proof )
585+ }
547586}
548587
549588impl Authorized {
@@ -555,11 +594,6 @@ impl Authorized {
555594 }
556595 }
557596
558- /// Return the proof component of the authorizing data.
559- pub fn proof ( & self ) -> & Proof {
560- & self . proof
561- }
562-
563597 /// Return the versioned binding signature.
564598 pub fn binding_signature ( & self ) -> & VerBindingSig {
565599 & self . binding_signature
@@ -584,6 +618,7 @@ impl<V, P: OrchardPrimitives> Bundle<Authorized, V, P> {
584618 pub fn verify_proof ( & self , vk : & VerifyingKey ) -> Result < ( ) , halo2_proofs:: plonk:: Error > {
585619 self . authorization ( )
586620 . proof ( )
621+ . unwrap ( )
587622 . verify ( vk, & self . to_instances ( ) )
588623 }
589624}
@@ -767,8 +802,8 @@ pub mod testing {
767802
768803 prop_compose ! {
769804 /// Create an arbitrary set of flags.
770- pub fn arb_flags( ) ( spends_enabled in prop:: bool :: ANY , outputs_enabled in prop:: bool :: ANY , zsa_enabled in prop:: bool :: ANY ) -> Flags {
771- Flags :: from_parts( spends_enabled, outputs_enabled, zsa_enabled)
805+ pub fn arb_flags( ) ( spends_enabled in prop:: bool :: ANY , outputs_enabled in prop:: bool :: ANY , zsa_enabled in prop:: bool :: ANY , swaps_enabled in prop :: bool :: ANY ) -> Flags {
806+ Flags :: from_parts( spends_enabled, outputs_enabled, zsa_enabled, swaps_enabled )
772807 }
773808 }
774809
@@ -803,7 +838,7 @@ pub mod testing {
803838 balances. into_iter( ) . sum:: <Result <ValueSum , _>>( ) . unwrap( ) ,
804839 burn,
805840 anchor,
806- None ,
841+ 0 ,
807842 super :: EffectsOnly ,
808843 )
809844 }
@@ -836,6 +871,7 @@ pub mod testing {
836871 balances. into_iter( ) . sum:: <Result <ValueSum , _>>( ) . unwrap( ) ,
837872 burn,
838873 anchor,
874+ 0 ,
839875 Authorized {
840876 proof: Proof :: new( fake_proof) ,
841877 binding_signature: VerBindingSig :: new( P :: default_sighash_version( ) , sk. sign( rng, & fake_sighash) ) ,
0 commit comments