2023-06-11 21:50:02 +00:00
package statechange
2023-02-09 21:26:36 +00:00
2023-02-11 22:15:30 +00:00
import (
2023-07-19 22:20:33 +00:00
"github.com/ledgerwatch/erigon/cl/abstract"
2023-02-11 22:15:30 +00:00
"sort"
2023-02-09 21:26:36 +00:00
2023-05-28 15:11:18 +00:00
"github.com/ledgerwatch/erigon/cl/cltypes/solid"
2023-06-11 21:50:02 +00:00
"github.com/ledgerwatch/erigon/cl/phase1/core/state"
2023-05-28 15:11:18 +00:00
2023-03-04 21:14:45 +00:00
"github.com/ledgerwatch/erigon/cl/clparams"
)
2023-02-09 21:26:36 +00:00
// computeActivationExitEpoch is Implementation of compute_activation_exit_epoch. Defined in https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#compute_activation_exit_epoch.
2023-03-04 21:14:45 +00:00
func computeActivationExitEpoch ( beaconConfig * clparams . BeaconChainConfig , epoch uint64 ) uint64 {
return epoch + 1 + beaconConfig . MaxSeedLookahead
2023-02-09 21:26:36 +00:00
}
// ProcessRegistyUpdates updates every epoch the activation status of validators. Specs at: https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#registry-updates.
2023-07-19 22:20:33 +00:00
func ProcessRegistryUpdates ( s abstract . BeaconState ) error {
2023-05-04 13:18:42 +00:00
beaconConfig := s . BeaconConfig ( )
2023-07-19 22:20:33 +00:00
currentEpoch := state . Epoch ( s )
2023-02-09 21:26:36 +00:00
// start also initializing the activation queue.
2023-02-11 22:15:30 +00:00
activationQueue := make ( [ ] uint64 , 0 )
2023-02-09 21:26:36 +00:00
// Process activation eligibility and ejections.
2023-05-10 19:37:50 +00:00
var err error
2023-05-28 15:11:18 +00:00
s . ForEachValidator ( func ( validator solid . Validator , validatorIndex , total int ) bool {
2023-07-19 22:20:33 +00:00
if state . IsValidatorEligibleForActivationQueue ( s , validator ) {
2023-05-04 13:18:42 +00:00
s . SetActivationEligibilityEpochForValidatorAtIndex ( validatorIndex , currentEpoch + 1 )
2023-02-09 21:26:36 +00:00
}
2023-05-10 19:37:50 +00:00
if validator . Active ( currentEpoch ) && validator . EffectiveBalance ( ) <= beaconConfig . EjectionBalance {
if err = s . InitiateValidatorExit ( uint64 ( validatorIndex ) ) ; err != nil {
return false
2023-02-09 21:26:36 +00:00
}
}
// Insert in the activation queue in case.
2023-07-19 22:20:33 +00:00
if state . IsValidatorEligibleForActivation ( s , validator ) {
2023-02-09 21:26:36 +00:00
activationQueue = append ( activationQueue , uint64 ( validatorIndex ) )
}
2023-05-10 19:37:50 +00:00
return true
} )
if err != nil {
return err
2023-02-09 21:26:36 +00:00
}
// order the queue accordingly.
sort . Slice ( activationQueue , func ( i , j int ) bool {
// Order by the sequence of activation_eligibility_epoch setting and then index.
2023-05-10 19:37:50 +00:00
validatori , _ := s . ValidatorForValidatorIndex ( int ( activationQueue [ i ] ) )
validatorj , _ := s . ValidatorForValidatorIndex ( int ( activationQueue [ j ] ) )
if validatori . ActivationEligibilityEpoch ( ) != validatorj . ActivationEligibilityEpoch ( ) {
return validatori . ActivationEligibilityEpoch ( ) < validatorj . ActivationEligibilityEpoch ( )
2023-02-09 21:26:36 +00:00
}
return activationQueue [ i ] < activationQueue [ j ]
} )
2023-05-04 13:18:42 +00:00
activationQueueLength := s . GetValidatorChurnLimit ( )
2023-02-11 22:15:30 +00:00
if len ( activationQueue ) > int ( activationQueueLength ) {
activationQueue = activationQueue [ : activationQueueLength ]
}
2023-02-09 21:26:36 +00:00
// Only process up to epoch limit.
2023-02-11 22:15:30 +00:00
for _ , validatorIndex := range activationQueue {
2023-05-04 13:18:42 +00:00
s . SetActivationEpochForValidatorAtIndex ( int ( validatorIndex ) , computeActivationExitEpoch ( beaconConfig , currentEpoch ) )
2023-02-09 21:26:36 +00:00
}
return nil
}