@@ -31,6 +31,7 @@ use bitcoin::blockdata::script::PushBytes;
3131use bitcoin:: blockdata:: { opcodes, script} ;
3232use bitcoin:: hashes:: { hash160, ripemd160, sha256, Hash } ;
3333use bitcoin:: { self , hashes, ScriptBuf as BtcScript } ;
34+ use bitcoin_miniscript:: miniscript:: limits:: MAX_PUBKEYS_PER_MULTISIG ;
3435use bitcoin_miniscript:: TranslatePk as BtcTranslatePk ;
3536use elements:: secp256k1_zkp;
3637
@@ -114,16 +115,15 @@ impl MiniscriptKey for LegacyPeginKey {
114115/// Legacy Pegin Descriptor
115116#[ derive( Clone , Ord , PartialOrd , Eq , PartialEq ) ]
116117pub struct LegacyPegin < Pk : MiniscriptKey > {
117- /// The federation pks
118- pub fed_pks : Vec < LegacyPeginKey > ,
119118 /// The federation threshold
120- pub fed_k : usize ,
121- /// The emergency pks
122- pub emer_pks : Vec < LegacyPeginKey > ,
119+ fed : bitcoin_miniscript:: Threshold < LegacyPeginKey , MAX_PUBKEYS_PER_MULTISIG > ,
120+
123121 /// The emergency threshold
124- pub emer_k : usize ,
122+ emer : bitcoin_miniscript:: Threshold < LegacyPeginKey , MAX_PUBKEYS_PER_MULTISIG > ,
123+
125124 /// csv timelock
126- pub timelock : bitcoin:: Sequence ,
125+ timelock : bitcoin_miniscript:: RelLockTime ,
126+
127127 /// The elements descriptor required to redeem
128128 ///
129129 /// TODO: Allow extension user descriptors when claiming pegins
@@ -136,30 +136,29 @@ pub struct LegacyPegin<Pk: MiniscriptKey> {
136136impl < Pk : MiniscriptKey > LegacyPegin < Pk > {
137137 /// Create a new LegacyPegin descriptor
138138 pub fn new (
139- fed_pks : Vec < LegacyPeginKey > ,
140- fed_k : usize ,
141- emer_pks : Vec < LegacyPeginKey > ,
142- emer_k : usize ,
143- timelock : bitcoin:: Sequence ,
139+ fed : bitcoin_miniscript:: Threshold < LegacyPeginKey , MAX_PUBKEYS_PER_MULTISIG > ,
140+ emer : bitcoin_miniscript:: Threshold < LegacyPeginKey , MAX_PUBKEYS_PER_MULTISIG > ,
141+ timelock : bitcoin_miniscript:: RelLockTime ,
144142 desc : Descriptor < Pk , CovenantExt < CovExtArgs > > ,
145143 ) -> Self {
146- let fed_ms = BtcMiniscript :: from_ast ( BtcTerminal :: Multi ( fed_k , fed_pks . clone ( ) ) )
144+ let fed_ms = BtcMiniscript :: from_ast ( BtcTerminal :: Multi ( fed . clone ( ) ) )
147145 . expect ( "Multi type check can't fail" ) ;
148146 let csv = BtcMiniscript :: from_ast ( BtcTerminal :: Verify ( Arc :: new (
149- BtcMiniscript :: from_ast ( BtcTerminal :: Older ( timelock) ) . unwrap ( ) ,
147+ BtcMiniscript :: from_ast ( BtcTerminal :: Older (
148+ bitcoin_miniscript:: RelLockTime :: try_from ( timelock) . expect ( "TODO" ) ,
149+ ) )
150+ . unwrap ( ) ,
150151 ) ) )
151152 . unwrap ( ) ;
152- let emer_ms = BtcMiniscript :: from_ast ( BtcTerminal :: Multi ( emer_k , emer_pks . clone ( ) ) )
153+ let emer_ms = BtcMiniscript :: from_ast ( BtcTerminal :: Multi ( emer . clone ( ) ) )
153154 . expect ( "Multi type check can't fail" ) ;
154155 let emer_ms =
155156 BtcMiniscript :: from_ast ( BtcTerminal :: AndV ( Arc :: new ( csv) , Arc :: new ( emer_ms) ) ) . unwrap ( ) ;
156157 let ms = BtcMiniscript :: from_ast ( BtcTerminal :: OrD ( Arc :: new ( fed_ms) , Arc :: new ( emer_ms) ) )
157158 . expect ( "Type check" ) ;
158159 Self {
159- fed_pks,
160- fed_k,
161- emer_pks,
162- emer_k,
160+ fed,
161+ emer,
163162 timelock,
164163 desc,
165164 ms,
@@ -175,21 +174,19 @@ impl<Pk: MiniscriptKey> LegacyPegin<Pk> {
175174 // Miniscript is a bunch of Arc's. So, cloning is not as bad.
176175 // Can we avoid this without NLL?
177176 let ms_clone = ms. clone ( ) ;
178- let ( fed_pks , fed_k , right) = if let BtcTerminal :: OrD ( ref a, ref b) = ms_clone. node {
179- if let ( BtcTerminal :: Multi ( fed_k , fed_pks ) , right) = ( & a. node , & b. node ) {
180- ( fed_pks , * fed_k , right)
177+ let ( fed , right) = if let BtcTerminal :: OrD ( ref a, ref b) = ms_clone. node {
178+ if let ( BtcTerminal :: Multi ( t ) , right) = ( & a. node , & b. node ) {
179+ ( t . clone ( ) , right)
181180 } else {
182181 unreachable ! ( "Only valid pegin miniscripts" ) ;
183182 }
184183 } else {
185184 unreachable ! ( "Only valid pegin miniscripts" ) ;
186185 } ;
187- let ( timelock, emer_pks, emer_k) = if let BtcTerminal :: AndV ( l, r) = right {
188- if let ( BtcTerminal :: Verify ( csv) , BtcTerminal :: Multi ( emer_k, emer_pks) ) =
189- ( & l. node , & r. node )
190- {
186+ let ( timelock, emer) = if let BtcTerminal :: AndV ( l, r) = right {
187+ if let ( BtcTerminal :: Verify ( csv) , BtcTerminal :: Multi ( t) ) = ( & l. node , & r. node ) {
191188 if let BtcTerminal :: Older ( timelock) = csv. node {
192- ( timelock, emer_pks , * emer_k )
189+ ( timelock, t . clone ( ) )
193190 } else {
194191 unreachable ! ( "Only valid pegin miniscripts" ) ;
195192 }
@@ -200,10 +197,8 @@ impl<Pk: MiniscriptKey> LegacyPegin<Pk> {
200197 unreachable ! ( "Only valid pegin miniscripts" ) ;
201198 } ;
202199 Self {
203- fed_pks : fed_pks. to_vec ( ) ,
204- fed_k,
205- emer_pks : emer_pks. to_vec ( ) ,
206- emer_k,
200+ fed,
201+ emer,
207202 timelock,
208203 desc,
209204 ms,
@@ -222,18 +217,18 @@ impl<Pk: MiniscriptKey> LegacyPegin<Pk> {
222217 // Hopefully, we never have to use this and dynafed is deployed
223218 let mut builder = script:: Builder :: new ( )
224219 . push_opcode ( opcodes:: all:: OP_DEPTH )
225- . push_int ( self . fed_k as i64 + 1 )
220+ . push_int ( self . fed . k ( ) as i64 + 1 )
226221 . push_opcode ( opcodes:: all:: OP_EQUAL )
227222 . push_opcode ( opcodes:: all:: OP_IF )
228223 // manually serialize the left CMS branch, without the OP_CMS
229- . push_int ( self . fed_k as i64 ) ;
224+ . push_int ( self . fed . k ( ) as i64 ) ;
230225
231- for key in & self . fed_pks {
226+ for key in self . fed . iter ( ) {
232227 let tweaked_pk = tweak_key ( key. as_untweaked ( ) , secp, tweak. as_byte_array ( ) ) ;
233228 builder = builder. push_key ( & tweaked_pk) ;
234229 }
235230 let mut nearly_done = builder
236- . push_int ( self . fed_pks . len ( ) as i64 )
231+ . push_int ( self . fed . n ( ) as i64 )
237232 . push_opcode ( opcodes:: all:: OP_ELSE )
238233 . into_script ( )
239234 . to_bytes ( ) ;
@@ -298,6 +293,8 @@ impl<Pk: MiniscriptKey> LegacyPegin<Pk> {
298293 . map ( |pk| LegacyPeginKey :: Functionary ( bitcoin:: PublicKey :: from_str ( pk) . unwrap ( ) ) )
299294 . collect ( ) ;
300295
296+ let fed = bitcoin_miniscript:: Threshold :: new ( 22 , fed_pks) . expect ( "statically defined" ) ;
297+
301298 let emer_pks = "
302299 03aab896d53a8e7d6433137bbba940f9c521e085dd07e60994579b64a6d992cf79,
303300 0291b7d0b1b692f8f524516ed950872e5da10fb1b808b5a526dedc6fed1cf29807,
@@ -307,12 +304,12 @@ impl<Pk: MiniscriptKey> LegacyPegin<Pk> {
307304 . map ( |pk| LegacyPeginKey :: Functionary ( bitcoin:: PublicKey :: from_str ( pk) . unwrap ( ) ) )
308305 . collect ( ) ;
309306
307+ let emer = bitcoin_miniscript:: Threshold :: new ( 2 , emer_pks) . expect ( "statically defined" ) ;
308+
310309 Self :: new (
311- fed_pks,
312- 11 ,
313- emer_pks,
314- 2 ,
315- bitcoin:: Sequence :: from_consensus ( 4032 ) ,
310+ fed,
311+ emer,
312+ bitcoin_miniscript:: RelLockTime :: from_consensus ( 4032 ) . expect ( "statically defined" ) ,
316313 user_desc,
317314 )
318315 }
@@ -473,28 +470,28 @@ impl<Pk: MiniscriptKey> LegacyPegin<Pk> {
473470 let tweak = hashes:: sha256:: Hash :: hash ( & tweak_vec) ;
474471 let unsigned_script_sig = self . bitcoin_unsigned_script_sig ( secp) ;
475472 let mut sigs = vec ! [ ] ;
476- for key in & self . fed_pks {
473+ for key in self . fed . iter ( ) {
477474 let tweaked_pk = tweak_key ( key. as_untweaked ( ) , secp, tweak. as_byte_array ( ) ) ;
478475 if let Some ( sig) = satisfier. lookup_ecdsa_sig ( & tweaked_pk) {
479476 sigs. push ( sig. to_vec ( ) ) ;
480477 }
481478 }
482479 sigs. sort_by_key ( |a| a. len ( ) ) ;
483- if sigs. len ( ) >= self . fed_k {
480+ if sigs. len ( ) >= self . fed . k ( ) {
484481 // Prefer using federation keys over emergency paths
485- let mut sigs: Vec < Vec < u8 > > = sigs. into_iter ( ) . take ( self . fed_k ) . collect ( ) ;
482+ let mut sigs: Vec < Vec < u8 > > = sigs. into_iter ( ) . take ( self . fed . k ( ) ) . collect ( ) ;
486483 sigs. push ( vec ! [ 0 ] ) ; // CMS extra value
487484 Ok ( ( sigs, unsigned_script_sig) )
488485 } else {
489486 let mut emer_sigs = vec ! [ ] ;
490- for emer_key in & self . emer_pks {
487+ for emer_key in self . emer . iter ( ) {
491488 if let Some ( sig) = satisfier. lookup_ecdsa_sig ( emer_key. as_untweaked ( ) ) {
492489 emer_sigs. push ( sig. to_vec ( ) ) ;
493490 }
494491 }
495492 emer_sigs. sort_by_key ( |a| a. len ( ) ) ;
496- if emer_sigs. len ( ) >= self . emer_k {
497- let mut sigs: Vec < Vec < u8 > > = emer_sigs. into_iter ( ) . take ( self . emer_k ) . collect ( ) ;
493+ if emer_sigs. len ( ) >= self . emer . k ( ) {
494+ let mut sigs: Vec < Vec < u8 > > = emer_sigs. into_iter ( ) . take ( self . emer . k ( ) ) . collect ( ) ;
498495 sigs. push ( vec ! [ 0 ] ) ; // CMS extra value
499496 Ok ( ( sigs, unsigned_script_sig) )
500497 } else {
0 commit comments