@@ -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 {
15
17
bitcoin:: VarInt ( n as u64 ) . len ( )
16
18
}
@@ -60,7 +62,7 @@ pub(crate) fn witness_to_scriptsig(witness: &[Vec<u8>]) -> ScriptBuf {
60
62
} else {
61
63
let push = <& PushBytes >:: try_from ( wit. as_slice ( ) )
62
64
. expect ( "All pushes in miniscript are <73 bytes" ) ;
63
- b = b. push_slice ( push)
65
+ b = b. push_slice ( push) ;
64
66
}
65
67
}
66
68
b. into_script ( )
@@ -138,7 +140,7 @@ pub fn combine_assets(
138
140
}
139
141
140
142
// Do product of K combinations
141
- pub fn get_combinations_product ( values : & [ u64 ] , k : u64 ) -> Vec < u64 > {
143
+ pub fn get_combinations_product ( values : & [ u32 ] , k : u32 ) -> Vec < u32 > {
142
144
let mut products = Vec :: new ( ) ;
143
145
let n = values. len ( ) ;
144
146
@@ -149,10 +151,10 @@ pub fn get_combinations_product(values: &[u64], k: u64) -> Vec<u64> {
149
151
// Using bitwise operations to generate combinations
150
152
let max_combinations = 1u32 << n;
151
153
for combination_bits in 1 ..max_combinations {
152
- if combination_bits. count_ones ( ) as usize == k as usize {
154
+ if ( combination_bits. count_ones ( ) as usize ) == ( k as usize ) {
153
155
let mut product = 1 ;
154
156
for i in 0 ..n {
155
- if combination_bits & ( 1u32 << i) != 0 {
157
+ if ( combination_bits & ( 1u32 << i) ) != 0 {
156
158
product *= values[ i] ;
157
159
}
158
160
}
@@ -164,9 +166,20 @@ pub fn get_combinations_product(values: &[u64], k: u64) -> Vec<u64> {
164
166
}
165
167
166
168
// ways to select k things out of n
167
- pub fn k_of_n ( k : u64 , n : u64 ) -> u64 {
168
- if k == 0 || k == n {
169
- return 1 ;
169
+ pub fn k_of_n ( k : u32 , n : u32 ) -> Result < u32 , Error > {
170
+ let mut k = k;
171
+ if k > n - k {
172
+ k = n - k;
170
173
}
171
- k_of_n ( k - 1 , n - 1 ) + k_of_n ( k, n - 1 )
174
+
175
+ let mut result = 1 ;
176
+ for i in 0 ..k {
177
+ result *= n - i;
178
+ result /= i + 1 ;
179
+ if result > MAX_ASSET_THRESHOLD . into ( ) {
180
+ return Err ( Error :: MaxAssetThresholdExceeded ) ;
181
+ }
182
+ }
183
+
184
+ Ok ( result)
172
185
}
0 commit comments