@@ -14,7 +14,6 @@ use sync::Arc;
14
14
use super :: checksum;
15
15
use crate :: descriptor:: DefiniteDescriptorKey ;
16
16
use crate :: expression:: { self , FromTree } ;
17
- use crate :: iter:: TreeLike as _;
18
17
use crate :: miniscript:: satisfy:: { Placeholder , Satisfaction , SchnorrSigType , Witness } ;
19
18
use crate :: miniscript:: Miniscript ;
20
19
use crate :: plan:: AssetProvider ;
@@ -495,99 +494,84 @@ impl<Pk: FromStrKey> core::str::FromStr for Tr<Pk> {
495
494
496
495
fn from_str ( s : & str ) -> Result < Self , Self :: Err > {
497
496
let expr_tree = expression:: Tree :: from_str ( s) ?;
498
- Self :: from_tree ( & expr_tree)
497
+ Self :: from_tree ( expr_tree. root ( ) )
499
498
}
500
499
}
501
500
502
501
impl < Pk : FromStrKey > crate :: expression:: FromTree for Tr < Pk > {
503
- fn from_tree ( expr_tree : & expression:: Tree ) -> Result < Self , Error > {
502
+ fn from_tree ( root : expression:: TreeIterItem ) -> Result < Self , Error > {
504
503
use crate :: expression:: { Parens , ParseTreeError } ;
505
504
506
- expr_tree
507
- . verify_toplevel ( "tr" , 1 ..=2 )
505
+ struct TreeStack < ' s , Pk : MiniscriptKey > {
506
+ inner : Vec < ( expression:: TreeIterItem < ' s > , TapTree < Pk > ) > ,
507
+ }
508
+
509
+ impl < ' s , Pk : MiniscriptKey > TreeStack < ' s , Pk > {
510
+ fn new ( ) -> Self { Self { inner : Vec :: with_capacity ( 128 ) } }
511
+
512
+ fn push ( & mut self , parent : expression:: TreeIterItem < ' s > , tree : TapTree < Pk > ) {
513
+ let mut next_push = ( parent, tree) ;
514
+ while let Some ( top) = self . inner . pop ( ) {
515
+ if next_push. 0 . index ( ) == top. 0 . index ( ) {
516
+ next_push. 0 = top. 0 . parent ( ) . unwrap ( ) ;
517
+ next_push. 1 = TapTree :: combine ( top. 1 , next_push. 1 ) ;
518
+ } else {
519
+ self . inner . push ( top) ;
520
+ break ;
521
+ }
522
+ }
523
+ self . inner . push ( next_push) ;
524
+ }
525
+
526
+ fn pop_final ( & mut self ) -> Option < TapTree < Pk > > {
527
+ assert_eq ! ( self . inner. len( ) , 1 ) ;
528
+ self . inner . pop ( ) . map ( |x| x. 1 )
529
+ }
530
+ }
531
+
532
+ root. verify_toplevel ( "tr" , 1 ..=2 )
508
533
. map_err ( From :: from)
509
534
. map_err ( Error :: Parse ) ?;
510
535
511
- let mut round_paren_depth = 0 ;
536
+ let mut root_children = root. children ( ) ;
537
+ let internal_key: Pk = root_children
538
+ . next ( )
539
+ . unwrap ( ) // `verify_toplevel` above checked that first child existed
540
+ . verify_terminal ( "internal key" )
541
+ . map_err ( Error :: Parse ) ?;
512
542
513
- let mut internal_key = None ;
514
- let mut tree_stack = vec ! [ ] ;
543
+ let tap_tree = match root_children. next ( ) {
544
+ None => return Tr :: new ( internal_key, None ) ,
545
+ Some ( tree) => tree,
546
+ } ;
515
547
516
- for item in expr_tree. verbose_pre_order_iter ( ) {
517
- // Top-level "tr" node.
518
- if item. index == 0 {
519
- if item. is_complete {
520
- debug_assert ! (
521
- internal_key. is_some( ) ,
522
- "checked above that top-level 'tr' has children"
523
- ) ;
548
+ let mut tree_stack = TreeStack :: new ( ) ;
549
+ let mut tap_tree_iter = tap_tree. pre_order_iter ( ) ;
550
+ // while let construction needed because we modify the iterator inside the loop
551
+ // (by calling skip_descendants to skip over the contents of the tapscripts).
552
+ while let Some ( node) = tap_tree_iter. next ( ) {
553
+ if node. parens ( ) == Parens :: Curly {
554
+ if !node. name ( ) . is_empty ( ) {
555
+ return Err ( Error :: Parse ( ParseError :: Tree ( ParseTreeError :: IncorrectName {
556
+ actual : node. name ( ) . to_owned ( ) ,
557
+ expected : "" ,
558
+ } ) ) ) ;
524
559
}
525
- } else if item. index == 1 {
526
- // First child of tr, which must be the internal key
527
- internal_key = item
528
- . node
529
- . verify_terminal ( "internal key" )
530
- . map_err ( Error :: Parse )
531
- . map ( Some ) ?;
560
+ node. verify_n_children ( "taptree branch" , 2 ..=2 )
561
+ . map_err ( From :: from)
562
+ . map_err ( Error :: Parse ) ?;
532
563
} else {
533
- // From here on we are into the taptree.
534
- if item. n_children_yielded == 0 {
535
- match item. node . parens ( ) {
536
- Parens :: Curly => {
537
- if !item. node . name ( ) . is_empty ( ) {
538
- return Err ( Error :: Parse ( ParseError :: Tree (
539
- ParseTreeError :: IncorrectName {
540
- actual : item. node . name ( ) . to_owned ( ) ,
541
- expected : "" ,
542
- } ,
543
- ) ) ) ;
544
- }
545
- if round_paren_depth > 0 {
546
- return Err ( Error :: Parse ( ParseError :: Tree (
547
- ParseTreeError :: IllegalCurlyBrace {
548
- pos : item. node . children_pos ( ) ,
549
- } ,
550
- ) ) ) ;
551
- }
552
- }
553
- Parens :: Round => round_paren_depth += 1 ,
554
- _ => { }
555
- }
556
- }
557
- if item. is_complete {
558
- if item. node . parens ( ) == Parens :: Curly {
559
- if item. n_children_yielded == 2 {
560
- let rchild = tree_stack. pop ( ) . unwrap ( ) ;
561
- let lchild = tree_stack. pop ( ) . unwrap ( ) ;
562
- tree_stack. push ( TapTree :: combine ( lchild, rchild) ) ;
563
- } else {
564
- return Err ( Error :: Parse ( ParseError :: Tree (
565
- ParseTreeError :: IncorrectNumberOfChildren {
566
- description : "Taptree node" ,
567
- n_children : item. n_children_yielded ,
568
- minimum : Some ( 2 ) ,
569
- maximum : Some ( 2 ) ,
570
- } ,
571
- ) ) ) ;
572
- }
573
- } else {
574
- if item. node . parens ( ) == Parens :: Round {
575
- round_paren_depth -= 1 ;
576
- }
577
- if round_paren_depth == 0 {
578
- let script = Miniscript :: from_tree ( item. node ) ?;
579
- // FIXME hack for https://github.com/rust-bitcoin/rust-miniscript/issues/734
580
- if script. ty . corr . base != crate :: miniscript:: types:: Base :: B {
581
- return Err ( Error :: NonTopLevel ( format ! ( "{:?}" , script) ) ) ;
582
- } ;
583
- tree_stack. push ( TapTree :: Leaf ( Arc :: new ( script) ) ) ;
584
- }
585
- }
586
- }
564
+ let script = Miniscript :: from_tree ( node) ?;
565
+ // FIXME hack for https://github.com/rust-bitcoin/rust-miniscript/issues/734
566
+ if script. ty . corr . base != crate :: miniscript:: types:: Base :: B {
567
+ return Err ( Error :: NonTopLevel ( format ! ( "{:?}" , script) ) ) ;
568
+ } ;
569
+
570
+ tree_stack. push ( node. parent ( ) . unwrap ( ) , TapTree :: Leaf ( Arc :: new ( script) ) ) ;
571
+ tap_tree_iter. skip_descendants ( ) ;
587
572
}
588
573
}
589
- assert ! ( tree_stack. len( ) <= 1 ) ;
590
- Tr :: new ( internal_key. unwrap ( ) , tree_stack. pop ( ) )
574
+ Tr :: new ( internal_key, tree_stack. pop_final ( ) )
591
575
}
592
576
}
593
577
0 commit comments