@@ -8,10 +8,9 @@ use crate::{
8
8
} ;
9
9
use cosmwasm_std:: { Coin , Decimal } ;
10
10
use nym_mixnet_contract_common:: NodeRewarding ;
11
- use nym_topology:: NodeId ;
12
11
use nym_validator_client:: nyxd:: AccountId ;
13
12
use std:: collections:: { HashMap , HashSet } ;
14
- use tracing:: warn ;
13
+ use tracing:: error ;
15
14
16
15
pub ( crate ) struct AddressDataCollector {
17
16
nyxd_client : crate :: nyxd:: Client ,
@@ -56,18 +55,18 @@ impl AddressDataCollector {
56
55
Ok ( balance)
57
56
}
58
57
59
- pub ( crate ) async fn get_delegations ( & mut self ) -> AxumResult < AddressDelegationInfo > {
58
+ pub ( crate ) async fn get_delegations ( & mut self ) -> AxumResult < Vec < AddressDelegationInfo > > {
60
59
let og_delegations = self
61
60
. nyxd_client
62
61
. get_all_delegator_delegations ( & self . account_id )
63
- . await ?;
62
+ . await ?
63
+ . into_iter ( )
64
+ . map ( |delegation| ( delegation. node_id , delegation) )
65
+ . collect :: < HashMap < _ , _ > > ( ) ;
64
66
65
- let delegated_to_nodes = og_delegations
66
- . iter ( )
67
- . map ( |d| d. node_id )
68
- . collect :: < HashSet < _ > > ( ) ;
67
+ let mut node_delegation_info = Vec :: new ( ) ;
69
68
70
- let nym_nodes = self
69
+ let delegated_to_nodes_bonded = self
71
70
. nym_contract_cache
72
71
. all_cached_nym_nodes ( )
73
72
. await
@@ -85,61 +84,72 @@ impl AddressDataCollector {
85
84
// add to totals
86
85
self . total_value += pending_operator_reward;
87
86
}
88
- if delegated_to_nodes. contains ( & node_details. node_id ( ) ) {
89
- Some ( (
90
- node_details. node_id ( ) ,
91
- // avoid cloning node data which we don't need
92
- (
93
- node_details. rewarding_details . clone ( ) ,
87
+ if let Some ( delegation) = og_delegations. get ( & node_details. node_id ( ) ) {
88
+ node_delegation_info. push ( AddressDelegationInfo {
89
+ details : delegation. clone ( ) ,
90
+ node_reward_info : NodeBondStatus :: Bonded (
91
+ node_details. rewarding_details . to_owned ( ) ,
94
92
node_details. is_unbonding ( ) ,
95
93
) ,
96
- ) )
94
+ } ) ;
95
+
96
+ Some ( node_details. node_id ( ) )
97
97
} else {
98
98
None
99
99
}
100
100
} )
101
- . collect :: < HashMap < _ , _ > > ( ) ;
101
+ . collect :: < HashSet < _ > > ( ) ;
102
+
103
+ for ( node_id, delegation) in og_delegations {
104
+ if !delegated_to_nodes_bonded. contains ( & node_id) {
105
+ node_delegation_info. push ( AddressDelegationInfo {
106
+ details : delegation. clone ( ) ,
107
+ node_reward_info : NodeBondStatus :: UnBonded ,
108
+ } ) ;
109
+ }
110
+ }
102
111
103
- Ok ( AddressDelegationInfo {
104
- delegations : og_delegations,
105
- delegated_to_nodes : nym_nodes,
106
- } )
112
+ Ok ( node_delegation_info)
107
113
}
108
114
109
115
pub ( crate ) async fn calculate_rewards (
110
116
& mut self ,
111
- delegation_data : & AddressDelegationInfo ,
117
+ delegation_data : & Vec < AddressDelegationInfo > ,
112
118
) -> AxumResult < Vec < NyxAccountDelegationRewardDetails > > {
113
119
let mut accumulated_rewards = Vec :: new ( ) ;
114
- for delegation in delegation_data. delegations . iter ( ) {
115
- let node_id = & delegation. node_id ;
116
-
117
- if let Some ( ( rewarding_details , is_unbonding ) ) =
118
- delegation_data . delegated_to_nodes . get ( node_id )
119
- {
120
- match rewarding_details . determine_delegation_reward ( delegation ) {
121
- Ok ( delegation_reward ) => {
122
- let reward = NyxAccountDelegationRewardDetails {
123
- node_id : delegation . node_id ,
124
- rewards : decimal_to_coin ( delegation_reward , & self . base_denom ) ,
125
- amount_staked : delegation . amount . clone ( ) ,
126
- node_still_fully_bonded : !is_unbonding ,
127
- } ;
128
- // 4. sum the rewards and delegations
129
- self . total_delegations += delegation. amount . amount . u128 ( ) ;
130
- self . total_value += delegation . amount . amount . u128 ( ) ;
131
- self . total_value += reward. rewards . amount . u128 ( ) ;
132
- self . claimable_rewards += reward . rewards . amount . u128 ( ) ;
133
-
134
- accumulated_rewards . push ( reward ) ;
135
- }
136
- Err ( err ) => {
137
- warn ! (
138
- "Couldn't determine delegations for {} on node {}: {}" ,
139
- & self . account_id , node_id , err
140
- )
120
+ for delegation in delegation_data {
121
+ let node_id = delegation. details . node_id ;
122
+
123
+ match & delegation . node_reward_info {
124
+ NodeBondStatus :: Bonded ( node_rewarding , is_unbonding ) => {
125
+ match node_rewarding . determine_delegation_reward ( & delegation . details ) {
126
+ Ok ( delegation_reward ) => {
127
+ let reward = NyxAccountDelegationRewardDetails {
128
+ node_id ,
129
+ rewards : decimal_to_coin ( delegation_reward , & self . base_denom ) ,
130
+ amount_staked : delegation . details . amount . clone ( ) ,
131
+ node_still_fully_bonded : !is_unbonding ,
132
+ } ;
133
+ // 4. sum the rewards and delegations
134
+ self . total_delegations += delegation . details . amount . amount . u128 ( ) ;
135
+ self . total_value += delegation. details . amount . amount . u128 ( ) ;
136
+ self . total_value += reward . rewards . amount . u128 ( ) ;
137
+ self . claimable_rewards += reward. rewards . amount . u128 ( ) ;
138
+
139
+ accumulated_rewards . push ( reward ) ;
140
+ }
141
+ Err ( err ) => {
142
+ error ! (
143
+ "Couldn't determine delegations for {} on node {}: {}" ,
144
+ & self . account_id , node_id , err
145
+ )
146
+ }
141
147
}
142
148
}
149
+ NodeBondStatus :: UnBonded => {
150
+ // directory cache doesn't store node details required to
151
+ // calculate rewarding for unbonded nodes
152
+ }
143
153
}
144
154
}
145
155
@@ -171,24 +181,33 @@ impl AddressDataCollector {
171
181
}
172
182
173
183
pub ( crate ) struct AddressDelegationInfo {
174
- delegations : Vec < nym_mixnet_contract_common:: Delegation > ,
175
- delegated_to_nodes : HashMap < NodeId , RewardAndBondInfo > ,
184
+ details : nym_mixnet_contract_common:: Delegation ,
185
+ node_reward_info : NodeBondStatus ,
176
186
}
177
187
178
188
impl AddressDelegationInfo {
179
- pub ( crate ) fn delegations ( self ) -> Vec < nym_mixnet_contract_common:: Delegation > {
180
- self . delegations
189
+ pub ( crate ) fn details ( & self ) -> & nym_mixnet_contract_common:: Delegation {
190
+ & self . details
191
+ }
192
+
193
+ pub ( crate ) fn is_node_bonded ( & self ) -> bool {
194
+ matches ! ( self . node_reward_info, NodeBondStatus :: Bonded ( _, _) )
181
195
}
182
196
}
183
197
184
- type RewardAndBondInfo = ( NodeRewarding , bool ) ;
198
+ pub ( crate ) enum NodeBondStatus {
199
+ /// bool: is node in the process of unbonding
200
+ Bonded ( NodeRewarding , bool ) ,
201
+ UnBonded ,
202
+ }
185
203
186
204
fn decimal_to_coin ( decimal : Decimal , denom : impl Into < String > ) -> Coin {
187
205
Coin :: new ( decimal. to_uint_floor ( ) , denom)
188
206
}
189
207
190
208
#[ cfg( test) ]
191
209
mod test {
210
+
192
211
use super :: * ;
193
212
194
213
#[ tokio:: test]
0 commit comments