@@ -25,7 +25,6 @@ use bitcoin::blockdata::script;
2525use bitcoin:: { Address , Network , Script } ;
2626
2727use super :: checksum:: { desc_checksum, verify_checksum} ;
28- use super :: DescriptorTrait ;
2928use crate :: expression:: { self , FromTree } ;
3029use crate :: miniscript:: context:: ScriptContext ;
3130use crate :: policy:: { semantic, Liftable } ;
@@ -66,6 +65,20 @@ impl<Pk: MiniscriptKey> Bare<Pk> {
6665 self . ms . sanity_check ( ) ?;
6766 Ok ( ( ) )
6867 }
68+
69+ /// Computes an upper bound on the weight of a satisfying witness to the
70+ /// transaction.
71+ ///
72+ /// Assumes all ec-signatures are 73 bytes, including push opcode and
73+ /// sighash suffix. Includes the weight of the VarInts encoding the
74+ /// scriptSig and witness stack length.
75+ ///
76+ /// # Errors
77+ /// When the descriptor is impossible to safisfy (ex: sh(OP_FALSE)).
78+ pub fn max_satisfaction_weight ( & self ) -> Result < usize , Error > {
79+ let scriptsig_len = self . ms . max_satisfaction_size ( ) ?;
80+ Ok ( 4 * ( varint_len ( scriptsig_len) + scriptsig_len) )
81+ }
6982}
7083
7184impl < Pk : MiniscriptKey + ToPublicKey > Bare < Pk > {
@@ -83,6 +96,32 @@ impl<Pk: MiniscriptKey + ToPublicKey> Bare<Pk> {
8396 pub fn ecdsa_sighash_script_code ( & self ) -> Script {
8497 self . script_pubkey ( )
8598 }
99+
100+ /// Returns satisfying non-malleable witness and scriptSig with minimum
101+ /// weight to spend an output controlled by the given descriptor if it is
102+ /// possible to construct one using the `satisfier`.
103+ pub fn get_satisfaction < S > ( & self , satisfier : S ) -> Result < ( Vec < Vec < u8 > > , Script ) , Error >
104+ where
105+ S : Satisfier < Pk > ,
106+ {
107+ let ms = self . ms . satisfy ( satisfier) ?;
108+ let script_sig = witness_to_scriptsig ( & ms) ;
109+ let witness = vec ! [ ] ;
110+ Ok ( ( witness, script_sig) )
111+ }
112+
113+ /// Returns satisfying, possibly malleable, witness and scriptSig with
114+ /// minimum weight to spend an output controlled by the given descriptor if
115+ /// it is possible to construct one using the `satisfier`.
116+ pub fn get_satisfaction_mall < S > ( & self , satisfier : S ) -> Result < ( Vec < Vec < u8 > > , Script ) , Error >
117+ where
118+ S : Satisfier < Pk > ,
119+ {
120+ let ms = self . ms . satisfy_malleable ( satisfier) ?;
121+ let script_sig = witness_to_scriptsig ( & ms) ;
122+ let witness = vec ! [ ] ;
123+ Ok ( ( witness, script_sig) )
124+ }
86125}
87126
88127impl < Pk : MiniscriptKey > fmt:: Debug for Bare < Pk > {
@@ -135,35 +174,6 @@ where
135174 }
136175}
137176
138- impl < Pk : MiniscriptKey > DescriptorTrait < Pk > for Bare < Pk > {
139- fn get_satisfaction < S > ( & self , satisfier : S ) -> Result < ( Vec < Vec < u8 > > , Script ) , Error >
140- where
141- Pk : ToPublicKey ,
142- S : Satisfier < Pk > ,
143- {
144- let ms = self . ms . satisfy ( satisfier) ?;
145- let script_sig = witness_to_scriptsig ( & ms) ;
146- let witness = vec ! [ ] ;
147- Ok ( ( witness, script_sig) )
148- }
149-
150- fn get_satisfaction_mall < S > ( & self , satisfier : S ) -> Result < ( Vec < Vec < u8 > > , Script ) , Error >
151- where
152- Pk : ToPublicKey ,
153- S : Satisfier < Pk > ,
154- {
155- let ms = self . ms . satisfy_malleable ( satisfier) ?;
156- let script_sig = witness_to_scriptsig ( & ms) ;
157- let witness = vec ! [ ] ;
158- Ok ( ( witness, script_sig) )
159- }
160-
161- fn max_satisfaction_weight ( & self ) -> Result < usize , Error > {
162- let scriptsig_len = self . ms . max_satisfaction_size ( ) ?;
163- Ok ( 4 * ( varint_len ( scriptsig_len) + scriptsig_len) )
164- }
165- }
166-
167177impl < Pk : MiniscriptKey > ForEachKey < Pk > for Bare < Pk > {
168178 fn for_each_key < ' a , F : FnMut ( ForEach < ' a , Pk > ) -> bool > ( & ' a self , pred : F ) -> bool
169179 where
@@ -215,6 +225,16 @@ impl<Pk: MiniscriptKey> Pkh<Pk> {
215225 pub fn into_inner ( self ) -> Pk {
216226 self . pk
217227 }
228+
229+ /// Computes an upper bound on the weight of a satisfying witness to the
230+ /// transaction.
231+ ///
232+ /// Assumes all ec-signatures are 73 bytes, including push opcode and
233+ /// sighash suffix. Includes the weight of the VarInts encoding the
234+ /// scriptSig and witness stack length.
235+ pub fn max_satisfaction_weight ( & self ) -> usize {
236+ 4 * ( 1 + 73 + BareCtx :: pk_len ( & self . pk ) )
237+ }
218238}
219239
220240impl < Pk : MiniscriptKey + ToPublicKey > Pkh < Pk > {
@@ -240,6 +260,36 @@ impl<Pk: MiniscriptKey + ToPublicKey> Pkh<Pk> {
240260 pub fn ecdsa_sighash_script_code ( & self ) -> Script {
241261 self . script_pubkey ( )
242262 }
263+
264+ /// Returns satisfying non-malleable witness and scriptSig with minimum
265+ /// weight to spend an output controlled by the given descriptor if it is
266+ /// possible to construct one using the `satisfier`.
267+ pub fn get_satisfaction < S > ( & self , satisfier : S ) -> Result < ( Vec < Vec < u8 > > , Script ) , Error >
268+ where
269+ S : Satisfier < Pk > ,
270+ {
271+ if let Some ( sig) = satisfier. lookup_ecdsa_sig ( & self . pk ) {
272+ let sig_vec = sig. to_vec ( ) ;
273+ let script_sig = script:: Builder :: new ( )
274+ . push_slice ( & sig_vec[ ..] )
275+ . push_key ( & self . pk . to_public_key ( ) )
276+ . into_script ( ) ;
277+ let witness = vec ! [ ] ;
278+ Ok ( ( witness, script_sig) )
279+ } else {
280+ Err ( Error :: MissingSig ( self . pk . to_public_key ( ) ) )
281+ }
282+ }
283+
284+ /// Returns satisfying, possibly malleable, witness and scriptSig with
285+ /// minimum weight to spend an output controlled by the given descriptor if
286+ /// it is possible to construct one using the `satisfier`.
287+ pub fn get_satisfaction_mall < S > ( & self , satisfier : S ) -> Result < ( Vec < Vec < u8 > > , Script ) , Error >
288+ where
289+ S : Satisfier < Pk > ,
290+ {
291+ self . get_satisfaction ( satisfier)
292+ }
243293}
244294
245295impl < Pk : MiniscriptKey > fmt:: Debug for Pkh < Pk > {
@@ -300,38 +350,6 @@ where
300350 }
301351}
302352
303- impl < Pk : MiniscriptKey > DescriptorTrait < Pk > for Pkh < Pk > {
304- fn get_satisfaction < S > ( & self , satisfier : S ) -> Result < ( Vec < Vec < u8 > > , Script ) , Error >
305- where
306- Pk : ToPublicKey ,
307- S : Satisfier < Pk > ,
308- {
309- if let Some ( sig) = satisfier. lookup_ecdsa_sig ( & self . pk ) {
310- let sig_vec = sig. to_vec ( ) ;
311- let script_sig = script:: Builder :: new ( )
312- . push_slice ( & sig_vec[ ..] )
313- . push_key ( & self . pk . to_public_key ( ) )
314- . into_script ( ) ;
315- let witness = vec ! [ ] ;
316- Ok ( ( witness, script_sig) )
317- } else {
318- Err ( Error :: MissingSig ( self . pk . to_public_key ( ) ) )
319- }
320- }
321-
322- fn get_satisfaction_mall < S > ( & self , satisfier : S ) -> Result < ( Vec < Vec < u8 > > , Script ) , Error >
323- where
324- Pk : ToPublicKey ,
325- S : Satisfier < Pk > ,
326- {
327- self . get_satisfaction ( satisfier)
328- }
329-
330- fn max_satisfaction_weight ( & self ) -> Result < usize , Error > {
331- Ok ( 4 * ( 1 + 73 + BareCtx :: pk_len ( & self . pk ) ) )
332- }
333- }
334-
335353impl < Pk : MiniscriptKey > ForEachKey < Pk > for Pkh < Pk > {
336354 fn for_each_key < ' a , F : FnMut ( ForEach < ' a , Pk > ) -> bool > ( & ' a self , mut pred : F ) -> bool
337355 where
0 commit comments