@@ -10,7 +10,9 @@ use crate::miniscript::context;
10
10
use crate :: miniscript:: satisfy:: Placeholder ;
11
11
use crate :: plan:: Assets ;
12
12
use crate :: prelude:: * ;
13
- use crate :: { DescriptorPublicKey , MiniscriptKey , ScriptContext , ToPublicKey } ;
13
+ use crate :: {
14
+ DescriptorPublicKey , Error , MiniscriptKey , ScriptContext , ToPublicKey , MAX_ASSET_THRESHOLD ,
15
+ } ;
14
16
pub ( crate ) fn varint_len ( n : usize ) -> usize { bitcoin:: VarInt ( n as u64 ) . len ( ) }
15
17
16
18
pub ( crate ) trait ItemSize {
@@ -56,7 +58,7 @@ pub(crate) fn witness_to_scriptsig(witness: &[Vec<u8>]) -> ScriptBuf {
56
58
} else {
57
59
let push = <& PushBytes >:: try_from ( wit. as_slice ( ) )
58
60
. expect ( "All pushes in miniscript are <73 bytes" ) ;
59
- b = b. push_slice ( push)
61
+ b = b. push_slice ( push) ;
60
62
}
61
63
}
62
64
b. into_script ( )
@@ -134,7 +136,7 @@ pub fn combine_assets(
134
136
}
135
137
136
138
// Do product of K combinations
137
- pub fn get_combinations_product ( values : & [ u64 ] , k : u64 ) -> Vec < u64 > {
139
+ pub fn get_combinations_product ( values : & [ u32 ] , k : u32 ) -> Vec < u32 > {
138
140
let mut products = Vec :: new ( ) ;
139
141
let n = values. len ( ) ;
140
142
@@ -145,10 +147,10 @@ pub fn get_combinations_product(values: &[u64], k: u64) -> Vec<u64> {
145
147
// Using bitwise operations to generate combinations
146
148
let max_combinations = 1u32 << n;
147
149
for combination_bits in 1 ..max_combinations {
148
- if combination_bits. count_ones ( ) as usize == k as usize {
150
+ if ( combination_bits. count_ones ( ) as usize ) == ( k as usize ) {
149
151
let mut product = 1 ;
150
152
for i in 0 ..n {
151
- if combination_bits & ( 1u32 << i) != 0 {
153
+ if ( combination_bits & ( 1u32 << i) ) != 0 {
152
154
product *= values[ i] ;
153
155
}
154
156
}
@@ -160,9 +162,20 @@ pub fn get_combinations_product(values: &[u64], k: u64) -> Vec<u64> {
160
162
}
161
163
162
164
// ways to select k things out of n
163
- pub fn k_of_n ( k : u64 , n : u64 ) -> u64 {
164
- if k == 0 || k == n {
165
- return 1 ;
165
+ pub fn k_of_n ( k : u32 , n : u32 ) -> Result < u32 , Error > {
166
+ let mut k = k;
167
+ if k > n - k {
168
+ k = n - k;
166
169
}
167
- k_of_n ( k - 1 , n - 1 ) + k_of_n ( k, n - 1 )
170
+
171
+ let mut result = 1 ;
172
+ for i in 0 ..k {
173
+ result *= n - i;
174
+ result /= i + 1 ;
175
+ if result > MAX_ASSET_THRESHOLD . into ( ) {
176
+ return Err ( Error :: MaxAssetThresholdExceeded ) ;
177
+ }
178
+ }
179
+
180
+ Ok ( result)
168
181
}
0 commit comments