@@ -19,7 +19,7 @@ use crate::miniscript::types::{self, Property};
1919use crate :: miniscript:: ScriptContext ;
2020use crate :: plan:: Assets ;
2121use crate :: prelude:: * ;
22- use crate :: util:: { MsKeyBuilder , get_asset_combination } ;
22+ use crate :: util:: { asset_combination , get_combinations_product , k_of_n , MsKeyBuilder } ;
2323use crate :: {
2424 errstr, expression, AbsLockTime , DescriptorPublicKey , Error , Miniscript , MiniscriptKey ,
2525 Terminal , ToPublicKey ,
@@ -605,7 +605,6 @@ impl<Ctx: ScriptContext> Terminal<DescriptorPublicKey, Ctx> {
605605 Terminal :: PkK ( _) => 1 ,
606606 Terminal :: PkH ( _) => 1 ,
607607 Terminal :: RawPkH ( _) => 1 ,
608- // What happens to timelocks ? for both the assets and the count.
609608 Terminal :: After ( _) => 0 ,
610609 Terminal :: Older ( _) => 0 ,
611610 Terminal :: Sha256 ( _) => 1 ,
@@ -619,12 +618,7 @@ impl<Ctx: ScriptContext> Terminal<DescriptorPublicKey, Ctx> {
619618 Terminal :: Verify ( k) => k. count_assets ( ) ,
620619 Terminal :: NonZero ( k) => k. count_assets ( ) ,
621620 Terminal :: ZeroNotEqual ( k) => k. count_assets ( ) ,
622- Terminal :: AndV ( left, right) => {
623- let left_count = left. count_assets ( ) ;
624- let right_count = right. count_assets ( ) ;
625- left_count * right_count
626- }
627- Terminal :: AndB ( left, right) => {
621+ Terminal :: AndV ( left, right) | Terminal :: AndB ( left, right) => {
628622 let left_count = left. count_assets ( ) ;
629623 let right_count = right. count_assets ( ) ;
630624 left_count * right_count
@@ -635,51 +629,30 @@ impl<Ctx: ScriptContext> Terminal<DescriptorPublicKey, Ctx> {
635629 let c = c. count_assets ( ) ;
636630 ( a * b) + c
637631 }
638- Terminal :: OrB ( left, right) => {
639- let left_count = left. count_assets ( ) ;
640- let right_count = right. count_assets ( ) ;
641- left_count + right_count
642- }
643- Terminal :: OrD ( left, right) => {
644- let left_count = left. count_assets ( ) ;
645- let right_count = right. count_assets ( ) ;
646- left_count + right_count
647- }
648- Terminal :: OrC ( left, right) => {
649- let left_count = left. count_assets ( ) ;
650- let right_count = right. count_assets ( ) ;
651- left_count + right_count
652- }
653- Terminal :: OrI ( left, right) => {
632+ Terminal :: OrB ( left, right)
633+ | Terminal :: OrC ( left, right)
634+ | Terminal :: OrD ( left, right)
635+ | Terminal :: OrI ( left, right) => {
654636 let left_count = left. count_assets ( ) ;
655637 let right_count = right. count_assets ( ) ;
656638 left_count + right_count
657639 }
658640 Terminal :: Thresh ( k, ms_v) => {
659- // k = 2, n = ms_v.len()
660- // ms_v = [ms(A),ms(B),ms(C)];
661- // Assume count array as [5,7,8] and k=2
662- // get_combinations_product gives [5*7,5*8,7*8] = [35,40,56]
663641 let mut count_array = Vec :: new ( ) ;
664642 for ms in ms_v {
665643 count_array. push ( ms. count_assets ( ) ) ;
666644 }
667- let products = Self :: get_combinations_product ( & count_array, * k as u64 ) ;
645+ let products = get_combinations_product ( & count_array, * k as u64 ) ;
668646 let mut total_count: u64 = 0 ;
669647 for product in products {
670648 total_count += product;
671649 }
672650 total_count
673651 }
674- Terminal :: Multi ( k, dpk) => {
652+ Terminal :: Multi ( k, dpk) | Terminal :: MultiA ( k , dpk ) => {
675653 let k: u64 = * k as u64 ;
676654 let n: u64 = dpk. len ( ) as u64 ;
677- Self :: k_of_n ( k, n)
678- }
679- Terminal :: MultiA ( k, dpk) => {
680- let k: u64 = * k as u64 ;
681- let n: u64 = dpk. len ( ) as u64 ;
682- Self :: k_of_n ( k, n)
655+ k_of_n ( k, n)
683656 }
684657 }
685658 }
@@ -741,9 +714,7 @@ impl<Ctx: ScriptContext> Terminal<DescriptorPublicKey, Ctx> {
741714 Terminal :: Verify ( k) => k. all_assets ( ) ,
742715 Terminal :: NonZero ( k) => k. all_assets ( ) ,
743716 Terminal :: ZeroNotEqual ( k) => k. all_assets ( ) ,
744- Terminal :: AndB ( left, right) |
745- Terminal :: AndV ( left, right)
746- => {
717+ Terminal :: AndB ( left, right) | Terminal :: AndV ( left, right) => {
747718 let a = left. all_assets ( ) ;
748719 let b = right. all_assets ( ) ;
749720 let result: Vec < Assets > = a
@@ -777,11 +748,10 @@ impl<Ctx: ScriptContext> Terminal<DescriptorPublicKey, Ctx> {
777748 c. extend ( and) ;
778749 c
779750 }
780- Terminal :: OrB ( left, right) |
781- Terminal :: OrC ( left, right) |
782- Terminal :: OrD ( left, right) |
783- Terminal :: OrI ( left, right)
784- => {
751+ Terminal :: OrB ( left, right)
752+ | Terminal :: OrC ( left, right)
753+ | Terminal :: OrD ( left, right)
754+ | Terminal :: OrI ( left, right) => {
785755 let mut a = left. all_assets ( ) ;
786756 let b = right. all_assets ( ) ;
787757 a. extend ( b) ;
@@ -792,14 +762,14 @@ impl<Ctx: ScriptContext> Terminal<DescriptorPublicKey, Ctx> {
792762 // Eg : thresh(2,ms(A),ms(B),ms(C)) Here ms(A),ms(B) and ms(C) are miniscript policies
793763 // k = 2
794764 // ms = [ms(A),ms(B),ms(C)];
795- // We would consider the possible combinations of k policies into the ms_v
765+ // We would consider the possible combinations of k policies into the ms_v
796766 // here k=2 so all possible combinations of 2.
797767 // ms_v = [[ms(A),ms(B)],[ms(A),ms(C)],[ms(B),ms(C)]]
798- // Between each set of combination we would need to do an OR
768+ // Between each set of combination we would need to do an OR
799769 // (i.e ms_v[0] OR ms_v[1] OR ms_v[3])
800770 // Now inside of each policy combination we need to have AND
801771 // Eg : ms_v[0] = [ms(A),ms(B)] so here -> ms(A) AND ms(B)
802-
772+
803773 let ms_v = Self :: get_ms_combination_thresh ( * k, ms) ;
804774 let mut result = Vec :: new ( ) ;
805775 for ms in ms_v {
@@ -826,8 +796,7 @@ impl<Ctx: ScriptContext> Terminal<DescriptorPublicKey, Ctx> {
826796 }
827797 result
828798 }
829- Terminal :: Multi ( k, dpk_v) |
830- Terminal :: MultiA ( k, dpk_v ) => get_asset_combination ( * k, dpk_v) ,
799+ Terminal :: Multi ( k, dpk_v) | Terminal :: MultiA ( k, dpk_v) => asset_combination ( * k, dpk_v) ,
831800 }
832801 }
833802
@@ -860,38 +829,4 @@ impl<Ctx: ScriptContext> Terminal<DescriptorPublicKey, Ctx> {
860829 current_combination. truncate ( current_combination. len ( ) - 1 ) ;
861830 }
862831 }
863-
864- // Do product of K combinations
865- fn get_combinations_product ( values : & [ u64 ] , k : u64 ) -> Vec < u64 > {
866- let mut products = Vec :: new ( ) ;
867- let n = values. len ( ) ;
868-
869- if k == 0 {
870- return vec ! [ 1 ] ; // Empty combination has a product of 1
871- }
872-
873- // Using bitwise operations to generate combinations
874- let max_combinations = 1u32 << n;
875- for combination_bits in 1 ..max_combinations {
876- if combination_bits. count_ones ( ) as usize == k as usize {
877- let mut product = 1 ;
878- for i in 0 ..n {
879- if combination_bits & ( 1u32 << i) != 0 {
880- product *= values[ i] ;
881- }
882- }
883- products. push ( product) ;
884- }
885- }
886-
887- products
888- }
889-
890- // ways to select k things out of n
891- fn k_of_n ( k : u64 , n : u64 ) -> u64 {
892- if k == 0 || k == n {
893- return 1 ;
894- }
895- Self :: k_of_n ( k - 1 , n - 1 ) + Self :: k_of_n ( k, n - 1 )
896- }
897832}
0 commit comments