mirror of
https://gitlab.com/pulsechaincom/erigon-pulse.git
synced 2025-01-10 21:11:20 +00:00
126 lines
4.7 KiB
Go
126 lines
4.7 KiB
Go
package statechange
|
|
|
|
import (
|
|
"github.com/ledgerwatch/erigon/cl/abstract"
|
|
"github.com/ledgerwatch/erigon/cl/clparams"
|
|
"github.com/ledgerwatch/erigon/cl/cltypes"
|
|
"github.com/ledgerwatch/erigon/cl/cltypes/solid"
|
|
"github.com/ledgerwatch/erigon/cl/phase1/core/state"
|
|
)
|
|
|
|
// weighJustificationAndFinalization checks justification and finality of epochs and adds records to the state as needed.
|
|
func weighJustificationAndFinalization(s abstract.BeaconState, previousEpochTargetBalance, currentEpochTargetBalance uint64) error {
|
|
totalActiveBalance := s.GetTotalActiveBalance()
|
|
currentEpoch := state.Epoch(s)
|
|
previousEpoch := state.PreviousEpoch(s)
|
|
oldPreviousJustifiedCheckpoint := s.PreviousJustifiedCheckpoint()
|
|
oldCurrentJustifiedCheckpoint := s.CurrentJustifiedCheckpoint()
|
|
justificationBits := s.JustificationBits()
|
|
// Process justification
|
|
s.SetPreviousJustifiedCheckpoint(oldCurrentJustifiedCheckpoint)
|
|
// Discard oldest bit
|
|
copy(justificationBits[1:], justificationBits[:3])
|
|
// Turn off current justification bit
|
|
justificationBits[0] = false
|
|
// Update justified checkpoint if super majority is reached on previous epoch
|
|
if previousEpochTargetBalance*3 >= totalActiveBalance*2 {
|
|
checkPointRoot, err := state.GetBlockRoot(s, previousEpoch)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
s.SetCurrentJustifiedCheckpoint(solid.NewCheckpointFromParameters(checkPointRoot, previousEpoch))
|
|
justificationBits[1] = true
|
|
}
|
|
if currentEpochTargetBalance*3 >= totalActiveBalance*2 {
|
|
checkPointRoot, err := state.GetBlockRoot(s, currentEpoch)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
s.SetCurrentJustifiedCheckpoint(solid.NewCheckpointFromParameters(checkPointRoot, currentEpoch))
|
|
justificationBits[0] = true
|
|
}
|
|
// Process finalization
|
|
// The 2nd/3rd/4th most recent epochs are justified, the 2nd using the 4th as source
|
|
// The 2nd/3rd most recent epochs are justified, the 2nd using the 3rd as source
|
|
if (justificationBits.CheckRange(1, 4) && oldPreviousJustifiedCheckpoint.Epoch()+3 == currentEpoch) ||
|
|
(justificationBits.CheckRange(1, 3) && oldPreviousJustifiedCheckpoint.Epoch()+2 == currentEpoch) {
|
|
s.SetFinalizedCheckpoint(oldPreviousJustifiedCheckpoint)
|
|
}
|
|
// The 1st/2nd/3rd most recent epochs are justified, the 1st using the 3rd as source
|
|
// The 1st/2nd most recent epochs are justified, the 1st using the 2nd as source
|
|
if (justificationBits.CheckRange(0, 3) && oldCurrentJustifiedCheckpoint.Epoch()+2 == currentEpoch) ||
|
|
(justificationBits.CheckRange(0, 2) && oldCurrentJustifiedCheckpoint.Epoch()+1 == currentEpoch) {
|
|
s.SetFinalizedCheckpoint(oldCurrentJustifiedCheckpoint)
|
|
}
|
|
// Write justification bits
|
|
s.SetJustificationBits(justificationBits)
|
|
return nil
|
|
}
|
|
|
|
func ProcessJustificationBitsAndFinality(s abstract.BeaconState, unslashedParticipatingIndicies [][]bool) error {
|
|
currentEpoch := state.Epoch(s)
|
|
beaconConfig := s.BeaconConfig()
|
|
// Skip for first 2 epochs
|
|
if currentEpoch <= beaconConfig.GenesisEpoch+1 {
|
|
return nil
|
|
}
|
|
var previousTargetBalance, currentTargetBalance uint64
|
|
previousEpoch := state.PreviousEpoch(s)
|
|
if s.Version() == clparams.Phase0Version {
|
|
var err error
|
|
s.ForEachValidator(func(validator solid.Validator, idx, total int) bool {
|
|
if validator.Slashed() {
|
|
return true
|
|
}
|
|
isCurrentMatchingTargetAttester, err2 := s.ValidatorIsCurrentMatchingTargetAttester(idx)
|
|
if err2 != nil {
|
|
err = err2
|
|
return false
|
|
}
|
|
isPreviousMatchingTargetAttester, err2 := s.ValidatorIsPreviousMatchingTargetAttester(idx)
|
|
if err2 != nil {
|
|
err = err2
|
|
return false
|
|
}
|
|
|
|
if isCurrentMatchingTargetAttester {
|
|
currentTargetBalance += validator.EffectiveBalance()
|
|
}
|
|
if isPreviousMatchingTargetAttester {
|
|
previousTargetBalance += validator.EffectiveBalance()
|
|
}
|
|
return true
|
|
})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
} else {
|
|
// Use bitlists to determine finality.
|
|
currentParticipation, previousParticipation := s.EpochParticipation(true), s.EpochParticipation(false)
|
|
s.ForEachValidator(func(validator solid.Validator, i, total int) bool {
|
|
if validator.Slashed() {
|
|
return true
|
|
}
|
|
effectiveBalance := validator.EffectiveBalance()
|
|
if unslashedParticipatingIndicies != nil {
|
|
if unslashedParticipatingIndicies[beaconConfig.TimelyTargetFlagIndex][i] {
|
|
previousTargetBalance += effectiveBalance
|
|
}
|
|
} else if validator.Active(previousEpoch) &&
|
|
cltypes.ParticipationFlags(previousParticipation.Get(i)).HasFlag(int(beaconConfig.TimelyTargetFlagIndex)) {
|
|
previousTargetBalance += effectiveBalance
|
|
}
|
|
|
|
if validator.Active(currentEpoch) &&
|
|
cltypes.ParticipationFlags(currentParticipation.Get(i)).HasFlag(int(beaconConfig.TimelyTargetFlagIndex)) {
|
|
currentTargetBalance += effectiveBalance
|
|
}
|
|
return true
|
|
})
|
|
}
|
|
|
|
return weighJustificationAndFinalization(s, previousTargetBalance, currentTargetBalance)
|
|
}
|