@@ -14,7 +14,6 @@ use sync::Arc;
1414use super :: checksum;
1515use crate :: descriptor:: DefiniteDescriptorKey ;
1616use crate :: expression:: { self , FromTree } ;
17- use crate :: iter:: TreeLike as _;
1817use crate :: miniscript:: satisfy:: { Placeholder , Satisfaction , SchnorrSigType , Witness } ;
1918use crate :: miniscript:: Miniscript ;
2019use crate :: plan:: AssetProvider ;
@@ -495,99 +494,84 @@ impl<Pk: FromStrKey> core::str::FromStr for Tr<Pk> {
495494
496495 fn from_str ( s : & str ) -> Result < Self , Self :: Err > {
497496 let expr_tree = expression:: Tree :: from_str ( s) ?;
498- Self :: from_tree ( & expr_tree)
497+ Self :: from_tree ( expr_tree. root ( ) )
499498 }
500499}
501500
502501impl < 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 > {
504503 use crate :: expression:: { Parens , ParseTreeError } ;
505504
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 )
508533 . map_err ( From :: from)
509534 . map_err ( Error :: Parse ) ?;
510535
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 ) ?;
512542
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+ } ;
515547
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+ } ) ) ) ;
524559 }
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 ) ?;
532563 } 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 ( ) ;
587572 }
588573 }
589- assert ! ( tree_stack. len( ) <= 1 ) ;
590- Tr :: new ( internal_key. unwrap ( ) , tree_stack. pop ( ) )
574+ Tr :: new ( internal_key, tree_stack. pop_final ( ) )
591575 }
592576}
593577
0 commit comments