@@ -6,15 +6,78 @@ use types::{
66        TIMELY_TARGET_FLAG_INDEX , 
77    } , 
88    BeaconState ,  BeaconStateError ,  ChainSpec ,  Epoch ,  EthSpec ,  ParticipationFlags ,  RelativeEpoch , 
9+     Validator , 
910} ; 
1011
12+ #[ derive( PartialEq ,  Debug ,  Clone ,  Copy ) ]  
13+ struct  Balance  { 
14+     balance :  u64 , 
15+     minimum :  u64 , 
16+ } 
17+ 
18+ impl  Balance  { 
19+     pub  fn  balance ( & self )  -> u64  { 
20+         std:: cmp:: max ( self . balance ,  self . minimum ) 
21+     } 
22+ } 
23+ 
1124#[ derive( PartialEq ,  Debug ) ]  
1225struct  EpochParticipation  { 
1326    unslashed_participating_indices :  HashMap < usize ,  ParticipationFlags > , 
1427    total_flag_balances :  [ u64 ;  NUM_FLAG_INDICES ] , 
1528    total_active_balance :  u64 , 
1629} 
1730
31+ impl  EpochParticipation  { 
32+     pub  fn  new ( hashmap_len :  usize )  -> Self  { 
33+         Self  { 
34+             unslashed_participating_indices :  HashMap :: with_capacity ( hashmap_len) , 
35+             total_flag_balances :  <_ >:: default ( ) , 
36+             total_active_balance :  <_ >:: default ( ) , 
37+         } 
38+     } 
39+ 
40+     pub  fn  process_active_validator < T :  EthSpec > ( 
41+         & mut  self , 
42+         val_index :  usize , 
43+         state :  & BeaconState < T > , 
44+         epoch_participation :  & [ ParticipationFlags ] , 
45+     )  -> Result < ( ) ,  BeaconStateError >  { 
46+         let  val_balance = state. get_effective_balance ( val_index) ?; 
47+         self . total_active_balance . safe_add_assign ( val_balance) ?; 
48+ 
49+         if  state. get_validator ( val_index) ?. slashed  { 
50+             return  Ok ( ( ) ) ; 
51+         } 
52+ 
53+         // Iterate through all the flags and increment total balances. 
54+         self . total_flag_balances 
55+             . iter_mut ( ) 
56+             . enumerate ( ) 
57+             . try_for_each ( |( flag,  balance) | { 
58+                 if  epoch_participation
59+                     . get ( val_index) 
60+                     . ok_or ( BeaconStateError :: ParticipationOutOfBounds ( val_index) ) ?
61+                     . has_flag ( flag) ?
62+                 { 
63+                     balance. safe_add_assign ( val_balance) ?; 
64+                 } 
65+ 
66+                 Ok :: < _ ,  BeaconStateError > ( ( ) ) 
67+             } ) ?; 
68+ 
69+         // The validator is active an unslashed, add their `ParticipationFlags` to the map. 
70+         self . unslashed_participating_indices . insert ( 
71+             val_index, 
72+             * epoch_participation
73+                 . get ( val_index) 
74+                 . ok_or ( BeaconStateError :: ParticipationOutOfBounds ( val_index) ) ?, 
75+         ) ; 
76+ 
77+         Ok ( ( ) ) 
78+     } 
79+ } 
80+ 
1881#[ derive( PartialEq ,  Debug ) ]  
1982pub  struct  ParticipationCache  { 
2083    current_epoch :  Epoch , 
@@ -25,6 +88,7 @@ pub struct ParticipationCache {
2588} 
2689
2790impl  ParticipationCache  { 
91+     /* 
2892    pub fn new<T: EthSpec>( 
2993        state: &BeaconState<T>, 
3094        spec: &ChainSpec, 
@@ -40,6 +104,58 @@ impl ParticipationCache {
40104            eligible_indices: state.get_eligible_validator_indices()?, 
41105        }) 
42106    } 
107+     */ 
108+ 
109+     pub  fn  new < T :  EthSpec > ( 
110+         state :  & BeaconState < T > , 
111+         spec :  & ChainSpec , 
112+     )  -> Result < Self ,  BeaconStateError >  { 
113+         let  current_epoch = state. current_epoch ( ) ; 
114+         let  previous_epoch = state. previous_epoch ( ) ; 
115+ 
116+         let  num_previous_epoch_active_vals = state
117+             . get_cached_active_validator_indices ( RelativeEpoch :: Previous ) ?
118+             . len ( ) ; 
119+         let  num_current_epoch_active_vals = state
120+             . get_cached_active_validator_indices ( RelativeEpoch :: Current ) ?
121+             . len ( ) ; 
122+ 
123+         let  mut  current_epoch_participation =
124+             EpochParticipation :: new ( num_current_epoch_active_vals) ; 
125+         let  mut  previous_epoch_participation =
126+             EpochParticipation :: new ( num_previous_epoch_active_vals) ; 
127+         let  mut  eligible_indices = Vec :: with_capacity ( state. validators ( ) . len ( ) ) ; 
128+ 
129+         for  ( val_index,  val)  in  state. validators ( ) . iter ( ) . enumerate ( )  { 
130+             if  val. is_active_at ( current_epoch)  { 
131+                 current_epoch_participation. process_active_validator ( 
132+                     val_index, 
133+                     state, 
134+                     state. current_epoch_participation ( ) ?, 
135+                 ) ?; 
136+             } 
137+ 
138+             if  val. is_active_at ( previous_epoch)  { 
139+                 previous_epoch_participation. process_active_validator ( 
140+                     val_index, 
141+                     state, 
142+                     state. previous_epoch_participation ( ) ?, 
143+                 ) ?; 
144+             } 
145+ 
146+             if  state. is_eligible_validator ( val_index) ? { 
147+                 eligible_indices. push ( val_index) 
148+             } 
149+         } 
150+ 
151+         Ok ( Self  { 
152+             current_epoch, 
153+             current_epoch_participation, 
154+             previous_epoch, 
155+             previous_epoch_participation, 
156+             eligible_indices, 
157+         } ) 
158+     } 
43159
44160    pub  fn  eligible_validator_indices ( & self )  -> & [ usize ]  { 
45161        & self . eligible_indices 
@@ -169,6 +285,7 @@ impl<'a> UnslashedParticipatingIndices<'a> {
169285    } 
170286} 
171287
288+ /* 
172289fn get_epoch_participation<T: EthSpec>( 
173290    state: &BeaconState<T>, 
174291    epoch: Epoch, 
@@ -239,3 +356,4 @@ fn get_epoch_participation<T: EthSpec>(
239356        total_active_balance, 
240357    }) 
241358} 
359+ */ 
0 commit comments