1
1
use std:: collections:: BTreeMap ;
2
2
3
- use serde:: { Deserialize , Serialize } ;
4
-
5
3
use crate :: { BigNum , Channel , DomainError , ValidatorDesc } ;
6
4
use num:: rational:: Ratio ;
7
5
8
- type InnerBTreeMap = BTreeMap < String , BigNum > ;
6
+ pub type BalancesMap = BTreeMap < String , BigNum > ;
9
7
10
- #[ derive( Default , Clone , Debug , Serialize , Deserialize , PartialEq ) ]
11
- #[ serde( transparent) ]
12
- pub struct BalancesMap ( InnerBTreeMap ) ;
8
+ pub fn get_balances_after_fees_tree (
9
+ balances : & BalancesMap ,
10
+ channel : & Channel ,
11
+ ) -> Result < BalancesMap , DomainError > {
12
+ let distribution = Distribution :: new ( balances, & channel) ?;
13
13
14
- impl BalancesMap {
15
- pub fn apply_fees ( & self , on_channel : & Channel ) -> Result < Self , DomainError > {
16
- let distribution = Distribution :: new ( & self . 0 , & on_channel) ?;
14
+ let mut balances_after_fees = BTreeMap :: default ( ) ;
15
+ let mut total = BigNum :: from ( 0 ) ;
17
16
18
- let mut balances_after_fees = BTreeMap :: default ( ) ;
19
- let mut total = BigNum :: from ( 0 ) ;
17
+ for ( key , value ) in balances . iter ( ) {
18
+ let adjusted_balance = value * & distribution . ratio ;
20
19
21
- for ( key, value) in self . 0 . iter ( ) {
22
- let adjusted_balance = value * & distribution. ratio ;
20
+ total += & adjusted_balance;
21
+ balances_after_fees. insert ( key. clone ( ) , adjusted_balance) ;
22
+ }
23
23
24
- total += & adjusted_balance;
25
- balances_after_fees. insert ( key. clone ( ) , adjusted_balance) ;
26
- }
24
+ let rounding_error = distribution. rounding_error ( & total) ?;
27
25
28
- let rounding_error = distribution. rounding_error ( & total) ?;
26
+ let balances_after_fees = distribute_fee (
27
+ balances_after_fees,
28
+ rounding_error,
29
+ distribution. fee_ratio ,
30
+ channel. spec . validators . into_iter ( ) ,
31
+ ) ;
29
32
30
- let balances_after_fees = Self :: distribute_fee (
31
- balances_after_fees,
32
- rounding_error,
33
- distribution. fee_ratio ,
34
- on_channel. spec . validators . into_iter ( ) ,
35
- ) ;
33
+ Ok ( balances_after_fees)
34
+ }
36
35
37
- Ok ( Self ( balances_after_fees) )
38
- }
36
+ fn distribute_fee < ' a > (
37
+ mut balances : BalancesMap ,
38
+ rounding_error : BigNum ,
39
+ fee_ratio : Ratio < BigNum > ,
40
+ validators : impl Iterator < Item = & ' a ValidatorDesc > ,
41
+ ) -> BalancesMap {
42
+ for ( index, validator) in validators. enumerate ( ) {
43
+ let fee = & validator. fee * & fee_ratio;
44
+
45
+ let fee_rounded = if index == 0 {
46
+ & fee + & rounding_error
47
+ } else {
48
+ fee
49
+ } ;
39
50
40
- fn distribute_fee < ' a > (
41
- mut balances : InnerBTreeMap ,
42
- rounding_error : BigNum ,
43
- fee_ratio : Ratio < BigNum > ,
44
- validators : impl Iterator < Item = & ' a ValidatorDesc > ,
45
- ) -> InnerBTreeMap {
46
- for ( index, validator) in validators. enumerate ( ) {
47
- let fee = & validator. fee * & fee_ratio;
48
-
49
- let fee_rounded = if index == 0 {
50
- & fee + & rounding_error
51
- } else {
52
- fee
53
- } ;
54
-
55
- if fee_rounded > 0 . into ( ) {
56
- let entry = balances
57
- . entry ( validator. id . clone ( ) . into ( ) )
58
- . or_insert_with ( || 0 . into ( ) ) ;
59
-
60
- * entry += & fee_rounded;
61
- }
62
- }
51
+ if fee_rounded > 0 . into ( ) {
52
+ let entry = balances
53
+ . entry ( validator. id . clone ( ) . into ( ) )
54
+ . or_insert_with ( || 0 . into ( ) ) ;
63
55
64
- balances
56
+ * entry += & fee_rounded;
57
+ }
65
58
}
59
+
60
+ balances
66
61
}
67
62
68
63
#[ derive( Debug ) ]
@@ -82,7 +77,7 @@ struct Distribution {
82
77
}
83
78
84
79
impl Distribution {
85
- pub fn new ( for_balances : & InnerBTreeMap , on_channel : & Channel ) -> Result < Self , DomainError > {
80
+ pub fn new ( for_balances : & BalancesMap , on_channel : & Channel ) -> Result < Self , DomainError > {
86
81
let deposit = on_channel. deposit_amount . clone ( ) ;
87
82
88
83
let total_distributed: BigNum = for_balances. iter ( ) . map ( |( _, balance) | balance) . sum ( ) ;
@@ -144,63 +139,60 @@ mod test {
144
139
145
140
mod applying_fee_returns_the_same_tree_with_zero_fees {
146
141
use super :: * ;
147
- fn setup_balances_map ( tree : & InnerBTreeMap ) -> BalancesMap {
142
+ fn setup_balances_map ( balances_map : & BalancesMap ) -> BalancesMap {
148
143
let channel = get_zero_fee_channel ( ) ;
149
144
150
- let balances_map = BalancesMap ( tree. clone ( ) ) ;
151
-
152
- let balances_after_fee = balances_map
153
- . apply_fees ( & channel)
145
+ let balances_after_fee = get_balances_after_fees_tree ( balances_map, & channel)
154
146
. expect ( "Calculation of fees failed" ) ;
155
147
156
148
balances_after_fee
157
149
}
158
150
159
151
#[ test]
160
152
fn case_1_three_values ( ) {
161
- let tree : InnerBTreeMap = vec ! [
153
+ let balances_map : BalancesMap = vec ! [
162
154
( "a" . to_string( ) , 1001 . into( ) ) ,
163
155
( "b" . to_string( ) , 3124 . into( ) ) ,
164
156
( "c" . to_string( ) , 122 . into( ) ) ,
165
157
]
166
158
. into_iter ( )
167
159
. collect ( ) ;
168
160
169
- assert_eq ! ( setup_balances_map( & tree ) . 0 , tree ) ;
161
+ assert_eq ! ( setup_balances_map( & balances_map ) , balances_map ) ;
170
162
}
171
163
172
164
#[ test]
173
165
fn case_2_three_simple_values ( ) {
174
- let tree : InnerBTreeMap = vec ! [
166
+ let balances_map : BalancesMap = vec ! [
175
167
( "a" . to_string( ) , 1 . into( ) ) ,
176
168
( "b" . to_string( ) , 2 . into( ) ) ,
177
169
( "c" . to_string( ) , 3 . into( ) ) ,
178
170
]
179
171
. into_iter ( )
180
172
. collect ( ) ;
181
173
182
- assert_eq ! ( setup_balances_map( & tree ) . 0 , tree ) ;
174
+ assert_eq ! ( setup_balances_map( & balances_map ) , balances_map ) ;
183
175
}
184
176
185
177
#[ test]
186
178
fn case_3_one_value ( ) {
187
- let tree : InnerBTreeMap = vec ! [ ( "a" . to_string( ) , BigNum :: from( 1 ) ) ]
179
+ let balances_map = vec ! [ ( "a" . to_string( ) , BigNum :: from( 1 ) ) ]
188
180
. into_iter ( )
189
181
. collect ( ) ;
190
182
191
- assert_eq ! ( setup_balances_map( & tree ) . 0 , tree ) ;
183
+ assert_eq ! ( setup_balances_map( & balances_map ) , balances_map ) ;
192
184
}
193
185
194
186
#[ test]
195
187
fn case_4_two_values ( ) {
196
- let tree : InnerBTreeMap = vec ! [
188
+ let balances_map = vec ! [
197
189
( "a" . to_string( ) , 1 . into( ) ) ,
198
190
( "b" . to_string( ) , 99_999 . into( ) ) ,
199
191
]
200
192
. into_iter ( )
201
193
. collect ( ) ;
202
194
203
- assert_eq ! ( setup_balances_map( & tree ) . 0 , tree ) ;
195
+ assert_eq ! ( setup_balances_map( & balances_map ) , balances_map ) ;
204
196
}
205
197
206
198
fn get_zero_fee_channel ( ) -> Channel {
@@ -218,33 +210,30 @@ mod test {
218
210
mod applying_fee_correctly {
219
211
use super :: * ;
220
212
221
- fn setup_balances_after_fee ( tree : InnerBTreeMap ) -> BalancesMap {
213
+ fn setup_balances_after_fee ( balances_map : BalancesMap ) -> BalancesMap {
222
214
let leader = get_validator ( "one" , Some ( 50 . into ( ) ) ) ;
223
215
let follower = get_validator ( "two" , Some ( 50 . into ( ) ) ) ;
224
216
225
217
let spec = get_channel_spec ( ValidatorsOption :: Pair { leader, follower } ) ;
226
218
let mut channel = get_channel ( "apply fees" , & None , Some ( spec) ) ;
227
219
channel. deposit_amount = 10_000 . into ( ) ;
228
220
229
- let balances_map = BalancesMap ( tree) ;
230
-
231
- let balances_after_fee = balances_map
232
- . apply_fees ( & channel)
221
+ let balances_after_fee = get_balances_after_fees_tree ( & balances_map, & channel)
233
222
. expect ( "Calculation of fees failed" ) ;
234
223
235
224
balances_after_fee
236
225
}
237
226
238
227
#[ test]
239
228
fn case_1_partially_distributed ( ) {
240
- let tree = vec ! [
229
+ let balances_map = vec ! [
241
230
( "a" . to_string( ) , 1_000 . into( ) ) ,
242
231
( "b" . to_string( ) , 1_200 . into( ) ) ,
243
232
]
244
233
. into_iter ( )
245
234
. collect ( ) ;
246
235
247
- let expected_tree : InnerBTreeMap = vec ! [
236
+ let expected_balances : BalancesMap = vec ! [
248
237
( "a" . to_string( ) , 990 . into( ) ) ,
249
238
( "b" . to_string( ) , 1_188 . into( ) ) ,
250
239
( "one" . to_string( ) , 11 . into( ) ) ,
@@ -253,27 +242,30 @@ mod test {
253
242
. into_iter ( )
254
243
. collect ( ) ;
255
244
256
- let balances_after_fee = setup_balances_after_fee ( tree ) . 0 ;
245
+ let balances_after_fee = setup_balances_after_fee ( balances_map ) ;
257
246
let actual_sum: BigNum = balances_after_fee. iter ( ) . map ( |( _, v) | v) . sum ( ) ;
258
247
259
248
assert_eq ! (
260
- expected_tree. iter( ) . map( |( _, value) | value) . sum:: <BigNum >( ) ,
249
+ expected_balances
250
+ . iter( )
251
+ . map( |( _, value) | value)
252
+ . sum:: <BigNum >( ) ,
261
253
actual_sum
262
254
) ;
263
- assert_eq ! ( expected_tree , balances_after_fee) ;
255
+ assert_eq ! ( expected_balances , balances_after_fee) ;
264
256
}
265
257
266
258
#[ test]
267
- fn case_2_partially_distributed_with_validator_in_the_input_tree ( ) {
268
- let tree = vec ! [
259
+ fn case_2_partially_distributed_with_validator_in_the_input_balances_map ( ) {
260
+ let balances_map = vec ! [
269
261
( "a" . to_string( ) , 100 . into( ) ) ,
270
262
( "b" . to_string( ) , 2_000 . into( ) ) ,
271
263
( "one" . to_string( ) , 200 . into( ) ) ,
272
264
]
273
265
. into_iter ( )
274
266
. collect ( ) ;
275
267
276
- let expected_tree : InnerBTreeMap = vec ! [
268
+ let expected_balances : BalancesMap = vec ! [
277
269
( "a" . to_string( ) , 99 . into( ) ) ,
278
270
( "b" . to_string( ) , 1_980 . into( ) ) ,
279
271
( "one" . to_string( ) , 209 . into( ) ) ,
@@ -282,20 +274,23 @@ mod test {
282
274
. into_iter ( )
283
275
. collect ( ) ;
284
276
285
- let balances_after_fee = setup_balances_after_fee ( tree ) . 0 ;
277
+ let balances_after_fee = setup_balances_after_fee ( balances_map ) ;
286
278
let actual_sum: BigNum = balances_after_fee. iter ( ) . map ( |( _, v) | v) . sum ( ) ;
287
279
288
280
assert_eq ! (
289
- expected_tree. iter( ) . map( |( _, value) | value) . sum:: <BigNum >( ) ,
281
+ expected_balances
282
+ . iter( )
283
+ . map( |( _, value) | value)
284
+ . sum:: <BigNum >( ) ,
290
285
actual_sum
291
286
) ;
292
- assert_eq ! ( expected_tree , balances_after_fee) ;
287
+ assert_eq ! ( expected_balances , balances_after_fee) ;
293
288
}
294
289
295
290
#[ test]
296
291
/// also testing the rounding error correction
297
292
fn case_3_fully_distributed ( ) {
298
- let tree = vec ! [
293
+ let balances_map = vec ! [
299
294
( "a" . to_string( ) , 105 . into( ) ) ,
300
295
( "b" . to_string( ) , 195 . into( ) ) ,
301
296
( "c" . to_string( ) , 700 . into( ) ) ,
@@ -305,7 +300,7 @@ mod test {
305
300
. into_iter ( )
306
301
. collect ( ) ;
307
302
308
- let expected_tree : InnerBTreeMap = vec ! [
303
+ let expected_balances : BalancesMap = vec ! [
309
304
( "a" . to_string( ) , 103 . into( ) ) ,
310
305
( "b" . to_string( ) , 193 . into( ) ) ,
311
306
( "c" . to_string( ) , 693 . into( ) ) ,
@@ -317,20 +312,23 @@ mod test {
317
312
. into_iter ( )
318
313
. collect ( ) ;
319
314
320
- let balances_after_fee = setup_balances_after_fee ( tree ) . 0 ;
315
+ let balances_after_fee = setup_balances_after_fee ( balances_map ) ;
321
316
let actual_sum: BigNum = balances_after_fee. iter ( ) . map ( |( _, v) | v) . sum ( ) ;
322
317
323
318
assert_eq ! (
324
- expected_tree. iter( ) . map( |( _, value) | value) . sum:: <BigNum >( ) ,
319
+ expected_balances
320
+ . iter( )
321
+ . map( |( _, value) | value)
322
+ . sum:: <BigNum >( ) ,
325
323
actual_sum
326
324
) ;
327
- assert_eq ! ( expected_tree , balances_after_fee) ;
325
+ assert_eq ! ( expected_balances , balances_after_fee) ;
328
326
}
329
327
}
330
328
331
329
#[ test]
332
330
fn errors_when_fees_larger_that_deposit ( ) {
333
- let tree : InnerBTreeMap = vec ! [ ( "a" . to_string( ) , 10 . into( ) ) , ( "b" . to_string( ) , 10 . into( ) ) ]
331
+ let balances_map = vec ! [ ( "a" . to_string( ) , 10 . into( ) ) , ( "b" . to_string( ) , 10 . into( ) ) ]
334
332
. into_iter ( )
335
333
. collect ( ) ;
336
334
@@ -340,10 +338,7 @@ mod test {
340
338
let mut channel = get_channel ( "zero fees" , & None , Some ( spec) ) ;
341
339
channel. deposit_amount = 1_000 . into ( ) ;
342
340
343
- let balances_map = BalancesMap ( tree. clone ( ) ) ;
344
-
345
- let domain_error = balances_map
346
- . apply_fees ( & channel)
341
+ let domain_error = get_balances_after_fees_tree ( & balances_map, & channel)
347
342
. expect_err ( "Should be DomainError not allow fees sum to exceed the deposit" ) ;
348
343
349
344
assert_eq ! (
0 commit comments