13
13
//
14
14
15
15
use bitcoin;
16
+ use bitcoin:: blockdata:: witness:: Witness ;
16
17
use bitcoin:: hashes:: { hash160, sha256, Hash } ;
17
18
18
19
use super :: { stack, Error , Stack } ;
@@ -97,7 +98,7 @@ pub enum Inner {
97
98
pub fn from_txdata < ' txin > (
98
99
spk : & bitcoin:: Script ,
99
100
script_sig : & ' txin bitcoin:: Script ,
100
- witness : & ' txin [ Vec < u8 > ] ,
101
+ witness : & ' txin Witness ,
101
102
) -> Result < ( Inner , Stack < ' txin > , bitcoin:: Script ) , Error > {
102
103
let mut ssig_stack: Stack = script_sig
103
104
. instructions_minimal ( )
@@ -300,12 +301,12 @@ mod tests {
300
301
pkh_sig : bitcoin:: Script ,
301
302
pkh_sig_justkey : bitcoin:: Script ,
302
303
wpkh_spk : bitcoin:: Script ,
303
- wpkh_stack : Vec < Vec < u8 > > ,
304
- wpkh_stack_justkey : Vec < Vec < u8 > > ,
304
+ wpkh_stack : Witness ,
305
+ wpkh_stack_justkey : Witness ,
305
306
sh_wpkh_spk : bitcoin:: Script ,
306
307
sh_wpkh_sig : bitcoin:: Script ,
307
- sh_wpkh_stack : Vec < Vec < u8 > > ,
308
- sh_wpkh_stack_justkey : Vec < Vec < u8 > > ,
308
+ sh_wpkh_stack : Witness ,
309
+ sh_wpkh_stack_justkey : Witness ,
309
310
}
310
311
311
312
impl KeyTestData {
@@ -334,14 +335,14 @@ mod tests {
334
335
. into_script ( ) ,
335
336
pkh_sig_justkey : script:: Builder :: new ( ) . push_key ( & key) . into_script ( ) ,
336
337
wpkh_spk : wpkh_spk. clone ( ) ,
337
- wpkh_stack : vec ! [ dummy_sig. clone( ) , key. to_bytes( ) ] ,
338
- wpkh_stack_justkey : vec ! [ key. to_bytes( ) ] ,
338
+ wpkh_stack : Witness :: from_vec ( vec ! [ dummy_sig. clone( ) , key. to_bytes( ) ] ) ,
339
+ wpkh_stack_justkey : Witness :: from_vec ( vec ! [ key. to_bytes( ) ] ) ,
339
340
sh_wpkh_spk : bitcoin:: Script :: new_p2sh ( & wpkh_scripthash) ,
340
341
sh_wpkh_sig : script:: Builder :: new ( )
341
342
. push_slice ( & wpkh_spk[ ..] )
342
343
. into_script ( ) ,
343
- sh_wpkh_stack : vec ! [ dummy_sig, key. to_bytes( ) ] ,
344
- sh_wpkh_stack_justkey : vec ! [ key. to_bytes( ) ] ,
344
+ sh_wpkh_stack : Witness :: from_vec ( vec ! [ dummy_sig, key. to_bytes( ) ] ) ,
345
+ sh_wpkh_stack_justkey : Witness :: from_vec ( vec ! [ key. to_bytes( ) ] ) ,
345
346
}
346
347
}
347
348
}
@@ -375,31 +376,32 @@ mod tests {
375
376
let comp = KeyTestData :: from_key ( fixed. pk_comp ) ;
376
377
let uncomp = KeyTestData :: from_key ( fixed. pk_uncomp ) ;
377
378
let blank_script = bitcoin:: Script :: new ( ) ;
379
+ let empty_wit = Witness :: default ( ) ;
378
380
379
381
// Compressed pk, empty scriptsig
380
382
let ( inner, stack, script_code) =
381
- from_txdata ( & comp. pk_spk , & blank_script, & [ ] ) . expect ( "parse txdata" ) ;
383
+ from_txdata ( & comp. pk_spk , & blank_script, & empty_wit ) . expect ( "parse txdata" ) ;
382
384
assert_eq ! ( inner, Inner :: PublicKey ( fixed. pk_comp, PubkeyType :: Pk ) ) ;
383
385
assert_eq ! ( stack, Stack :: from( vec![ ] ) ) ;
384
386
assert_eq ! ( script_code, comp. pk_spk) ;
385
387
386
388
// Uncompressed pk, empty scriptsig
387
389
let ( inner, stack, script_code) =
388
- from_txdata ( & uncomp. pk_spk , & blank_script, & [ ] ) . expect ( "parse txdata" ) ;
390
+ from_txdata ( & uncomp. pk_spk , & blank_script, & empty_wit ) . expect ( "parse txdata" ) ;
389
391
assert_eq ! ( inner, Inner :: PublicKey ( fixed. pk_uncomp, PubkeyType :: Pk ) ) ;
390
392
assert_eq ! ( stack, Stack :: from( vec![ ] ) ) ;
391
393
assert_eq ! ( script_code, uncomp. pk_spk) ;
392
394
393
395
// Compressed pk, correct scriptsig
394
396
let ( inner, stack, script_code) =
395
- from_txdata ( & comp. pk_spk , & comp. pk_sig , & [ ] ) . expect ( "parse txdata" ) ;
397
+ from_txdata ( & comp. pk_spk , & comp. pk_sig , & empty_wit ) . expect ( "parse txdata" ) ;
396
398
assert_eq ! ( inner, Inner :: PublicKey ( fixed. pk_comp, PubkeyType :: Pk ) ) ;
397
399
assert_eq ! ( stack, Stack :: from( vec![ comp. pk_sig[ 1 ..] . into( ) ] ) ) ;
398
400
assert_eq ! ( script_code, comp. pk_spk) ;
399
401
400
402
// Uncompressed pk, correct scriptsig
401
403
let ( inner, stack, script_code) =
402
- from_txdata ( & uncomp. pk_spk , & uncomp. pk_sig , & [ ] ) . expect ( "parse txdata" ) ;
404
+ from_txdata ( & uncomp. pk_spk , & uncomp. pk_sig , & empty_wit ) . expect ( "parse txdata" ) ;
403
405
assert_eq ! ( inner, Inner :: PublicKey ( fixed. pk_uncomp, PubkeyType :: Pk ) ) ;
404
406
assert_eq ! ( stack, Stack :: from( vec![ uncomp. pk_sig[ 1 ..] . into( ) ] ) ) ;
405
407
assert_eq ! ( script_code, uncomp. pk_spk) ;
@@ -408,18 +410,19 @@ mod tests {
408
410
let mut spk = comp. pk_spk . to_bytes ( ) ;
409
411
spk[ 1 ] = 5 ;
410
412
let spk = bitcoin:: Script :: from ( spk) ;
411
- let err = from_txdata ( & spk, & bitcoin:: Script :: new ( ) , & [ ] ) . unwrap_err ( ) ;
413
+ let err = from_txdata ( & spk, & bitcoin:: Script :: new ( ) , & empty_wit ) . unwrap_err ( ) ;
412
414
assert_eq ! ( err. to_string( ) , "could not parse pubkey" ) ;
413
415
414
416
// Scriptpubkey has invalid script
415
417
let mut spk = comp. pk_spk . to_bytes ( ) ;
416
418
spk[ 0 ] = 100 ;
417
419
let spk = bitcoin:: Script :: from ( spk) ;
418
- let err = from_txdata ( & spk, & bitcoin:: Script :: new ( ) , & [ ] ) . unwrap_err ( ) ;
420
+ let err = from_txdata ( & spk, & bitcoin:: Script :: new ( ) , & empty_wit ) . unwrap_err ( ) ;
419
421
assert_eq ! ( & err. to_string( ) [ 0 ..12 ] , "parse error:" ) ;
420
422
421
423
// Witness is nonempty
422
- let err = from_txdata ( & comp. pk_spk , & comp. pk_sig , & [ vec ! [ ] ] ) . unwrap_err ( ) ;
424
+ let wit = Witness :: from_vec ( vec ! [ vec![ ] ] ) ;
425
+ let err = from_txdata ( & comp. pk_spk , & comp. pk_sig , & wit) . unwrap_err ( ) ;
423
426
assert_eq ! ( err. to_string( ) , "legacy spend had nonempty witness" ) ;
424
427
}
425
428
@@ -428,43 +431,47 @@ mod tests {
428
431
let fixed = fixed_test_data ( ) ;
429
432
let comp = KeyTestData :: from_key ( fixed. pk_comp ) ;
430
433
let uncomp = KeyTestData :: from_key ( fixed. pk_uncomp ) ;
434
+ let empty_wit = Witness :: default ( ) ;
431
435
432
436
// pkh, empty scriptsig; this time it errors out
433
- let err = from_txdata ( & comp. pkh_spk , & bitcoin:: Script :: new ( ) , & [ ] ) . unwrap_err ( ) ;
437
+ let err = from_txdata ( & comp. pkh_spk , & bitcoin:: Script :: new ( ) , & empty_wit ) . unwrap_err ( ) ;
434
438
assert_eq ! ( err. to_string( ) , "unexpected end of stack" ) ;
435
439
436
440
// pkh, wrong pubkey
437
- let err = from_txdata ( & comp. pkh_spk , & uncomp. pkh_sig_justkey , & [ ] ) . unwrap_err ( ) ;
441
+ let err = from_txdata ( & comp. pkh_spk , & uncomp. pkh_sig_justkey , & empty_wit ) . unwrap_err ( ) ;
438
442
assert_eq ! ( err. to_string( ) , "public key did not match scriptpubkey" ) ;
439
443
440
444
// pkh, right pubkey, no signature
441
445
let ( inner, stack, script_code) =
442
- from_txdata ( & comp. pkh_spk , & comp. pkh_sig_justkey , & [ ] ) . expect ( "parse txdata" ) ;
446
+ from_txdata ( & comp. pkh_spk , & comp. pkh_sig_justkey , & empty_wit ) . expect ( "parse txdata" ) ;
443
447
assert_eq ! ( inner, Inner :: PublicKey ( fixed. pk_comp, PubkeyType :: Pkh ) ) ;
444
448
assert_eq ! ( stack, Stack :: from( vec![ ] ) ) ;
445
449
assert_eq ! ( script_code, comp. pkh_spk) ;
446
450
447
451
let ( inner, stack, script_code) =
448
- from_txdata ( & uncomp. pkh_spk , & uncomp. pkh_sig_justkey , & [ ] ) . expect ( "parse txdata" ) ;
452
+ from_txdata ( & uncomp. pkh_spk , & uncomp. pkh_sig_justkey , & empty_wit)
453
+ . expect ( "parse txdata" ) ;
449
454
assert_eq ! ( inner, Inner :: PublicKey ( fixed. pk_uncomp, PubkeyType :: Pkh ) ) ;
450
455
assert_eq ! ( stack, Stack :: from( vec![ ] ) ) ;
451
456
assert_eq ! ( script_code, uncomp. pkh_spk) ;
452
457
453
458
// pkh, right pubkey, signature
454
459
let ( inner, stack, script_code) =
455
- from_txdata ( & comp. pkh_spk , & comp. pkh_sig_justkey , & [ ] ) . expect ( "parse txdata" ) ;
460
+ from_txdata ( & comp. pkh_spk , & comp. pkh_sig_justkey , & empty_wit ) . expect ( "parse txdata" ) ;
456
461
assert_eq ! ( inner, Inner :: PublicKey ( fixed. pk_comp, PubkeyType :: Pkh ) ) ;
457
462
assert_eq ! ( stack, Stack :: from( vec![ ] ) ) ;
458
463
assert_eq ! ( script_code, comp. pkh_spk) ;
459
464
460
465
let ( inner, stack, script_code) =
461
- from_txdata ( & uncomp. pkh_spk , & uncomp. pkh_sig_justkey , & [ ] ) . expect ( "parse txdata" ) ;
466
+ from_txdata ( & uncomp. pkh_spk , & uncomp. pkh_sig_justkey , & empty_wit)
467
+ . expect ( "parse txdata" ) ;
462
468
assert_eq ! ( inner, Inner :: PublicKey ( fixed. pk_uncomp, PubkeyType :: Pkh ) ) ;
463
469
assert_eq ! ( stack, Stack :: from( vec![ ] ) ) ;
464
470
assert_eq ! ( script_code, uncomp. pkh_spk) ;
465
471
466
472
// Witness is nonempty
467
- let err = from_txdata ( & comp. pkh_spk , & comp. pkh_sig , & [ vec ! [ ] ] ) . unwrap_err ( ) ;
473
+ let wit = Witness :: from_vec ( vec ! [ vec![ ] ] ) ;
474
+ let err = from_txdata ( & comp. pkh_spk , & comp. pkh_sig , & wit) . unwrap_err ( ) ;
468
475
assert_eq ! ( err. to_string( ) , "legacy spend had nonempty witness" ) ;
469
476
}
470
477
@@ -476,7 +483,7 @@ mod tests {
476
483
let blank_script = bitcoin:: Script :: new ( ) ;
477
484
478
485
// wpkh, empty witness; this time it errors out
479
- let err = from_txdata ( & comp. wpkh_spk , & blank_script, & [ ] ) . unwrap_err ( ) ;
486
+ let err = from_txdata ( & comp. wpkh_spk , & blank_script, & Witness :: default ( ) ) . unwrap_err ( ) ;
480
487
assert_eq ! ( err. to_string( ) , "unexpected end of stack" ) ;
481
488
482
489
// wpkh, uncompressed pubkey
@@ -507,7 +514,10 @@ mod tests {
507
514
let ( inner, stack, script_code) =
508
515
from_txdata ( & comp. wpkh_spk , & blank_script, & comp. wpkh_stack ) . expect ( "parse txdata" ) ;
509
516
assert_eq ! ( inner, Inner :: PublicKey ( fixed. pk_comp, PubkeyType :: Wpkh ) ) ;
510
- assert_eq ! ( stack, Stack :: from( vec![ comp. wpkh_stack[ 0 ] [ ..] . into( ) ] ) ) ;
517
+ assert_eq ! (
518
+ stack,
519
+ Stack :: from( vec![ comp. wpkh_stack. second_to_last( ) . unwrap( ) . into( ) ] )
520
+ ) ;
511
521
assert_eq ! ( script_code, comp. pkh_spk) ;
512
522
513
523
// Scriptsig is nonempty
@@ -523,9 +533,10 @@ mod tests {
523
533
let blank_script = bitcoin:: Script :: new ( ) ;
524
534
525
535
// sh_wpkh, missing witness or scriptsig
526
- let err = from_txdata ( & comp. sh_wpkh_spk , & blank_script, & [ ] ) . unwrap_err ( ) ;
536
+ let err = from_txdata ( & comp. sh_wpkh_spk , & blank_script, & Witness :: default ( ) ) . unwrap_err ( ) ;
527
537
assert_eq ! ( err. to_string( ) , "unexpected end of stack" ) ;
528
- let err = from_txdata ( & comp. sh_wpkh_spk , & comp. sh_wpkh_sig , & [ ] ) . unwrap_err ( ) ;
538
+ let err =
539
+ from_txdata ( & comp. sh_wpkh_spk , & comp. sh_wpkh_sig , & Witness :: default ( ) ) . unwrap_err ( ) ;
529
540
assert_eq ! ( err. to_string( ) , "unexpected end of stack" ) ;
530
541
let err = from_txdata ( & comp. sh_wpkh_spk , & blank_script, & comp. sh_wpkh_stack ) . unwrap_err ( ) ;
531
542
assert_eq ! ( err. to_string( ) , "unexpected end of stack" ) ;
@@ -576,7 +587,10 @@ mod tests {
576
587
from_txdata ( & comp. sh_wpkh_spk , & comp. sh_wpkh_sig , & comp. sh_wpkh_stack )
577
588
. expect ( "parse txdata" ) ;
578
589
assert_eq ! ( inner, Inner :: PublicKey ( fixed. pk_comp, PubkeyType :: ShWpkh ) ) ;
579
- assert_eq ! ( stack, Stack :: from( vec![ comp. sh_wpkh_stack[ 0 ] [ ..] . into( ) ] ) ) ;
590
+ assert_eq ! (
591
+ stack,
592
+ Stack :: from( vec![ comp. sh_wpkh_stack. second_to_last( ) . unwrap( ) . into( ) ] )
593
+ ) ;
580
594
assert_eq ! ( script_code, comp. pkh_spk) ;
581
595
}
582
596
@@ -589,19 +603,21 @@ mod tests {
589
603
590
604
let spk = miniscript. encode ( ) ;
591
605
let blank_script = bitcoin:: Script :: new ( ) ;
606
+ let empty_wit = Witness :: default ( ) ;
592
607
593
608
// bare script has no validity requirements beyond being a sane script
594
609
let ( inner, stack, script_code) =
595
- from_txdata ( & spk, & blank_script, & [ ] ) . expect ( "parse txdata" ) ;
610
+ from_txdata ( & spk, & blank_script, & empty_wit ) . expect ( "parse txdata" ) ;
596
611
assert_eq ! ( inner, Inner :: Script ( miniscript, ScriptType :: Bare ) ) ;
597
612
assert_eq ! ( stack, Stack :: from( vec![ ] ) ) ;
598
613
assert_eq ! ( script_code, spk) ;
599
614
600
- let err = from_txdata ( & blank_script, & blank_script, & [ ] ) . unwrap_err ( ) ;
615
+ let err = from_txdata ( & blank_script, & blank_script, & empty_wit ) . unwrap_err ( ) ;
601
616
assert_eq ! ( & err. to_string( ) [ 0 ..12 ] , "parse error:" ) ;
602
617
603
618
// nonempty witness
604
- let err = from_txdata ( & spk, & blank_script, & [ vec ! [ ] ] ) . unwrap_err ( ) ;
619
+ let wit = Witness :: from_vec ( vec ! [ vec![ ] ] ) ;
620
+ let err = from_txdata ( & spk, & blank_script, & wit) . unwrap_err ( ) ;
605
621
assert_eq ! ( & err. to_string( ) , "legacy spend had nonempty witness" ) ;
606
622
}
607
623
@@ -620,24 +636,26 @@ mod tests {
620
636
. push_slice ( & redeem_script[ ..] )
621
637
. into_script ( ) ;
622
638
let blank_script = bitcoin:: Script :: new ( ) ;
639
+ let empty_wit = Witness :: default ( ) ;
623
640
624
641
// sh without scriptsig
625
- let err = from_txdata ( & spk, & blank_script, & [ ] ) . unwrap_err ( ) ;
642
+ let err = from_txdata ( & spk, & blank_script, & Witness :: default ( ) ) . unwrap_err ( ) ;
626
643
assert_eq ! ( & err. to_string( ) , "unexpected end of stack" ) ;
627
644
628
645
// with incorrect scriptsig
629
- let err = from_txdata ( & spk, & spk, & [ ] ) . unwrap_err ( ) ;
646
+ let err = from_txdata ( & spk, & spk, & Witness :: default ( ) ) . unwrap_err ( ) ;
630
647
assert_eq ! ( & err. to_string( ) , "expected push in script" ) ;
631
648
632
649
// with correct scriptsig
633
650
let ( inner, stack, script_code) =
634
- from_txdata ( & spk, & script_sig, & [ ] ) . expect ( "parse txdata" ) ;
651
+ from_txdata ( & spk, & script_sig, & empty_wit ) . expect ( "parse txdata" ) ;
635
652
assert_eq ! ( inner, Inner :: Script ( miniscript, ScriptType :: Sh ) ) ;
636
653
assert_eq ! ( stack, Stack :: from( vec![ ] ) ) ;
637
654
assert_eq ! ( script_code, redeem_script) ;
638
655
639
656
// nonempty witness
640
- let err = from_txdata ( & spk, & script_sig, & [ vec ! [ ] ] ) . unwrap_err ( ) ;
657
+ let wit = Witness :: from_vec ( vec ! [ vec![ ] ] ) ;
658
+ let err = from_txdata ( & spk, & script_sig, & wit) . unwrap_err ( ) ;
641
659
assert_eq ! ( & err. to_string( ) , "legacy spend had nonempty witness" ) ;
642
660
}
643
661
@@ -650,17 +668,18 @@ mod tests {
650
668
651
669
let witness_script = miniscript. encode ( ) ;
652
670
let wit_hash = sha256:: Hash :: hash ( & witness_script[ ..] ) . into ( ) ;
653
- let wit_stack = vec ! [ witness_script. to_bytes( ) ] ;
671
+ let wit_stack = Witness :: from_vec ( vec ! [ witness_script. to_bytes( ) ] ) ;
654
672
655
673
let spk = Script :: new_v0_wsh ( & wit_hash) ;
656
674
let blank_script = bitcoin:: Script :: new ( ) ;
657
675
658
676
// wsh without witness
659
- let err = from_txdata ( & spk, & blank_script, & [ ] ) . unwrap_err ( ) ;
677
+ let err = from_txdata ( & spk, & blank_script, & Witness :: default ( ) ) . unwrap_err ( ) ;
660
678
assert_eq ! ( & err. to_string( ) , "unexpected end of stack" ) ;
661
679
662
680
// with incorrect witness
663
- let err = from_txdata ( & spk, & blank_script, & [ spk. to_bytes ( ) ] ) . unwrap_err ( ) ;
681
+ let wit = Witness :: from_vec ( vec ! [ spk. to_bytes( ) ] ) ;
682
+ let err = from_txdata ( & spk, & blank_script, & wit) . unwrap_err ( ) ;
664
683
assert_eq ! ( & err. to_string( ) [ 0 ..12 ] , "parse error:" ) ;
665
684
666
685
// with correct witness
@@ -687,7 +706,7 @@ mod tests {
687
706
688
707
let witness_script = miniscript. encode ( ) ;
689
708
let wit_hash = sha256:: Hash :: hash ( & witness_script[ ..] ) . into ( ) ;
690
- let wit_stack = vec ! [ witness_script. to_bytes( ) ] ;
709
+ let wit_stack = Witness :: from_vec ( vec ! [ witness_script. to_bytes( ) ] ) ;
691
710
692
711
let redeem_script = Script :: new_v0_wsh ( & wit_hash) ;
693
712
let script_sig = script:: Builder :: new ( )
@@ -699,15 +718,16 @@ mod tests {
699
718
let spk = Script :: new_p2sh ( & rs_hash) ;
700
719
701
720
// shwsh without witness or scriptsig
702
- let err = from_txdata ( & spk, & blank_script, & [ ] ) . unwrap_err ( ) ;
721
+ let err = from_txdata ( & spk, & blank_script, & Witness :: default ( ) ) . unwrap_err ( ) ;
703
722
assert_eq ! ( & err. to_string( ) , "unexpected end of stack" ) ;
704
- let err = from_txdata ( & spk, & script_sig, & [ ] ) . unwrap_err ( ) ;
723
+ let err = from_txdata ( & spk, & script_sig, & Witness :: default ( ) ) . unwrap_err ( ) ;
705
724
assert_eq ! ( & err. to_string( ) , "unexpected end of stack" ) ;
706
725
let err = from_txdata ( & spk, & blank_script, & wit_stack) . unwrap_err ( ) ;
707
726
assert_eq ! ( & err. to_string( ) , "unexpected end of stack" ) ;
708
727
709
728
// with incorrect witness
710
- let err = from_txdata ( & spk, & script_sig, & [ spk. to_bytes ( ) ] ) . unwrap_err ( ) ;
729
+ let wit = Witness :: from_vec ( vec ! [ spk. to_bytes( ) ] ) ;
730
+ let err = from_txdata ( & spk, & script_sig, & wit) . unwrap_err ( ) ;
711
731
assert_eq ! ( & err. to_string( ) [ 0 ..12 ] , "parse error:" ) ;
712
732
713
733
// with incorrect scriptsig
0 commit comments