@@ -105,6 +105,73 @@ impl<Pk: MiniscriptKey, Ctx: ScriptContext> Miniscript<Pk, Ctx> {
105105 pub fn as_inner ( & self ) -> & Terminal < Pk , Ctx > {
106106 & self . node
107107 }
108+
109+ /// Encode as a Bitcoin script
110+ pub fn encode ( & self ) -> script:: ScriptBuf
111+ where
112+ Pk : ToPublicKey ,
113+ {
114+ self . node . encode ( script:: Builder :: new ( ) ) . into_script ( )
115+ }
116+
117+ /// Size, in bytes of the script-pubkey. If this Miniscript is used outside
118+ /// of segwit (e.g. in a bare or P2SH descriptor), this quantity should be
119+ /// multiplied by 4 to compute the weight.
120+ ///
121+ /// In general, it is not recommended to use this function directly, but
122+ /// to instead call the corresponding function on a `Descriptor`, which
123+ /// will handle the segwit/non-segwit technicalities for you.
124+ pub fn script_size ( & self ) -> usize {
125+ let mut len = 0 ;
126+ for ms in self . pre_order_iter ( ) {
127+ len += match ms. node {
128+ Terminal :: PkK ( ref pk) => Ctx :: pk_len ( pk) ,
129+ Terminal :: PkH ( ..) | Terminal :: RawPkH ( ..) => 24 ,
130+ Terminal :: After ( n) => script_num_size ( n. to_consensus_u32 ( ) as usize ) + 1 ,
131+ Terminal :: Older ( n) => script_num_size ( n. to_consensus_u32 ( ) as usize ) + 1 ,
132+ Terminal :: Sha256 ( ..) => 33 + 6 ,
133+ Terminal :: Hash256 ( ..) => 33 + 6 ,
134+ Terminal :: Ripemd160 ( ..) => 21 + 6 ,
135+ Terminal :: Hash160 ( ..) => 21 + 6 ,
136+ Terminal :: True => 1 ,
137+ Terminal :: False => 1 ,
138+ Terminal :: Alt ( ..) => 2 ,
139+ Terminal :: Swap ( ..) => 1 ,
140+ Terminal :: Check ( ..) => 1 ,
141+ Terminal :: DupIf ( ..) => 3 ,
142+ Terminal :: Verify ( ref sub) => usize:: from ( !sub. ext . has_free_verify ) ,
143+ Terminal :: NonZero ( ..) => 4 ,
144+ Terminal :: ZeroNotEqual ( ..) => 1 ,
145+ Terminal :: AndV ( ..) => 0 ,
146+ Terminal :: AndB ( ..) => 1 ,
147+ Terminal :: AndOr ( ..) => 3 ,
148+ Terminal :: OrB ( ..) => 1 ,
149+ Terminal :: OrD ( ..) => 3 ,
150+ Terminal :: OrC ( ..) => 2 ,
151+ Terminal :: OrI ( ..) => 3 ,
152+ Terminal :: Thresh ( k, ref subs) => {
153+ assert ! ( !subs. is_empty( ) , "threshold must be nonempty" ) ;
154+ script_num_size ( k) // k
155+ + 1 // EQUAL
156+ + subs. len ( ) // ADD
157+ - 1 // no ADD on first element
158+ }
159+ Terminal :: Multi ( k, ref pks) => {
160+ script_num_size ( k)
161+ + 1
162+ + script_num_size ( pks. len ( ) )
163+ + pks. iter ( ) . map ( |pk| Ctx :: pk_len ( pk) ) . sum :: < usize > ( )
164+ }
165+ Terminal :: MultiA ( k, ref pks) => {
166+ script_num_size ( k)
167+ + 1 // NUMEQUAL
168+ + pks. iter ( ) . map ( |pk| Ctx :: pk_len ( pk) ) . sum :: < usize > ( ) // n keys
169+ + pks. len ( ) // n times CHECKSIGADD
170+ }
171+ }
172+ }
173+ len
174+ }
108175}
109176
110177/// `PartialOrd` of `Miniscript` must depend only on node and not the type information.
@@ -239,79 +306,6 @@ impl<Ctx: ScriptContext> Miniscript<Ctx::Key, Ctx> {
239306 }
240307}
241308
242- impl < Pk , Ctx > Miniscript < Pk , Ctx >
243- where
244- Pk : MiniscriptKey ,
245- Ctx : ScriptContext ,
246- {
247- /// Encode as a Bitcoin script
248- pub fn encode ( & self ) -> script:: ScriptBuf
249- where
250- Pk : ToPublicKey ,
251- {
252- self . node . encode ( script:: Builder :: new ( ) ) . into_script ( )
253- }
254-
255- /// Size, in bytes of the script-pubkey. If this Miniscript is used outside
256- /// of segwit (e.g. in a bare or P2SH descriptor), this quantity should be
257- /// multiplied by 4 to compute the weight.
258- ///
259- /// In general, it is not recommended to use this function directly, but
260- /// to instead call the corresponding function on a `Descriptor`, which
261- /// will handle the segwit/non-segwit technicalities for you.
262- pub fn script_size ( & self ) -> usize {
263- let mut len = 0 ;
264- for ms in self . pre_order_iter ( ) {
265- len += match ms. node {
266- Terminal :: PkK ( ref pk) => Ctx :: pk_len ( pk) ,
267- Terminal :: PkH ( ..) | Terminal :: RawPkH ( ..) => 24 ,
268- Terminal :: After ( n) => script_num_size ( n. to_consensus_u32 ( ) as usize ) + 1 ,
269- Terminal :: Older ( n) => script_num_size ( n. to_consensus_u32 ( ) as usize ) + 1 ,
270- Terminal :: Sha256 ( ..) => 33 + 6 ,
271- Terminal :: Hash256 ( ..) => 33 + 6 ,
272- Terminal :: Ripemd160 ( ..) => 21 + 6 ,
273- Terminal :: Hash160 ( ..) => 21 + 6 ,
274- Terminal :: True => 1 ,
275- Terminal :: False => 1 ,
276- Terminal :: Alt ( ..) => 2 ,
277- Terminal :: Swap ( ..) => 1 ,
278- Terminal :: Check ( ..) => 1 ,
279- Terminal :: DupIf ( ..) => 3 ,
280- Terminal :: Verify ( ref sub) => usize:: from ( !sub. ext . has_free_verify ) ,
281- Terminal :: NonZero ( ..) => 4 ,
282- Terminal :: ZeroNotEqual ( ..) => 1 ,
283- Terminal :: AndV ( ..) => 0 ,
284- Terminal :: AndB ( ..) => 1 ,
285- Terminal :: AndOr ( ..) => 3 ,
286- Terminal :: OrB ( ..) => 1 ,
287- Terminal :: OrD ( ..) => 3 ,
288- Terminal :: OrC ( ..) => 2 ,
289- Terminal :: OrI ( ..) => 3 ,
290- Terminal :: Thresh ( k, ref subs) => {
291- assert ! ( !subs. is_empty( ) , "threshold must be nonempty" ) ;
292- script_num_size ( k) // k
293- + 1 // EQUAL
294- + subs. len ( ) // ADD
295- - 1 // no ADD on first element
296- }
297- Terminal :: Multi ( k, ref pks) => {
298- script_num_size ( k)
299- + 1
300- + script_num_size ( pks. len ( ) )
301- + pks. iter ( ) . map ( |pk| Ctx :: pk_len ( pk) ) . sum :: < usize > ( )
302- }
303- Terminal :: MultiA ( k, ref pks) => {
304- script_num_size ( k)
305- + 1 // NUMEQUAL
306- + pks. iter ( ) . map ( |pk| Ctx :: pk_len ( pk) ) . sum :: < usize > ( ) // n keys
307- + pks. len ( ) // n times CHECKSIGADD
308- }
309- }
310- }
311- len
312- }
313- }
314-
315309impl < Pk : MiniscriptKey , Ctx : ScriptContext > Miniscript < Pk , Ctx > {
316310 /// Maximum number of witness elements used to satisfy the Miniscript
317311 /// fragment, including the witness script itself. Used to estimate
0 commit comments