@@ -12,12 +12,17 @@ use rand::{Rng, RngCore};
12
12
fn test_wv ( mut rng : impl RngCore ) -> impl Iterator < Item = Candidate > {
13
13
core:: iter:: repeat_with ( move || {
14
14
let value = rng. gen_range ( 0 ..1_000 ) ;
15
- Candidate {
15
+ let mut candidate = Candidate {
16
16
value,
17
17
weight : 100 ,
18
18
input_count : rng. gen_range ( 1 ..2 ) ,
19
19
is_segwit : rng. gen_bool ( 0.5 ) ,
20
- }
20
+ } ;
21
+ // HACK: set is_segwit = true for all these tests because you can't actually lower bound
22
+ // things easily with how segwit inputs interfere with their weights. We can't modify the
23
+ // above since that would change what we pull from rng.
24
+ candidate. is_segwit = true ;
25
+ candidate
21
26
} )
22
27
}
23
28
@@ -28,21 +33,21 @@ struct MinExcessThenWeight {
28
33
impl BnBMetric for MinExcessThenWeight {
29
34
type Score = ( i64 , u32 ) ;
30
35
31
- fn score < ' a > ( & mut self , cs : & CoinSelector < ' a > ) -> Option < Self :: Score > {
36
+ fn score ( & mut self , cs : & CoinSelector < ' _ > ) -> Option < Self :: Score > {
32
37
if cs. excess ( self . target , Drain :: none ( ) ) < 0 {
33
38
None
34
39
} else {
35
- Some ( ( cs. excess ( self . target , Drain :: none ( ) ) , cs. selected_weight ( ) ) )
40
+ Some ( ( cs. excess ( self . target , Drain :: none ( ) ) , cs. input_weight ( ) ) )
36
41
}
37
42
}
38
43
39
- fn bound < ' a > ( & mut self , cs : & CoinSelector < ' a > ) -> Option < Self :: Score > {
44
+ fn bound ( & mut self , cs : & CoinSelector < ' _ > ) -> Option < Self :: Score > {
40
45
let lower_bound_excess = cs. excess ( self . target , Drain :: none ( ) ) . max ( 0 ) ;
41
46
let lower_bound_weight = {
42
47
let mut cs = cs. clone ( ) ;
43
48
cs. select_until_target_met ( self . target , Drain :: none ( ) )
44
49
. ok ( ) ?;
45
- cs. selected_weight ( )
50
+ cs. input_weight ( )
46
51
} ;
47
52
Some ( ( lower_bound_excess, lower_bound_weight) )
48
53
}
@@ -56,13 +61,21 @@ fn bnb_finds_an_exact_solution_in_n_iter() {
56
61
let num_additional_canidates = 50 ;
57
62
58
63
let mut rng = TestRng :: deterministic_rng ( RngAlgorithm :: ChaCha ) ;
59
- let mut wv = test_wv ( & mut rng) ;
64
+ let mut wv = test_wv ( & mut rng) . map ( |mut candidate| {
65
+ candidate. is_segwit = true ;
66
+ candidate
67
+ } ) ;
60
68
61
69
let solution: Vec < Candidate > = ( 0 ..solution_len) . map ( |_| wv. next ( ) . unwrap ( ) ) . collect ( ) ;
62
- let solution_weight = solution. iter ( ) . map ( |sol| sol. weight ) . sum ( ) ;
70
+ let solution_weight = {
71
+ let mut cs = CoinSelector :: new ( & solution, 0 ) ;
72
+ cs. select_all ( ) ;
73
+ cs. input_weight ( )
74
+ } ;
75
+
63
76
let target = solution. iter ( ) . map ( |c| c. value ) . sum ( ) ;
64
77
65
- let mut candidates = solution. clone ( ) ;
78
+ let mut candidates = solution;
66
79
candidates. extend ( wv. take ( num_additional_canidates) ) ;
67
80
candidates. sort_unstable_by_key ( |wv| core:: cmp:: Reverse ( wv. value ) ) ;
68
81
@@ -86,7 +99,7 @@ fn bnb_finds_an_exact_solution_in_n_iter() {
86
99
87
100
assert_eq ! ( i, 806 ) ;
88
101
89
- assert ! ( best. selected_weight ( ) <= solution_weight) ;
102
+ assert ! ( best. input_weight ( ) <= solution_weight) ;
90
103
assert_eq ! ( best. selected_value( ) , target. value) ;
91
104
}
92
105
@@ -97,6 +110,7 @@ fn bnb_finds_solution_if_possible_in_n_iter() {
97
110
let mut rng = TestRng :: deterministic_rng ( RngAlgorithm :: ChaCha ) ;
98
111
let wv = test_wv ( & mut rng) ;
99
112
let candidates = wv. take ( num_inputs) . collect :: < Vec < _ > > ( ) ;
113
+
100
114
let cs = CoinSelector :: new ( & candidates, 0 ) ;
101
115
102
116
let target = Target {
@@ -151,13 +165,20 @@ proptest! {
151
165
let mut wv = test_wv( & mut rng) ;
152
166
153
167
let solution: Vec <Candidate > = ( 0 ..solution_len) . map( |_| wv. next( ) . unwrap( ) ) . collect( ) ;
168
+ let solution_weight = {
169
+ let mut cs = CoinSelector :: new( & solution, 0 ) ;
170
+ cs. select_all( ) ;
171
+ cs. input_weight( )
172
+ } ;
173
+
154
174
let target = solution. iter( ) . map( |c| c. value) . sum( ) ;
155
- let solution_weight = solution. iter( ) . map( |sol| sol. weight) . sum( ) ;
156
175
157
- let mut candidates = solution. clone ( ) ;
176
+ let mut candidates = solution;
158
177
candidates. extend( wv. take( num_additional_canidates) ) ;
159
178
160
179
let mut cs = CoinSelector :: new( & candidates, 0 ) ;
180
+
181
+
161
182
for i in 0 ..num_preselected. min( solution_len) {
162
183
cs. select( i) ;
163
184
}
@@ -182,7 +203,7 @@ proptest! {
182
203
183
204
184
205
185
- prop_assert!( best. selected_weight ( ) <= solution_weight) ;
206
+ prop_assert!( best. input_weight ( ) <= solution_weight) ;
186
207
prop_assert_eq!( best. selected_value( ) , target. value) ;
187
208
}
188
209
}
0 commit comments