@@ -110,7 +110,7 @@ pub const EpochCache = struct {
110110 // next_active_indices
111111
112112 // EpochCache does not take ownership of EffectiveBalanceIncrements, it is shared across EpochCache instances
113- effective_balance_increment : * EffectiveBalanceIncrementsRc ,
113+ effective_balance_increments : * EffectiveBalanceIncrementsRc ,
114114
115115 total_slashings_by_increment : u64 ,
116116
@@ -169,7 +169,7 @@ pub const EpochCache = struct {
169169 try syncPubkeys (validators , pubkey_to_index , index_to_pubkey );
170170 }
171171
172- const effective_balance_increment = try getEffectiveBalanceIncrementsWithLen (allocator , validator_count );
172+ const effective_balance_increments = try getEffectiveBalanceIncrementsWithLen (allocator , validator_count );
173173 const state_fork_seq = state .forkSeq ();
174174 const total_slashings_by_increment = switch (state_fork_seq ) {
175175 inline else = > | f | try getTotalSlashingsByIncrement (f , state .castToFork (f )),
@@ -188,15 +188,15 @@ pub const EpochCache = struct {
188188 const validator = validators [i ];
189189
190190 // Note: Not usable for fork-choice balances since in-active validators are not zero'ed
191- effective_balance_increment .items [i ] = @intCast (@divFloor (validator .effective_balance , preset .EFFECTIVE_BALANCE_INCREMENT ));
191+ effective_balance_increments .items [i ] = @intCast (@divFloor (validator .effective_balance , preset .EFFECTIVE_BALANCE_INCREMENT ));
192192
193193 if (isActiveValidator (& validator , previous_epoch )) {
194194 try previous_active_indices_array_list .append (i );
195195 }
196196
197197 if (isActiveValidator (& validator , current_epoch )) {
198198 try current_active_indices_array_list .append (i );
199- total_active_balance_increments += effective_balance_increment .items [i ];
199+ total_active_balance_increments += effective_balance_increments .items [i ];
200200 }
201201
202202 if (isActiveValidator (& validator , next_epoch )) {
@@ -242,6 +242,7 @@ pub const EpochCache = struct {
242242 inline else = > | f | try getSeed (f , state .castToFork (f ), current_epoch , c .DOMAIN_BEACON_PROPOSER , & current_proposer_seed ),
243243 }
244244 var proposers = [_ ]ValidatorIndex {0 } ** preset .SLOTS_PER_EPOCH ;
245+ var next_proposers : ? [preset .SLOTS_PER_EPOCH ]ValidatorIndex = null ;
245246 if (current_shuffling .active_indices .len > 0 ) {
246247 switch (fork_seq ) {
247248 inline else = > | f | try computeProposers (
@@ -250,10 +251,22 @@ pub const EpochCache = struct {
250251 current_proposer_seed ,
251252 current_epoch ,
252253 current_shuffling .active_indices ,
253- effective_balance_increment ,
254+ effective_balance_increments ,
254255 & proposers ,
255256 ),
256257 }
258+ if (fork_seq .gte (.fulu )) {
259+ // Post-Fulu, EIP-7917 introduced the `proposer_lookahead`
260+ switch (fork_seq ) {
261+ inline else = > | f | {
262+ next_proposers = undefined ;
263+ var proposer_lookahead = try state .castToFork (f ).proposerLookahead ();
264+ for (0.. preset .SLOTS_PER_EPOCH ) | i | {
265+ next_proposers .? [i ] = @intCast (try proposer_lookahead .get (preset .SLOTS_PER_EPOCH + i ));
266+ }
267+ },
268+ }
269+ }
257270 }
258271
259272 // Only after altair, compute the indices of the current sync committee
@@ -341,14 +354,14 @@ pub const EpochCache = struct {
341354 .proposers = proposers ,
342355 // On first epoch, set to null to prevent unnecessary work since this is only used for metrics
343356 .proposers_prev_epoch = null ,
344- .proposers_next_epoch = null ,
357+ .proposers_next_epoch = next_proposers ,
345358 .previous_decision_root = previous_decision_root ,
346359 .current_decision_root = current_decision_root ,
347360 .next_decision_root = next_decision_root ,
348361 .previous_shuffling = try EpochShufflingRc .init (allocator , previous_shuffling ),
349362 .current_shuffling = try EpochShufflingRc .init (allocator , current_shuffling ),
350363 .next_shuffling = try EpochShufflingRc .init (allocator , next_shuffling ),
351- .effective_balance_increment = try EffectiveBalanceIncrementsRc .init (allocator , effective_balance_increment ),
364+ .effective_balance_increments = try EffectiveBalanceIncrementsRc .init (allocator , effective_balance_increments ),
352365 .total_slashings_by_increment = total_slashings_by_increment ,
353366 .sync_participant_reward = sync_participant_reward ,
354367 .sync_proposer_reward = sync_proposer_reward ,
@@ -378,7 +391,7 @@ pub const EpochCache = struct {
378391 self .next_shuffling .release ();
379392
380393 // unref the effective balance increments
381- self .effective_balance_increment .release ();
394+ self .effective_balance_increments .release ();
382395
383396 // unref the sync committee caches
384397 self .current_sync_committee_indexed .release ();
@@ -402,7 +415,7 @@ pub const EpochCache = struct {
402415 .current_shuffling = self .current_shuffling .acquire (),
403416 .next_shuffling = self .next_shuffling .acquire (),
404417 // reuse the same instances, increase reference count, cloned only when necessary before an epoch transition
405- .effective_balance_increment = self .effective_balance_increment .acquire (),
418+ .effective_balance_increments = self .effective_balance_increments .acquire (),
406419 .total_slashings_by_increment = self .total_slashings_by_increment ,
407420 // Basic types (numbers) cloned implicitly
408421 .sync_participant_reward = self .sync_participant_reward ,
@@ -449,7 +462,7 @@ pub const EpochCache = struct {
449462
450463 /// Utility method to return SyncCommitteeCache so that consumers don't have to deal with ".get()" call
451464 pub fn getEffectiveBalanceIncrements (self : * const EpochCache ) EffectiveBalanceIncrements {
452- return self .effective_balance_increment .get ();
465+ return self .effective_balance_increments .get ();
453466 }
454467
455468 pub fn afterProcessEpoch (self : * EpochCache , state : * AnyBeaconState , epoch_transition_cache : * const EpochTransitionCache ) ! void {
@@ -526,7 +539,7 @@ pub const EpochCache = struct {
526539 upcoming_proposer_seed ,
527540 self .epoch ,
528541 self .current_shuffling .get ().active_indices ,
529- self .effective_balance_increment .get (),
542+ self .effective_balance_increments .get (),
530543 & self .proposers ,
531544 );
532545 }
@@ -536,11 +549,11 @@ pub const EpochCache = struct {
536549
537550 pub fn beforeEpochTransition (self : * EpochCache ) ! void {
538551 // Clone (copy) before being mutated in processEffectiveBalanceUpdates
539- var effective_balance_increment = try EffectiveBalanceIncrements .initCapacity (self .allocator , self .effective_balance_increment .get ().items .len );
540- try effective_balance_increment .appendSlice (self .effective_balance_increment .get ().items );
552+ var effective_balance_increment = try EffectiveBalanceIncrements .initCapacity (self .allocator , self .effective_balance_increments .get ().items .len );
553+ try effective_balance_increment .appendSlice (self .effective_balance_increments .get ().items );
541554 // unref the previous effective balance increment
542- self .effective_balance_increment .release ();
543- self .effective_balance_increment = try EffectiveBalanceIncrementsRc .init (self .allocator , effective_balance_increment );
555+ self .effective_balance_increments .release ();
556+ self .effective_balance_increments = try EffectiveBalanceIncrementsRc .init (self .allocator , effective_balance_increment );
544557 }
545558
546559 /// Consumer borrows the returned slice
@@ -770,14 +783,14 @@ pub const EpochCache = struct {
770783
771784 /// This is different from typescript version: only allocate new EffectiveBalanceIncrements if needed
772785 pub fn effectiveBalanceIncrementsSet (self : * EpochCache , allocator : Allocator , index : usize , effective_balance : u64 ) ! void {
773- var effective_balance_increments = self .effective_balance_increment .get ();
786+ var effective_balance_increments = self .effective_balance_increments .get ();
774787 if (index >= effective_balance_increments .items .len ) {
775788 // Clone and extend effectiveBalanceIncrements
776789 effective_balance_increments = try getEffectiveBalanceIncrementsWithLen (self .allocator , index + 1 );
777- self .effective_balance_increment .release ();
778- self .effective_balance_increment = try EffectiveBalanceIncrementsRc .init (allocator , effective_balance_increments );
790+ self .effective_balance_increments .release ();
791+ self .effective_balance_increments = try EffectiveBalanceIncrementsRc .init (allocator , effective_balance_increments );
779792 }
780- self .effective_balance_increment .get ().items [index ] = @intCast (@divFloor (effective_balance , preset .EFFECTIVE_BALANCE_INCREMENT ));
793+ self .effective_balance_increments .get ().items [index ] = @intCast (@divFloor (effective_balance , preset .EFFECTIVE_BALANCE_INCREMENT ));
781794 }
782795
783796 pub fn isPostElectra (self : * const EpochCache ) bool {
0 commit comments