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