@@ -19,62 +19,55 @@ use crate::plan::AssetProvider;
1919use crate :: prelude:: * ;
2020use crate :: sync:: Arc ;
2121use crate :: {
22- errstr , expression, policy, script_num_size, Error , ForEachKey , Miniscript , MiniscriptKey ,
23- Satisfier , ToPublicKey , TranslateErr , Translator ,
22+ expression, policy, script_num_size, Error , ForEachKey , Miniscript , MiniscriptKey , Satisfier ,
23+ Threshold , ToPublicKey , TranslateErr , Translator ,
2424} ;
2525
2626/// Contents of a "sortedmulti" descriptor
2727#[ derive( Clone , PartialEq , Eq , PartialOrd , Ord , Hash ) ]
2828pub struct SortedMultiVec < Pk : MiniscriptKey , Ctx : ScriptContext > {
29- /// signatures required
30- pub k : usize ,
31- /// public keys inside sorted Multi
32- pub pks : Vec < Pk > ,
29+ inner : Threshold < Pk , MAX_PUBKEYS_PER_MULTISIG > ,
3330 /// The current ScriptContext for sortedmulti
34- pub ( crate ) phantom : PhantomData < Ctx > ,
31+ phantom : PhantomData < Ctx > ,
3532}
3633
3734impl < Pk : MiniscriptKey , Ctx : ScriptContext > SortedMultiVec < Pk , Ctx > {
38- /// Create a new instance of `SortedMultiVec` given a list of keys and the threshold
39- ///
40- /// Internally checks all the applicable size limits and pubkey types limitations according to the current `Ctx`.
41- pub fn new ( k : usize , pks : Vec < Pk > ) -> Result < Self , Error > {
42- // A sortedmulti() is only defined for <= 20 keys (it maps to CHECKMULTISIG)
43- if pks. len ( ) > MAX_PUBKEYS_PER_MULTISIG {
44- return Err ( Error :: BadDescriptor ( "Too many public keys" . to_string ( ) ) ) ;
45- }
46-
35+ fn constructor_check ( & self ) -> Result < ( ) , Error > {
4736 // Check the limits before creating a new SortedMultiVec
4837 // For example, under p2sh context the scriptlen can only be
4938 // upto 520 bytes.
50- let term: Terminal < Pk , Ctx > = Terminal :: Multi ( k , pks . clone ( ) ) ;
39+ let term: Terminal < Pk , Ctx > = Terminal :: Multi ( self . inner . k ( ) , self . inner . data ( ) . to_owned ( ) ) ;
5140 let ms = Miniscript :: from_ast ( term) ?;
52-
5341 // This would check all the consensus rules for p2sh/p2wsh and
5442 // even tapscript in future
55- Ctx :: check_local_validity ( & ms) ?;
43+ Ctx :: check_local_validity ( & ms) . map_err ( From :: from)
44+ }
5645
57- Ok ( Self { k, pks, phantom : PhantomData } )
46+ /// Create a new instance of `SortedMultiVec` given a list of keys and the threshold
47+ ///
48+ /// Internally checks all the applicable size limits and pubkey types limitations according to the current `Ctx`.
49+ pub fn new ( k : usize , pks : Vec < Pk > ) -> Result < Self , Error > {
50+ let ret =
51+ Self { inner : Threshold :: new ( k, pks) . map_err ( Error :: Threshold ) ?, phantom : PhantomData } ;
52+ ret. constructor_check ( ) ?;
53+ Ok ( ret)
5854 }
55+
5956 /// Parse an expression tree into a SortedMultiVec
6057 pub fn from_tree ( tree : & expression:: Tree ) -> Result < Self , Error >
6158 where
6259 Pk : FromStr ,
6360 <Pk as FromStr >:: Err : fmt:: Display ,
6461 {
65- if tree. args . is_empty ( ) {
66- return Err ( errstr ( "no arguments given for sortedmulti" ) ) ;
67- }
68- let k = expression:: parse_num ( tree. args [ 0 ] . name ) ?;
69- if k > ( tree. args . len ( ) - 1 ) as u32 {
70- return Err ( errstr ( "higher threshold than there were keys in sortedmulti" ) ) ;
71- }
72- let pks: Result < Vec < Pk > , _ > = tree. args [ 1 ..]
73- . iter ( )
74- . map ( |sub| expression:: terminal ( sub, Pk :: from_str) )
75- . collect ( ) ;
76-
77- pks. map ( |pks| SortedMultiVec :: new ( k as usize , pks) ) ?
62+ let ret = Self {
63+ inner : tree
64+ . to_null_threshold ( )
65+ . map_err ( Error :: ParseThreshold ) ?
66+ . translate_by_index ( |i| expression:: terminal ( & tree. args [ i + 1 ] , Pk :: from_str) ) ?,
67+ phantom : PhantomData ,
68+ } ;
69+ ret. constructor_check ( ) ?;
70+ Ok ( ret)
7871 }
7972
8073 /// This will panic if fpk returns an uncompressed key when
@@ -88,23 +81,39 @@ impl<Pk: MiniscriptKey, Ctx: ScriptContext> SortedMultiVec<Pk, Ctx> {
8881 T : Translator < Pk , Q , FuncError > ,
8982 Q : MiniscriptKey ,
9083 {
91- let pks: Result < Vec < Q > , _ > = self . pks . iter ( ) . map ( |pk| t. pk ( pk) ) . collect ( ) ;
92- let res = SortedMultiVec :: new ( self . k , pks?) . map_err ( TranslateErr :: OuterError ) ?;
93- Ok ( res)
84+ let ret = SortedMultiVec {
85+ inner : self . inner . translate_ref ( |pk| t. pk ( pk) ) ?,
86+ phantom : PhantomData ,
87+ } ;
88+ ret. constructor_check ( ) . map_err ( TranslateErr :: OuterError ) ?;
89+ Ok ( ret)
9490 }
91+
92+ /// The threshold value for the multisig.
93+ pub fn k ( & self ) -> usize { self . inner . k ( ) }
94+
95+ /// The number of keys in the multisig.
96+ pub fn n ( & self ) -> usize { self . inner . n ( ) }
97+
98+ /// Accessor for the public keys in the multisig.
99+ ///
100+ /// The keys in this structure might **not** be sorted. In general, they cannot be
101+ /// sorted until they are converted to consensus-encoded public keys, which may not
102+ /// be possible (for example for BIP32 paths with unfilled wildcards).
103+ pub fn pks ( & self ) -> & [ Pk ] { self . inner . data ( ) }
95104}
96105
97106impl < Pk : MiniscriptKey , Ctx : ScriptContext > ForEachKey < Pk > for SortedMultiVec < Pk , Ctx > {
98107 fn for_each_key < ' a , F : FnMut ( & ' a Pk ) -> bool > ( & ' a self , pred : F ) -> bool {
99- self . pks . iter ( ) . all ( pred)
108+ self . pks ( ) . iter ( ) . all ( pred)
100109 }
101110}
102111
103112impl < Pk : MiniscriptKey , Ctx : ScriptContext > SortedMultiVec < Pk , Ctx > {
104113 /// utility function to sanity a sorted multi vec
105114 pub fn sanity_check ( & self ) -> Result < ( ) , Error > {
106115 let ms: Miniscript < Pk , Ctx > =
107- Miniscript :: from_ast ( Terminal :: Multi ( self . k , self . pks . clone ( ) ) )
116+ Miniscript :: from_ast ( Terminal :: Multi ( self . k ( ) , self . pks ( ) . to_owned ( ) ) )
108117 . expect ( "Must typecheck" ) ;
109118 // '?' for doing From conversion
110119 ms. sanity_check ( ) ?;
@@ -118,7 +127,7 @@ impl<Pk: MiniscriptKey, Ctx: ScriptContext> SortedMultiVec<Pk, Ctx> {
118127 where
119128 Pk : ToPublicKey ,
120129 {
121- let mut pks = self . pks . clone ( ) ;
130+ let mut pks = self . pks ( ) . to_owned ( ) ;
122131 // Sort pubkeys lexicographically according to BIP 67
123132 pks. sort_by ( |a, b| {
124133 a. to_public_key ( )
@@ -127,7 +136,7 @@ impl<Pk: MiniscriptKey, Ctx: ScriptContext> SortedMultiVec<Pk, Ctx> {
127136 . partial_cmp ( & b. to_public_key ( ) . inner . serialize ( ) )
128137 . unwrap ( )
129138 } ) ;
130- Terminal :: Multi ( self . k , pks)
139+ Terminal :: Multi ( self . k ( ) , pks)
131140 }
132141
133142 /// Encode as a Bitcoin script
@@ -169,10 +178,10 @@ impl<Pk: MiniscriptKey, Ctx: ScriptContext> SortedMultiVec<Pk, Ctx> {
169178 /// to instead call the corresponding function on a `Descriptor`, which
170179 /// will handle the segwit/non-segwit technicalities for you.
171180 pub fn script_size ( & self ) -> usize {
172- script_num_size ( self . k )
181+ script_num_size ( self . k ( ) )
173182 + 1
174- + script_num_size ( self . pks . len ( ) )
175- + self . pks . iter ( ) . map ( |pk| Ctx :: pk_len ( pk) ) . sum :: < usize > ( )
183+ + script_num_size ( self . n ( ) )
184+ + self . pks ( ) . iter ( ) . map ( |pk| Ctx :: pk_len ( pk) ) . sum :: < usize > ( )
176185 }
177186
178187 /// Maximum number of witness elements used to satisfy the Miniscript
@@ -183,7 +192,7 @@ impl<Pk: MiniscriptKey, Ctx: ScriptContext> SortedMultiVec<Pk, Ctx> {
183192 /// This function may panic on malformed `Miniscript` objects which do
184193 /// not correspond to semantically sane Scripts. (Such scripts should be
185194 /// rejected at parse time. Any exceptions are bugs.)
186- pub fn max_satisfaction_witness_elements ( & self ) -> usize { 2 + self . k }
195+ pub fn max_satisfaction_witness_elements ( & self ) -> usize { 2 + self . k ( ) }
187196
188197 /// Maximum size, in bytes, of a satisfying witness.
189198 /// In general, it is not recommended to use this function directly, but
@@ -193,19 +202,16 @@ impl<Pk: MiniscriptKey, Ctx: ScriptContext> SortedMultiVec<Pk, Ctx> {
193202 /// All signatures are assumed to be 73 bytes in size, including the
194203 /// length prefix (segwit) or push opcode (pre-segwit) and sighash
195204 /// postfix.
196- pub fn max_satisfaction_size ( & self ) -> usize { 1 + 73 * self . k }
205+ pub fn max_satisfaction_size ( & self ) -> usize { 1 + 73 * self . k ( ) }
197206}
198207
199208impl < Pk : MiniscriptKey , Ctx : ScriptContext > policy:: Liftable < Pk > for SortedMultiVec < Pk , Ctx > {
200209 fn lift ( & self ) -> Result < policy:: semantic:: Policy < Pk > , Error > {
201- let ret = policy:: semantic:: Policy :: Thresh (
202- self . k ,
203- self . pks
204- . iter ( )
205- . map ( |k| Arc :: new ( policy:: semantic:: Policy :: Key ( k. clone ( ) ) ) )
206- . collect ( ) ,
207- ) ;
208- Ok ( ret)
210+ Ok ( policy:: semantic:: Policy :: Thresh (
211+ self . inner
212+ . map_ref ( |pk| Arc :: new ( policy:: semantic:: Policy :: Key ( pk. clone ( ) ) ) )
213+ . forget_maximum ( ) ,
214+ ) )
209215 }
210216}
211217
@@ -215,11 +221,7 @@ impl<Pk: MiniscriptKey, Ctx: ScriptContext> fmt::Debug for SortedMultiVec<Pk, Ct
215221
216222impl < Pk : MiniscriptKey , Ctx : ScriptContext > fmt:: Display for SortedMultiVec < Pk , Ctx > {
217223 fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
218- write ! ( f, "sortedmulti({}" , self . k) ?;
219- for k in & self . pks {
220- write ! ( f, ",{}" , k) ?;
221- }
222- f. write_str ( ")" )
224+ fmt:: Display :: fmt ( & self . inner . display ( "sortedmulti" , true ) , f)
223225 }
224226}
225227
@@ -249,7 +251,7 @@ mod tests {
249251 let error = res. expect_err ( "constructor should err" ) ;
250252
251253 match error {
252- Error :: BadDescriptor ( _) => { } // ok
254+ Error :: Threshold ( _) => { } // ok
253255 other => panic ! ( "unexpected error: {:?}" , other) ,
254256 }
255257 }
0 commit comments