@@ -19,7 +19,7 @@ use crate::miniscript::types::{self, Property};
19
19
use crate :: miniscript:: ScriptContext ;
20
20
use crate :: plan:: Assets ;
21
21
use crate :: prelude:: * ;
22
- use crate :: util:: { MsKeyBuilder , get_asset_combination } ;
22
+ use crate :: util:: { asset_combination , get_combinations_product , k_of_n , MsKeyBuilder } ;
23
23
use crate :: {
24
24
errstr, expression, AbsLockTime , DescriptorPublicKey , Error , Miniscript , MiniscriptKey ,
25
25
Terminal , ToPublicKey ,
@@ -605,7 +605,6 @@ impl<Ctx: ScriptContext> Terminal<DescriptorPublicKey, Ctx> {
605
605
Terminal :: PkK ( _) => 1 ,
606
606
Terminal :: PkH ( _) => 1 ,
607
607
Terminal :: RawPkH ( _) => 1 ,
608
- // What happens to timelocks ? for both the assets and the count.
609
608
Terminal :: After ( _) => 0 ,
610
609
Terminal :: Older ( _) => 0 ,
611
610
Terminal :: Sha256 ( _) => 1 ,
@@ -619,12 +618,7 @@ impl<Ctx: ScriptContext> Terminal<DescriptorPublicKey, Ctx> {
619
618
Terminal :: Verify ( k) => k. count_assets ( ) ,
620
619
Terminal :: NonZero ( k) => k. count_assets ( ) ,
621
620
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) => {
628
622
let left_count = left. count_assets ( ) ;
629
623
let right_count = right. count_assets ( ) ;
630
624
left_count * right_count
@@ -635,51 +629,30 @@ impl<Ctx: ScriptContext> Terminal<DescriptorPublicKey, Ctx> {
635
629
let c = c. count_assets ( ) ;
636
630
( a * b) + c
637
631
}
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) => {
654
636
let left_count = left. count_assets ( ) ;
655
637
let right_count = right. count_assets ( ) ;
656
638
left_count + right_count
657
639
}
658
640
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]
663
641
let mut count_array = Vec :: new ( ) ;
664
642
for ms in ms_v {
665
643
count_array. push ( ms. count_assets ( ) ) ;
666
644
}
667
- let products = Self :: get_combinations_product ( & count_array, * k as u64 ) ;
645
+ let products = get_combinations_product ( & count_array, * k as u64 ) ;
668
646
let mut total_count: u64 = 0 ;
669
647
for product in products {
670
648
total_count += product;
671
649
}
672
650
total_count
673
651
}
674
- Terminal :: Multi ( k, dpk) => {
652
+ Terminal :: Multi ( k, dpk) | Terminal :: MultiA ( k , dpk ) => {
675
653
let k: u64 = * k as u64 ;
676
654
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)
683
656
}
684
657
}
685
658
}
@@ -741,9 +714,7 @@ impl<Ctx: ScriptContext> Terminal<DescriptorPublicKey, Ctx> {
741
714
Terminal :: Verify ( k) => k. all_assets ( ) ,
742
715
Terminal :: NonZero ( k) => k. all_assets ( ) ,
743
716
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) => {
747
718
let a = left. all_assets ( ) ;
748
719
let b = right. all_assets ( ) ;
749
720
let result: Vec < Assets > = a
@@ -777,11 +748,10 @@ impl<Ctx: ScriptContext> Terminal<DescriptorPublicKey, Ctx> {
777
748
c. extend ( and) ;
778
749
c
779
750
}
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) => {
785
755
let mut a = left. all_assets ( ) ;
786
756
let b = right. all_assets ( ) ;
787
757
a. extend ( b) ;
@@ -792,14 +762,14 @@ impl<Ctx: ScriptContext> Terminal<DescriptorPublicKey, Ctx> {
792
762
// Eg : thresh(2,ms(A),ms(B),ms(C)) Here ms(A),ms(B) and ms(C) are miniscript policies
793
763
// k = 2
794
764
// 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
796
766
// here k=2 so all possible combinations of 2.
797
767
// 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
799
769
// (i.e ms_v[0] OR ms_v[1] OR ms_v[3])
800
770
// Now inside of each policy combination we need to have AND
801
771
// Eg : ms_v[0] = [ms(A),ms(B)] so here -> ms(A) AND ms(B)
802
-
772
+
803
773
let ms_v = Self :: get_ms_combination_thresh ( * k, ms) ;
804
774
let mut result = Vec :: new ( ) ;
805
775
for ms in ms_v {
@@ -826,8 +796,7 @@ impl<Ctx: ScriptContext> Terminal<DescriptorPublicKey, Ctx> {
826
796
}
827
797
result
828
798
}
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) ,
831
800
}
832
801
}
833
802
@@ -860,38 +829,4 @@ impl<Ctx: ScriptContext> Terminal<DescriptorPublicKey, Ctx> {
860
829
current_combination. truncate ( current_combination. len ( ) - 1 ) ;
861
830
}
862
831
}
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
- }
897
832
}
0 commit comments