@@ -417,5 +417,77 @@ mod tests {
417417                "Policy contains duplicate keys" 
418418            ) ; 
419419        } 
420+ 
421+         // Non-trivial multi-node compilation 
422+         { 
423+             let  node_policies = [ 
424+                 "and(pk(A),pk(B))" , 
425+                 "and(pk(C),older(12960))" , 
426+                 "pk(D)" , 
427+                 "pk(E)" , 
428+                 "thresh(3,pk(F),pk(G),pk(H))" , 
429+                 "and(and(or(2@pk(I),1@pk(J)),or(1@pk(K),20@pk(L))),pk(M))" , 
430+                 "pk(N)" , 
431+             ] ; 
432+ 
433+             // Floating-point precision errors cause the minor errors 
434+             let  node_probabilities:  [ f64 ;  7 ]  =
435+                 [ 0.12000002 ,  0.28 ,  0.08 ,  0.12 ,  0.19 ,  0.18999998 ,  0.02 ] ; 
436+ 
437+             let  policy:  Concrete < String >  = policy_str ! ( 
438+                 "{}" , 
439+                 & format!( 
440+                     "or(4@or(3@{},7@{}),6@thresh(1,or(4@{},6@{}),{},or(9@{},1@{})))" , 
441+                     node_policies[ 0 ] , 
442+                     node_policies[ 1 ] , 
443+                     node_policies[ 2 ] , 
444+                     node_policies[ 3 ] , 
445+                     node_policies[ 4 ] , 
446+                     node_policies[ 5 ] , 
447+                     node_policies[ 6 ] 
448+                 ) 
449+             ) ; 
450+             let  descriptor = policy. compile_tr ( Some ( unspendable_key. clone ( ) ) ) . unwrap ( ) ; 
451+ 
452+             let  mut  sorted_policy_prob = node_policies
453+                 . into_iter ( ) 
454+                 . zip ( node_probabilities. into_iter ( ) ) 
455+                 . collect :: < Vec < _ > > ( ) ; 
456+             sorted_policy_prob. sort_by ( |a,  b| ( a. 1 ) . partial_cmp ( & b. 1 ) . unwrap ( ) ) ; 
457+             let  sorted_policies = sorted_policy_prob
458+                 . into_iter ( ) 
459+                 . map ( |( x,  _prob) | x) 
460+                 . collect :: < Vec < _ > > ( ) ; 
461+ 
462+             // Generate TapTree leaves compilations from the given sub-policies 
463+             let  node_compilations = sorted_policies
464+                 . into_iter ( ) 
465+                 . map ( |x| { 
466+                     let  leaf_policy:  Concrete < String >  = policy_str ! ( "{}" ,  x) ; 
467+                     TapTree :: Leaf ( Arc :: from ( leaf_policy. compile :: < Tap > ( ) . unwrap ( ) ) ) 
468+                 } ) 
469+                 . collect :: < Vec < _ > > ( ) ; 
470+ 
471+             // Arrange leaf compilations (acc. to probabilities) using huffman encoding into a TapTree 
472+             let  tree = TapTree :: Tree ( 
473+                 Arc :: from ( TapTree :: Tree ( 
474+                     Arc :: from ( node_compilations[ 4 ] . clone ( ) ) , 
475+                     Arc :: from ( node_compilations[ 5 ] . clone ( ) ) , 
476+                 ) ) , 
477+                 Arc :: from ( TapTree :: Tree ( 
478+                     Arc :: from ( TapTree :: Tree ( 
479+                         Arc :: from ( TapTree :: Tree ( 
480+                             Arc :: from ( node_compilations[ 0 ] . clone ( ) ) , 
481+                             Arc :: from ( node_compilations[ 1 ] . clone ( ) ) , 
482+                         ) ) , 
483+                         Arc :: from ( node_compilations[ 3 ] . clone ( ) ) , 
484+                     ) ) , 
485+                     Arc :: from ( node_compilations[ 6 ] . clone ( ) ) , 
486+                 ) ) , 
487+             ) ; 
488+ 
489+             let  expected_descriptor = Descriptor :: new_tr ( "E" . to_string ( ) ,  Some ( tree) ) . unwrap ( ) ; 
490+             assert_eq ! ( descriptor,  expected_descriptor) ; 
491+         } 
420492    } 
421493} 
0 commit comments