@@ -20,7 +20,7 @@ use bitcoin::util::taproot::{ControlBlock, TAPROOT_ANNEX_PREFIX};
20
20
21
21
use { BareCtx , Legacy , Segwitv0 , Tap } ;
22
22
23
- use super :: { stack, BitcoinKey , Error , Stack , TaggedHash160 } ;
23
+ use super :: { stack, BitcoinKey , Error , Stack , TypedHash160 } ;
24
24
use miniscript:: context:: { NoChecks , ScriptContext } ;
25
25
use { Miniscript , MiniscriptKey } ;
26
26
@@ -186,7 +186,7 @@ pub(super) fn from_txdata<'txin>(
186
186
Some ( elem) => {
187
187
let miniscript = script_from_stackelem :: < Segwitv0 > ( & elem) ?;
188
188
let script = miniscript. encode ( ) ;
189
- let miniscript = pre_taproot_to_no_checks ( & miniscript) ;
189
+ let miniscript = miniscript. to_no_checks_ms ( ) ;
190
190
let scripthash = sha256:: Hash :: hash ( & script[ ..] ) ;
191
191
if * spk == bitcoin:: Script :: new_v0_p2wsh ( & scripthash. into ( ) ) {
192
192
Ok ( (
@@ -230,7 +230,7 @@ pub(super) fn from_txdata<'txin>(
230
230
let ctrl_blk = ControlBlock :: from_slice ( ctrl_blk)
231
231
. map_err ( |e| Error :: ControlBlockParse ( e) ) ?;
232
232
let tap_script = script_from_stackelem :: < Tap > ( & tap_script) ?;
233
- let ms = taproot_to_no_checks ( & tap_script) ;
233
+ let ms = tap_script. to_no_checks_ms ( ) ;
234
234
// Creating new contexts is cheap
235
235
let secp = bitcoin:: secp256k1:: Secp256k1 :: verification_only ( ) ;
236
236
let tap_script = tap_script. encode ( ) ;
@@ -306,7 +306,7 @@ pub(super) fn from_txdata<'txin>(
306
306
// parse wsh with Segwitv0 context
307
307
let miniscript = script_from_stackelem :: < Segwitv0 > ( & elem) ?;
308
308
let script = miniscript. encode ( ) ;
309
- let miniscript = pre_taproot_to_no_checks ( & miniscript) ;
309
+ let miniscript = miniscript. to_no_checks_ms ( ) ;
310
310
let scripthash = sha256:: Hash :: hash ( & script[ ..] ) ;
311
311
if slice
312
312
== & bitcoin:: Script :: new_v0_p2wsh ( & scripthash. into ( ) ) [ ..]
@@ -328,7 +328,7 @@ pub(super) fn from_txdata<'txin>(
328
328
// normal p2sh parsed in Legacy context
329
329
let miniscript = script_from_stackelem :: < Legacy > ( & elem) ?;
330
330
let script = miniscript. encode ( ) ;
331
- let miniscript = pre_taproot_to_no_checks ( & miniscript) ;
331
+ let miniscript = miniscript. to_no_checks_ms ( ) ;
332
332
if wit_stack. is_empty ( ) {
333
333
let scripthash = hash160:: Hash :: hash ( & script[ ..] ) ;
334
334
if * spk == bitcoin:: Script :: new_p2sh ( & scripthash. into ( ) ) {
@@ -351,7 +351,7 @@ pub(super) fn from_txdata<'txin>(
351
351
if wit_stack. is_empty ( ) {
352
352
// Bare script parsed in BareCtx
353
353
let miniscript = Miniscript :: < bitcoin:: PublicKey , BareCtx > :: parse_insane ( spk) ?;
354
- let miniscript = pre_taproot_to_no_checks ( & miniscript) ;
354
+ let miniscript = miniscript. to_no_checks_ms ( ) ;
355
355
Ok ( (
356
356
Inner :: Script ( miniscript, ScriptType :: Bare ) ,
357
357
ssig_stack,
@@ -363,29 +363,39 @@ pub(super) fn from_txdata<'txin>(
363
363
}
364
364
}
365
365
366
- // Convert a miniscript from a specified context into an insane miniscript
367
- // We need to remember how the hash160 was translated because while doing a checksig
368
- // we need to know whether to parse the public key provided in witness as x-only or full
369
- pub ( super ) fn pre_taproot_to_no_checks < Ctx : ScriptContext > (
370
- ms : & Miniscript < bitcoin :: PublicKey , Ctx > ,
371
- ) -> Miniscript < BitcoinKey , NoChecks > {
372
- // specify the () error type as this cannot error
373
- ms . real_translate_pk :: < _ , _ , _ , ( ) , _ > ( & mut |pk| Ok ( BitcoinKey :: Fullkey ( * pk ) ) , & mut |pkh| {
374
- Ok ( TaggedHash160 :: FullKey ( * pkh ) )
375
- } )
376
- . expect ( "Translation should succeed" )
366
+ // Convert a miniscript from a well-defined context to a no checks context.
367
+ // We need to parse insane scripts because these scripts are obtained from already
368
+ // created transaction possibly already confirmed in a block.
369
+ // In order to avoid code duplication for various contexts related interpreter checks,
370
+ // we convert all the scripts to from a well-defined context to NoContexts.
371
+ //
372
+ // While executing Pkh(<hash>) in NoChecks, we need to pop a public key from stack
373
+ // However, NoChecks context does not know whether to parse the key as 33 bytes or 32 bytes
374
+ // While converting into NoChecks we store explicitly in TypedHash160 enum.
375
+ pub ( super ) trait ToNoChecks {
376
+ fn to_no_checks_ms ( & self ) -> Miniscript < BitcoinKey , NoChecks > ;
377
377
}
378
378
379
- // Convert a miniscript from a specified context into an insane miniscript
380
- pub ( super ) fn taproot_to_no_checks < Ctx : ScriptContext > (
381
- ms : & Miniscript < bitcoin:: XOnlyPublicKey , Ctx > ,
382
- ) -> Miniscript < BitcoinKey , NoChecks > {
383
- // specify the () error type as this cannot error
384
- ms. real_translate_pk :: < _ , _ , _ , ( ) , _ > (
385
- & mut |xpk| Ok ( BitcoinKey :: XOnlyPublicKey ( * xpk) ) ,
386
- & mut |pkh| Ok ( TaggedHash160 :: XonlyKey ( * pkh) ) ,
387
- )
388
- . expect ( "Translation should succeed" )
379
+ impl < Ctx : ScriptContext > ToNoChecks for Miniscript < bitcoin:: PublicKey , Ctx > {
380
+ fn to_no_checks_ms ( & self ) -> Miniscript < BitcoinKey , NoChecks > {
381
+ // specify the () error type as this cannot error
382
+ self . real_translate_pk :: < _ , _ , _ , ( ) , _ > (
383
+ & mut |pk| Ok ( BitcoinKey :: Fullkey ( * pk) ) ,
384
+ & mut |pkh| Ok ( TypedHash160 :: FullKey ( * pkh) ) ,
385
+ )
386
+ . expect ( "Translation should succeed" )
387
+ }
388
+ }
389
+
390
+ impl < Ctx : ScriptContext > ToNoChecks for Miniscript < bitcoin:: XOnlyPublicKey , Ctx > {
391
+ fn to_no_checks_ms ( & self ) -> Miniscript < BitcoinKey , NoChecks > {
392
+ // specify the () error type as this cannot error
393
+ self . real_translate_pk :: < _ , _ , _ , ( ) , _ > (
394
+ & mut |xpk| Ok ( BitcoinKey :: XOnlyPublicKey ( * xpk) ) ,
395
+ & mut |pkh| Ok ( TypedHash160 :: XonlyKey ( * pkh) ) ,
396
+ )
397
+ . expect ( "Translation should succeed" )
398
+ }
389
399
}
390
400
391
401
#[ cfg( test) ]
@@ -737,7 +747,7 @@ mod tests {
737
747
fn ms_inner_script ( ms : & str ) -> ( Miniscript < BitcoinKey , NoChecks > , bitcoin:: Script ) {
738
748
let ms = Miniscript :: < bitcoin:: PublicKey , Segwitv0 > :: from_str_insane ( ms) . unwrap ( ) ;
739
749
let spk = ms. encode ( ) ;
740
- let miniscript = pre_taproot_to_no_checks ( & ms ) ;
750
+ let miniscript = ms . to_no_checks_ms ( ) ;
741
751
( miniscript, spk)
742
752
}
743
753
#[ test]
0 commit comments