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