Skip to content

Commit

Permalink
feat: pod activation analysis
Browse files Browse the repository at this point in the history
  • Loading branch information
wadealexc committed Sep 9, 2024
1 parent 4c660ce commit 9e5daaf
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 47 deletions.
7 changes: 3 additions & 4 deletions cli/commands/analyze.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,16 +40,15 @@ func AnalyzeCommand(args TAnalyzeArgs) error {
records, err := reader.ReadAll()
core.PanicOnError("error reading records: %w", err)

var pods []core.PodData
pods := make(map[string]core.PodInfo)
for _, record := range records {
pod := core.PodData{
pods[record[0]] = core.PodInfo{
PodAddress: common.HexToAddress(record[0]),
Owner: common.HexToAddress(record[1]),
}
pods = append(pods, pod)
}

analysis := core.AnalyzePods(ctx, pods, eth, beaconClient)
core.AnalyzePods(ctx, pods, eth, beaconClient)

return nil
}
92 changes: 49 additions & 43 deletions cli/core/analyze.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,16 @@ package core
import (
"context"
"fmt"
"math"
"math/big"

"github.com/Layr-Labs/eigenpod-proofs-generation/cli/core/onchain"
"github.com/ethereum/go-ethereum/common"
gethCommon "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/ethclient"
)

type PodInfo struct {
PodAddress gethCommon.Address
Owner gethCommon.Address
Validators map[string]Validator
}

type PodAnalysis struct {
Expand Down Expand Up @@ -46,62 +44,70 @@ type PodAnalysis struct {
}

func AnalyzePods(ctx context.Context, pods map[string]PodInfo, eth *ethclient.Client, beaconClient BeaconClient) PodAnalysis {
fmt.Printf("Analyzing %d pods", len(pods))
fmt.Printf("Analyzing %d pods\n", len(pods))

beaconState, err := beaconClient.GetBeaconState(ctx, "head")
PanicOnError("failed to fetch beacon state: %w", err)

allValidators, err := beaconState.Validators()
PanicOnError("failed to fetch state validators: %w", err)

for _, pod := range pods {
podValidators, err := FindAllValidatorsForEigenpod()
}
var inactiveFound bool
var problemsFound bool
podsAnalyzed := 0
validatorsAnalyzed := 0
numWithExitEpochs := 0

validators := map[string]Validator{}
var activeCheckpoint *Checkpoint = nil
for addr, _ := range pods {
podValidators, err := FindAllValidatorsForEigenpod(addr, beaconState)
PanicOnError("failed to fetch validators for pod: %w", err)

eigenPod, err := onchain.NewEigenPod(common.HexToAddress(eigenpodAddress), eth)
PanicOnError("failed to reach eigenpod", err)
podsAnalyzed++
validatorsAnalyzed += len(podValidators)

checkpoint, err := eigenPod.CurrentCheckpoint(nil)
PanicOnError("failed to fetch checkpoint information", err)
if podsAnalyzed%100 == 0 {
fmt.Printf("Analyzed %d/%d pods (%d total validators | %d total exited)...\n", podsAnalyzed, len(pods), validatorsAnalyzed, numWithExitEpochs)
}

// Fetch the beacon state associated with the checkpoint (or "head" if there is no checkpoint)
checkpointTimestamp, state, err := GetCheckpointTimestampAndBeaconState(ctx, eigenpodAddress, eth, beaconClient)
PanicOnError("failed to fetch checkpoint and beacon state", err)
var inactiveValidators []ValidatorWithIndex
for _, validator := range podValidators {
if validator.Validator.ActivationEpoch == math.MaxUint64 {
inactiveFound = true
inactiveValidators = append(inactiveValidators, validator)
}

allValidatorsForEigenpod, err := FindAllValidatorsForEigenpod(eigenpodAddress, state)
PanicOnError("failed to find validators", err)
if validator.Validator.ExitEpoch != math.MaxUint64 {
numWithExitEpochs++
}
}

allValidatorsWithInfoForEigenpod, err := FetchMultipleOnchainValidatorInfo(ctx, eth, eigenpodAddress, allValidatorsForEigenpod)
PanicOnError("failed to fetch validator info", err)
if len(inactiveValidators) == 0 {
continue
}

allBeaconBalances := getRegularBalancesGwei(state)
fmt.Printf("Found %d inactive validators in pod %s\n", len(inactiveValidators), addr)

activeValidators, err := SelectActiveValidators(eth, eigenpodAddress, allValidatorsWithInfoForEigenpod)
PanicOnError("failed to find active validators", err)
inactiveValidatorsWithInfo, err := FetchMultipleOnchainValidatorInfo(context.Background(), eth, addr, inactiveValidators)
PanicOnError("failed to fetch onchain info for pod: %w", err)

checkpointableValidators, err := SelectCheckpointableValidators(eth, eigenpodAddress, allValidatorsWithInfoForEigenpod, checkpointTimestamp)
PanicOnError("failed to find checkpointable validators", err)
var problemValidators []ValidatorWithOnchainInfo
for _, validator := range inactiveValidatorsWithInfo {
if validator.Info.Status == ValidatorStatusActive {
problemValidators = append(problemValidators, validator)
}
}

sumBeaconBalancesGwei := new(big.Float).SetUint64(uint64(sumActiveValidatorBeaconBalancesGwei(activeValidators, allBeaconBalances, state)))
if len(problemValidators) == 0 {
continue
}

sumRestakedBalancesU64, err := sumRestakedBalancesGwei(eth, eigenpodAddress, activeValidators)
PanicOnError("failed to calculate sum of onchain validator balances", err)
sumRestakedBalancesGwei := new(big.Float).SetUint64(uint64(sumRestakedBalancesU64))
fmt.Printf("Found %d problematic validators in pod %s\n", len(problemValidators), addr)
}

for _, validator := range allValidatorsWithInfoForEigenpod {
if !inactiveFound {
fmt.Printf("Didn't find any inactive validators!\n")
}

validators[fmt.Sprintf("%d", validator.Index)] = Validator{
Index: validator.Index,
Status: int(validator.Info.Status),
Slashed: validator.Validator.Slashed,
PublicKey: validator.Validator.PublicKey.String(),
IsAwaitingActivationQueue: validator.Validator.ActivationEpoch == FAR_FUTURE_EPOCH,
IsAwaitingWithdrawalCredentialProof: IsAwaitingWithdrawalCredentialProof(validator.Info, validator.Validator),
EffectiveBalance: uint64(validator.Validator.EffectiveBalance),
CurrentBalance: uint64(allBeaconBalances[validator.Index]),
}
if !problemsFound {
fmt.Printf("Didn't find any problematic validators!\n")
}

return PodAnalysis{}
}

0 comments on commit 9e5daaf

Please sign in to comment.