@@ -5,24 +5,58 @@ pub fn get_balances_after_fees_tree(
5
5
balances : & BalancesMap ,
6
6
channel : & Channel ,
7
7
) -> Result < BalancesMap , DomainError > {
8
- let distribution = Distribution :: new ( balances, & channel) ?;
8
+ let deposit = channel. deposit_amount . clone ( ) ;
9
+
10
+ let total_distributed = balances. iter ( ) . map ( |( _, balance) | balance) . sum :: < BigNum > ( ) ;
11
+
12
+ let validators_iter = channel. spec . validators . into_iter ( ) ;
13
+ let total_validators_fee = validators_iter
14
+ . map ( |validator| & validator. fee )
15
+ . sum :: < BigNum > ( ) ;
16
+
17
+ if total_validators_fee > deposit {
18
+ return Err ( DomainError :: RuleViolation (
19
+ "total fees <= deposit: fee constraint violated" . into ( ) ,
20
+ ) ) ;
21
+ }
22
+
23
+ if total_distributed > deposit {
24
+ return Err ( DomainError :: RuleViolation (
25
+ "distributed <= deposit: OUTPACE rule #4" . into ( ) ,
26
+ ) ) ;
27
+ }
28
+
29
+ let to_distribute = & deposit - & total_validators_fee;
30
+
31
+ let ratio = Ratio :: new ( to_distribute. clone ( ) , deposit. clone ( ) ) ;
32
+ let fee_ratio = Ratio :: new ( total_distributed. clone ( ) , deposit. clone ( ) ) ;
9
33
10
34
let mut balances_after_fees = BalancesMap :: default ( ) ;
11
35
let mut total = BigNum :: from ( 0 ) ;
12
36
13
37
for ( key, value) in balances. iter ( ) {
14
- let adjusted_balance = value * & distribution . ratio ;
38
+ let adjusted_balance = value * & ratio;
15
39
16
40
total += & adjusted_balance;
17
41
balances_after_fees. insert ( key. clone ( ) , adjusted_balance) ;
18
42
}
19
43
20
- let rounding_error = distribution. rounding_error ( & total) ?;
44
+ let rounding_error = if deposit == total_distributed {
45
+ & to_distribute - & total_distributed
46
+ } else {
47
+ BigNum :: from ( 0 )
48
+ } ;
49
+
50
+ if rounding_error < BigNum :: from ( 0 ) {
51
+ return Err ( DomainError :: RuleViolation (
52
+ "The Rounding error should never be negative" . into ( ) ,
53
+ ) ) ;
54
+ }
21
55
22
56
let balances_after_fees = distribute_fee (
23
57
balances_after_fees,
24
58
rounding_error,
25
- distribution . fee_ratio ,
59
+ fee_ratio,
26
60
channel. spec . validators . into_iter ( ) ,
27
61
) ;
28
62
@@ -56,77 +90,6 @@ fn distribute_fee<'a>(
56
90
balances
57
91
}
58
92
59
- #[ derive( Debug ) ]
60
- struct Distribution {
61
- pub deposit : BigNum ,
62
- /// Total Distributed is the sum of all balances in the BalancesMap
63
- pub total_distributed : BigNum ,
64
- /// The Sum of all validators fee
65
- pub validators_fee : BigNum ,
66
- /// Deposit - Validators fee
67
- pub to_distribute : BigNum ,
68
- /// The ratio that is (Deposit - TotalValidatorFee) / Deposit
69
- pub ratio : Ratio < BigNum > ,
70
- /// Total Distributed / Deposit
71
- pub fee_ratio : Ratio < BigNum > ,
72
- _secret : ( ) ,
73
- }
74
-
75
- impl Distribution {
76
- pub fn new ( for_balances : & BalancesMap , on_channel : & Channel ) -> Result < Self , DomainError > {
77
- let deposit = on_channel. deposit_amount . clone ( ) ;
78
-
79
- let total_distributed: BigNum = for_balances. iter ( ) . map ( |( _, balance) | balance) . sum ( ) ;
80
-
81
- let validators_iter = on_channel. spec . validators . into_iter ( ) ;
82
- let total_validators_fee: BigNum = validators_iter. map ( |validator| & validator. fee ) . sum ( ) ;
83
-
84
- if total_validators_fee > deposit {
85
- return Err ( DomainError :: RuleViolation (
86
- "total fees <= deposit: fee constraint violated" . into ( ) ,
87
- ) ) ;
88
- }
89
-
90
- if total_distributed > deposit {
91
- return Err ( DomainError :: RuleViolation (
92
- "distributed <= deposit: OUTPACE rule #4" . into ( ) ,
93
- ) ) ;
94
- }
95
-
96
- let to_distribute = & deposit - & total_validators_fee;
97
-
98
- let ratio = Ratio :: new ( to_distribute. clone ( ) , deposit. clone ( ) ) ;
99
- let fee_ratio = Ratio :: new ( total_distributed. clone ( ) , deposit. clone ( ) ) ;
100
-
101
- Ok ( Self {
102
- deposit,
103
- total_distributed,
104
- validators_fee : total_validators_fee,
105
- to_distribute,
106
- ratio,
107
- fee_ratio,
108
- _secret : ( ) ,
109
- } )
110
- }
111
-
112
- /// Returns the rounding error and also checks for rule violation if it is < 0
113
- pub fn rounding_error ( & self , total_distributed : & BigNum ) -> Result < BigNum , DomainError > {
114
- let rounding_error = if self . deposit == self . total_distributed {
115
- & self . to_distribute - total_distributed
116
- } else {
117
- BigNum :: from ( 0 )
118
- } ;
119
-
120
- if rounding_error < BigNum :: from ( 0 ) {
121
- Err ( DomainError :: RuleViolation (
122
- "The Rounding error should never be negative" . into ( ) ,
123
- ) )
124
- } else {
125
- Ok ( rounding_error)
126
- }
127
- }
128
- }
129
-
130
93
#[ cfg( test) ]
131
94
mod test {
132
95
use super :: * ;
0 commit comments