Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(BIDS-2981) fix activation estimation for eip-7514 #2828

Merged
merged 7 commits into from
Feb 5, 2024
Merged
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
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
Loading