Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 43 additions & 14 deletions state-transition/core/state_processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"bytes"
"fmt"
"sync"
"time"

ctypes "github.com/berachain/beacon-kit/consensus-types/types"
"github.com/berachain/beacon-kit/consensus/cometbft/service/cache"
Expand Down Expand Up @@ -279,40 +280,65 @@ func (sp *StateProcessor) processEpoch(st *state.StateDB) (transition.ValidatorU

// track validators set before updating it, to be able to
// inform consensus of the validators set changes
tStart := time.Now()
currentActiveVals, err := getActiveVals(st, currentEpoch)
if err != nil {
return nil, err
}
tActiveVals := time.Now()

// if err = sp.processRewardsAndPenalties(st); err != nil {
// return nil, err
// }
if err = sp.processRegistryUpdates(st); err != nil {
return nil, err
}
tRegistry := time.Now()

if err = sp.processEffectiveBalanceUpdates(st); err != nil {
return nil, err
}
tEffBalances := time.Now()

// if err = sp.processSlashingsReset(st); err != nil {
// return nil, err
// }
if err = sp.processRandaoMixesReset(st); err != nil {
return nil, err
}
tRandao := time.Now()

// only after we have fully updated validators, we enforce a cap on the validators set
if err = sp.processValidatorSetCap(st); err != nil {
return nil, err
}
tCap := time.Now()

// finally compute diffs in validator set to duly update consensus
nextEpoch := currentEpoch + 1
nextActiveVals, err := getActiveVals(st, nextEpoch)
if err != nil {
return nil, err
}
tNextActiveVals := time.Now()

diffs := validatorSetsDiffs(currentActiveVals, nextActiveVals)
tDiffs := time.Now()

// Per-step timings to locate epoch-boundary slowness.
sp.logger.Info("processEpoch timings",
"epoch", currentEpoch.Base10(),
"active_vals", tActiveVals.Sub(tStart).String(),
"registry_updates", tRegistry.Sub(tActiveVals).String(),
"effective_balances", tEffBalances.Sub(tRegistry).String(),
"randao_reset", tRandao.Sub(tEffBalances).String(),
"validator_set_cap", tCap.Sub(tRandao).String(),
"next_active_vals", tNextActiveVals.Sub(tCap).String(),
"set_diffs", tDiffs.Sub(tNextActiveVals).String(),
"total", tDiffs.Sub(tStart).String(),
)

return validatorSetsDiffs(currentActiveVals, nextActiveVals), nil
return diffs, nil
}

// processBlockHeader processes the header and ensures it matches the local state.
Expand Down Expand Up @@ -398,6 +424,19 @@ func (sp *StateProcessor) processEffectiveBalanceUpdates(st *state.StateDB) erro
return err
}

// Bulk-load balances. Validators and balances are index-keyed and dense, so index i and balances[i] both
// correspond to validator i, matching GetValidators order. Avoids a per-validator pubkey lookup.
balances, err := st.GetBalances()
if err != nil {
return err
}
if len(balances) != len(validators) {
return fmt.Errorf(
"effective balance update: validators/balances length mismatch (%d vs %d)",
len(validators), len(balances),
)
}

// Get the timestamp from the latest execution payload header to determine the active fork
// version for fork-gated hysteresis parameters (BRIP-0008).
//
Expand All @@ -417,21 +456,11 @@ func (sp *StateProcessor) processEffectiveBalanceUpdates(st *state.StateDB) erro
hysteresisIncrement = effectiveBalanceIncrement / sp.cs.HysteresisQuotient(timestamp)
downwardThreshold = hysteresisIncrement * sp.cs.HysteresisDownwardMultiplier()
upwardThreshold = hysteresisIncrement * sp.cs.HysteresisUpwardMultiplier(timestamp)

idx math.U64
balance math.Gwei
)

for _, val := range validators {
idx, err = st.ValidatorIndexByPubkey(val.GetPubkey())
if err != nil {
return err
}

balance, err = st.GetBalance(idx)
if err != nil {
return err
}
for i, val := range validators {
idx := math.ValidatorIndex(i)
balance := math.Gwei(balances[i])

if balance+downwardThreshold < val.GetEffectiveBalance() ||
val.GetEffectiveBalance()+upwardThreshold < balance {
Expand Down
10 changes: 2 additions & 8 deletions state-transition/core/state_processor_validators.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,14 +82,8 @@ func (sp *StateProcessor) processRegistryUpdates(st *statedb.StateDB) error {
}

if valModified {
idx, err = st.ValidatorIndexByPubkey(val.GetPubkey())
if err != nil {
return fmt.Errorf(
"registry update, failed loading validator index, state index %d: %w",
si,
err,
)
}
// vals is in registry-index order and dense, so si is the validator index.
idx = math.ValidatorIndex(si)
if err = st.UpdateValidatorAtIndex(idx, val); err != nil {
return fmt.Errorf(
"registry update, failed updating validator idx %d: %w",
Expand Down
Loading