Skip to content

Commit

Permalink
Merge pull request #2828 from gobitfly/BIDS-2981/fix-activation-estim…
Browse files Browse the repository at this point in the history
…ation

(BIDS-2981) fix activation estimation for eip-7514
  • Loading branch information
guybrush authored Feb 5, 2024
2 parents 5d22576 + 1e7a987 commit a0ad636
Show file tree
Hide file tree
Showing 8 changed files with 48 additions and 6 deletions.
9 changes: 7 additions & 2 deletions handlers/dashboard.go
Original file line number Diff line number Diff line change
Expand Up @@ -776,7 +776,12 @@ func DashboardDataValidators(w http.ResponseWriter, r *http.Request) {
latestEpoch := services.LatestEpoch()

stats := services.GetLatestStats()
churnRate := stats.ValidatorChurnLimit
activationChurnRate := stats.ValidatorActivationChurnLimit
if activationChurnRate == nil {
utils.LogError(fmt.Errorf("activation churn rate not available"), "error retrieving validator activation churn rate", 0, errFieldMap)
http.Error(w, "Internal server error", http.StatusInternalServerError)
return
}

if len(validatorIndexArr) > 0 {
balances, err := db.BigtableClient.GetValidatorBalanceHistory(validatorIndexArr, latestEpoch, latestEpoch)
Expand Down Expand Up @@ -842,7 +847,7 @@ func DashboardDataValidators(w http.ResponseWriter, r *http.Request) {
http.Error(w, "Internal server error", http.StatusInternalServerError)
return
}
epochsToWait := queueAhead / *churnRate
epochsToWait := queueAhead / *activationChurnRate
// calculate dequeue epoch
estimatedActivationEpoch := latestEpoch + epochsToWait + 1
// add activation offset
Expand Down
14 changes: 12 additions & 2 deletions handlers/validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,10 +99,20 @@ func Validator(w http.ResponseWriter, r *http.Request) {

if *churnRate == 0 {
*churnRate = 4
logger.Warning("Churn rate not set in config using 4 as default please set minPerEpochChurnLimit")
logger.Warning("Churn rate not set in config using 4 as default")
}
validatorPageData.ChurnRate = *churnRate

activationChurnRate := stats.ValidatorActivationChurnLimit
if activationChurnRate == nil {
activationChurnRate = new(uint64)
}

if *activationChurnRate == 0 {
*activationChurnRate = 4
logger.Warning("Activation Churn rate not set in config using 4 as default")
}

pendingCount := stats.PendingValidatorCount
if pendingCount == nil {
pendingCount = new(uint64)
Expand Down Expand Up @@ -558,7 +568,7 @@ func Validator(w http.ResponseWriter, r *http.Request) {
return fmt.Errorf("failed to retrieve queue ahead of validator %v: %w", validatorPageData.ValidatorIndex, err)
}
validatorPageData.QueuePosition = queueAhead + 1
epochsToWait := queueAhead / *churnRate
epochsToWait := queueAhead / *activationChurnRate
// calculate dequeue epoch
estimatedActivationEpoch := validatorPageData.Epoch + epochsToWait + 1
// add activation offset
Expand Down
1 change: 1 addition & 0 deletions services/services.go
Original file line number Diff line number Diff line change
Expand Up @@ -1229,6 +1229,7 @@ func GetLatestStats() *types.Stats {
ActiveValidatorCount: new(uint64),
PendingValidatorCount: new(uint64),
ValidatorChurnLimit: new(uint64),
ValidatorActivationChurnLimit: new(uint64),
LatestValidatorWithdrawalIndex: new(uint64),
}
}
Expand Down
26 changes: 24 additions & 2 deletions services/stats.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,14 +88,21 @@ func calculateStats() (*types.Stats, error) {

stats.ValidatorChurnLimit = &validatorChurnLimit

epoch := LatestEpoch()
validatorActivationChurnLimit, err := getValidatorActivationChurnLimit(activeValidatorCount, epoch)
if err != nil {
logger.WithError(err).Error("error getting total validator churn limit")
}

stats.ValidatorActivationChurnLimit = &validatorActivationChurnLimit

LatestValidatorWithdrawalIndex, err := db.GetMostRecentWithdrawalValidator()
if err != nil {
logger.WithError(err).Error("error getting most recent withdrawal validator index")
}

stats.LatestValidatorWithdrawalIndex = &LatestValidatorWithdrawalIndex

epoch := LatestEpoch()
WithdrawableValidatorCount, err := db.GetWithdrawableValidatorCount(epoch)
if err != nil {
logger.WithError(err).Error("error getting withdrawable validator count")
Expand Down Expand Up @@ -198,7 +205,22 @@ func eth1UniqueValidatorsCount() (*uint64, error) {
return &count, nil
}

// GetValidatorChurnLimit returns the rate at which validators can enter or leave the system
// getValidatorActivationChurnLimit returns the rate at which validators can enter the system, see https://eips.ethereum.org/EIPS/eip-7514
func getValidatorActivationChurnLimit(validatorCount, epoch uint64) (uint64, error) {
vcl, err := getValidatorChurnLimit(validatorCount)
if err != nil {
return 0, err
}
if utils.Config.Chain.ClConfig.DenebForkEpoch > epoch {
return vcl, nil
}
if vcl > utils.Config.Chain.ClConfig.MaxPerEpochActivationChurnLimit {
return utils.Config.Chain.ClConfig.MaxPerEpochActivationChurnLimit, nil
}
return vcl, nil
}

// getValidatorChurnLimit returns the rate at which validators can leave the system
func getValidatorChurnLimit(validatorCount uint64) (uint64, error) {
min := utils.Config.Chain.ClConfig.MinPerEpochChurnLimit

Expand Down
1 change: 1 addition & 0 deletions types/chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ type ClChainConfig struct {
EjectionBalance uint64 `yaml:"EJECTION_BALANCE"`
MinPerEpochChurnLimit uint64 `yaml:"MIN_PER_EPOCH_CHURN_LIMIT"`
ChurnLimitQuotient uint64 `yaml:"CHURN_LIMIT_QUOTIENT"`
MaxPerEpochActivationChurnLimit uint64 `yaml:"MAX_PER_EPOCH_ACTIVATION_CHURN_LIMIT"`
// fork choice
ProposerScoreBoost uint64 `yaml:"PROPOSER_SCORE_BOOST"`
// deposit contract
Expand Down
1 change: 1 addition & 0 deletions types/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,7 @@ type ConfigJsonResponse struct {
EjectionBalance string `json:"EJECTION_BALANCE"`
MinPerEpochChurnLimit string `json:"MIN_PER_EPOCH_CHURN_LIMIT"`
ChurnLimitQuotient string `json:"CHURN_LIMIT_QUOTIENT"`
MaxPerEpochActivationChurnLimit string `json:"MAX_PER_EPOCH_ACTIVATION_CHURN_LIMIT"`
ProposerScoreBoost string `json:"PROPOSER_SCORE_BOOST"`
DepositChainID string `json:"DEPOSIT_CHAIN_ID"`
DepositNetworkID string `json:"DEPOSIT_NETWORK_ID"`
Expand Down
1 change: 1 addition & 0 deletions types/templates.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ type Stats struct {
ActiveValidatorCount *uint64 `db:"count"`
PendingValidatorCount *uint64 `db:"count"`
ValidatorChurnLimit *uint64
ValidatorActivationChurnLimit *uint64
LatestValidatorWithdrawalIndex *uint64 `db:"index"`
WithdrawableValidatorCount *uint64 `db:"count"`
// WithdrawableAmount *uint64 `db:"amount"`
Expand Down
1 change: 1 addition & 0 deletions utils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -502,6 +502,7 @@ func ReadConfig(cfg *types.Config, path string) error {
EjectionBalance: mustParseUint(jr.Data.EjectionBalance),
MinPerEpochChurnLimit: mustParseUint(jr.Data.MinPerEpochChurnLimit),
ChurnLimitQuotient: mustParseUint(jr.Data.ChurnLimitQuotient),
MaxPerEpochActivationChurnLimit: mustParseUint(jr.Data.MaxPerEpochActivationChurnLimit),
ProposerScoreBoost: mustParseUint(jr.Data.ProposerScoreBoost),
DepositChainID: mustParseUint(jr.Data.DepositChainID),
DepositNetworkID: mustParseUint(jr.Data.DepositNetworkID),
Expand Down

0 comments on commit a0ad636

Please sign in to comment.