33#![ allow( clippy:: indexing_slicing) ]
44
55use super :: Error ;
6- use crate :: {
7- BeaconState , EthSpec , Hash256 , ParticipationFlags , ParticipationList , Slot , Unsigned , Validator ,
8- } ;
6+ use crate :: { BeaconState , EthSpec , Hash256 , ParticipationList , Slot , Unsigned , Validator } ;
97use cached_tree_hash:: { int_log, CacheArena , CachedTreeHash , TreeHashCache } ;
108use rayon:: prelude:: * ;
119use ssz_derive:: { Decode , Encode } ;
@@ -141,9 +139,10 @@ pub struct BeaconTreeHashCacheInner<T: EthSpec> {
141139 randao_mixes : TreeHashCache ,
142140 slashings : TreeHashCache ,
143141 eth1_data_votes : Eth1DataVotesTreeHashCache < T > ,
142+ inactivity_scores : OptionalTreeHashCache ,
144143 // Participation caches
145- previous_epoch_participation : ParticipationTreeHashCache ,
146- current_epoch_participation : ParticipationTreeHashCache ,
144+ previous_epoch_participation : OptionalTreeHashCache ,
145+ current_epoch_participation : OptionalTreeHashCache ,
147146}
148147
149148impl < T : EthSpec > BeaconTreeHashCacheInner < T > {
@@ -168,10 +167,22 @@ impl<T: EthSpec> BeaconTreeHashCacheInner<T> {
168167 let mut slashings_arena = CacheArena :: default ( ) ;
169168 let slashings = state. slashings ( ) . new_tree_hash_cache ( & mut slashings_arena) ;
170169
171- let previous_epoch_participation =
172- ParticipationTreeHashCache :: new ( state, BeaconState :: previous_epoch_participation) ;
173- let current_epoch_participation =
174- ParticipationTreeHashCache :: new ( state, BeaconState :: current_epoch_participation) ;
170+ let inactivity_scores = OptionalTreeHashCache :: new ( state. inactivity_scores ( ) . ok ( ) ) ;
171+
172+ let previous_epoch_participation = OptionalTreeHashCache :: new (
173+ state
174+ . previous_epoch_participation ( )
175+ . ok ( )
176+ . map ( ParticipationList :: new)
177+ . as_ref ( ) ,
178+ ) ;
179+ let current_epoch_participation = OptionalTreeHashCache :: new (
180+ state
181+ . current_epoch_participation ( )
182+ . ok ( )
183+ . map ( ParticipationList :: new)
184+ . as_ref ( ) ,
185+ ) ;
175186
176187 Self {
177188 previous_state : None ,
@@ -185,6 +196,7 @@ impl<T: EthSpec> BeaconTreeHashCacheInner<T> {
185196 balances,
186197 randao_mixes,
187198 slashings,
199+ inactivity_scores,
188200 eth1_data_votes : Eth1DataVotesTreeHashCache :: new ( state) ,
189201 previous_epoch_participation,
190202 current_epoch_participation,
@@ -287,12 +299,16 @@ impl<T: EthSpec> BeaconTreeHashCacheInner<T> {
287299 } else {
288300 hasher. write (
289301 self . previous_epoch_participation
290- . recalculate_tree_hash_root ( state. previous_epoch_participation ( ) ?) ?
302+ . recalculate_tree_hash_root ( & ParticipationList :: new (
303+ state. previous_epoch_participation ( ) ?,
304+ ) ) ?
291305 . as_bytes ( ) ,
292306 ) ?;
293307 hasher. write (
294308 self . current_epoch_participation
295- . recalculate_tree_hash_root ( state. current_epoch_participation ( ) ?) ?
309+ . recalculate_tree_hash_root ( & ParticipationList :: new (
310+ state. current_epoch_participation ( ) ?,
311+ ) ) ?
296312 . as_bytes ( ) ,
297313 ) ?;
298314 }
@@ -314,8 +330,11 @@ impl<T: EthSpec> BeaconTreeHashCacheInner<T> {
314330
315331 // Inactivity & light-client sync committees
316332 if let BeaconState :: Altair ( ref state) = state {
317- // FIXME(altair): add cache for this field
318- hasher. write ( state. inactivity_scores . tree_hash_root ( ) . as_bytes ( ) ) ?;
333+ hasher. write (
334+ self . inactivity_scores
335+ . recalculate_tree_hash_root ( & state. inactivity_scores ) ?
336+ . as_bytes ( ) ,
337+ ) ?;
319338
320339 hasher. write ( state. current_sync_committee . tree_hash_root ( ) . as_bytes ( ) ) ?;
321340 hasher. write ( state. next_sync_committee . tree_hash_root ( ) . as_bytes ( ) ) ?;
@@ -513,53 +532,43 @@ impl ParallelValidatorTreeHash {
513532}
514533
515534#[ derive( Debug , PartialEq , Clone ) ]
516- pub struct ParticipationTreeHashCache {
517- inner : Option < ParticipationTreeHashCacheInner > ,
535+ pub struct OptionalTreeHashCache {
536+ inner : Option < OptionalTreeHashCacheInner > ,
518537}
519538
520539#[ derive( Debug , PartialEq , Clone ) ]
521- pub struct ParticipationTreeHashCacheInner {
540+ pub struct OptionalTreeHashCacheInner {
522541 arena : CacheArena ,
523542 tree_hash_cache : TreeHashCache ,
524543}
525544
526- impl ParticipationTreeHashCache {
527- /// Initialize a new cache for the participation list returned by `field` (if any).
528- fn new < T : EthSpec > (
529- state : & BeaconState < T > ,
530- field : impl FnOnce (
531- & BeaconState < T > ,
532- ) -> Result <
533- & VariableList < ParticipationFlags , T :: ValidatorRegistryLimit > ,
534- Error ,
535- > ,
536- ) -> Self {
537- let inner = field ( state) . map ( ParticipationTreeHashCacheInner :: new) . ok ( ) ;
545+ impl OptionalTreeHashCache {
546+ /// Initialize a new cache if `item.is_some()`.
547+ fn new < C : CachedTreeHash < TreeHashCache > > ( item : Option < & C > ) -> Self {
548+ let inner = item. map ( OptionalTreeHashCacheInner :: new) ;
538549 Self { inner }
539550 }
540551
541- /// Compute the tree hash root for the given `epoch_participation `.
552+ /// Compute the tree hash root for the given `item `.
542553 ///
543554 /// This function will initialize the inner cache if necessary (e.g. when crossing the fork).
544- fn recalculate_tree_hash_root < N : Unsigned > (
555+ fn recalculate_tree_hash_root < C : CachedTreeHash < TreeHashCache > > (
545556 & mut self ,
546- epoch_participation : & VariableList < ParticipationFlags , N > ,
557+ item : & C ,
547558 ) -> Result < Hash256 , Error > {
548559 let cache = self
549560 . inner
550- . get_or_insert_with ( || ParticipationTreeHashCacheInner :: new ( epoch_participation) ) ;
551- ParticipationList :: new ( epoch_participation)
552- . recalculate_tree_hash_root ( & mut cache. arena , & mut cache. tree_hash_cache )
561+ . get_or_insert_with ( || OptionalTreeHashCacheInner :: new ( item) ) ;
562+ item. recalculate_tree_hash_root ( & mut cache. arena , & mut cache. tree_hash_cache )
553563 . map_err ( Into :: into)
554564 }
555565}
556566
557- impl ParticipationTreeHashCacheInner {
558- fn new < N : Unsigned > ( epoch_participation : & VariableList < ParticipationFlags , N > ) -> Self {
567+ impl OptionalTreeHashCacheInner {
568+ fn new < C : CachedTreeHash < TreeHashCache > > ( item : & C ) -> Self {
559569 let mut arena = CacheArena :: default ( ) ;
560- let tree_hash_cache =
561- ParticipationList :: new ( epoch_participation) . new_tree_hash_cache ( & mut arena) ;
562- ParticipationTreeHashCacheInner {
570+ let tree_hash_cache = item. new_tree_hash_cache ( & mut arena) ;
571+ OptionalTreeHashCacheInner {
563572 arena,
564573 tree_hash_cache,
565574 }
@@ -576,7 +585,7 @@ impl<T: EthSpec> arbitrary::Arbitrary for BeaconTreeHashCache<T> {
576585#[ cfg( test) ]
577586mod test {
578587 use super :: * ;
579- use crate :: MainnetEthSpec ;
588+ use crate :: { MainnetEthSpec , ParticipationFlags } ;
580589
581590 #[ test]
582591 fn validator_node_count ( ) {
@@ -594,13 +603,13 @@ mod test {
594603 test_flag. add_flag ( 0 ) . unwrap ( ) ;
595604 let epoch_participation = VariableList :: < _ , N > :: new ( vec ! [ test_flag; len] ) . unwrap ( ) ;
596605
597- let mut cache = ParticipationTreeHashCache { inner : None } ;
606+ let mut cache = OptionalTreeHashCache { inner : None } ;
598607
599608 let cache_root = cache
600- . recalculate_tree_hash_root ( & epoch_participation)
609+ . recalculate_tree_hash_root ( & ParticipationList :: new ( & epoch_participation) )
601610 . unwrap ( ) ;
602611 let recalc_root = cache
603- . recalculate_tree_hash_root ( & epoch_participation)
612+ . recalculate_tree_hash_root ( & ParticipationList :: new ( & epoch_participation) )
604613 . unwrap ( ) ;
605614
606615 assert_eq ! ( cache_root, recalc_root, "recalculated root should match" ) ;
0 commit comments