Skip to content

Commit 41c514b

Browse files
committed
apply processed consolidations
1 parent b810f4d commit 41c514b

File tree

3 files changed

+118
-8
lines changed

3 files changed

+118
-8
lines changed

metrics/beaconstate.go

Lines changed: 67 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"github.com/attestantio/go-eth2-client/http"
1313
"github.com/attestantio/go-eth2-client/spec"
1414
"github.com/attestantio/go-eth2-client/spec/altair"
15+
"github.com/attestantio/go-eth2-client/spec/electra"
1516
"github.com/attestantio/go-eth2-client/spec/phase0"
1617
"github.com/pkg/errors"
1718

@@ -55,7 +56,8 @@ func (p *BeaconState) Run(
5556
valKeyToIndex map[string]uint64,
5657
relayRewards *big.Int,
5758
validatorIndexToWithdrawalAmount map[uint64]*big.Int,
58-
proposerTips map[uint64]*big.Int) error {
59+
proposerTips map[uint64]*big.Int,
60+
validatorIndexToProcessedConsolidation map[uint64][]*electra.PendingConsolidation) error {
5961

6062
if currentBeaconState == nil || prevBeaconState == nil {
6163
return errors.New("current or previous beacon state is nil")
@@ -89,7 +91,8 @@ func (p *BeaconState) Run(
8991
activeValidatorIndexes,
9092
currentBeaconState,
9193
prevBeaconState,
92-
validatorIndexToWithdrawalAmount)
94+
validatorIndexToWithdrawalAmount,
95+
validatorIndexToProcessedConsolidation)
9396

9497
if err != nil {
9598
return errors.Wrap(err, "error populating participation and balance")
@@ -179,7 +182,8 @@ func (p *BeaconState) PopulateParticipationAndBalance(
179182
activeValidatorIndexes []uint64,
180183
beaconState *spec.VersionedBeaconState,
181184
prevBeaconState *spec.VersionedBeaconState,
182-
validatorIndexToWithdrawalAmount map[uint64]*big.Int) (schemas.ValidatorPerformanceMetrics, error) {
185+
validatorIndexToWithdrawalAmount map[uint64]*big.Int,
186+
validatorIndexToProcessedConsolidation map[uint64][]*electra.PendingConsolidation) (schemas.ValidatorPerformanceMetrics, error) {
183187

184188
metrics := schemas.ValidatorPerformanceMetrics{
185189
EarnedBalance: big.NewInt(0),
@@ -212,7 +216,8 @@ func (p *BeaconState) PopulateParticipationAndBalance(
212216
activeValidatorIndexes,
213217
prevBeaconState,
214218
beaconState,
215-
validatorIndexToWithdrawalAmount)
219+
validatorIndexToWithdrawalAmount,
220+
validatorIndexToProcessedConsolidation)
216221

217222
if err != nil {
218223
return schemas.ValidatorPerformanceMetrics{}, err
@@ -340,7 +345,8 @@ func (p *BeaconState) GetValidatorsWithLessBalance(
340345
activeValidatorIndexes []uint64,
341346
prevBeaconState *spec.VersionedBeaconState,
342347
currentBeaconState *spec.VersionedBeaconState,
343-
validatorIndexToWithdrawalAmount map[uint64]*big.Int) ([]uint64, *big.Int, *big.Int, error) {
348+
validatorIndexToWithdrawalAmount map[uint64]*big.Int,
349+
validatorIndexToProcessedConsolidation map[uint64][]*electra.PendingConsolidation) ([]uint64, *big.Int, *big.Int, error) {
344350

345351
prevEpoch := GetSlot(prevBeaconState) / p.networkParameters.slotsInEpoch
346352
currEpoch := GetSlot(currentBeaconState) / p.networkParameters.slotsInEpoch
@@ -367,9 +373,18 @@ func (p *BeaconState) GetValidatorsWithLessBalance(
367373

368374
prevEpochValBalance := big.NewInt(0).SetUint64(prevBalances[valIdx])
369375
currentEpochValBalance := big.NewInt(0).SetUint64(currBalances[valIdx])
376+
// Check if there is a withdrawal amount and add it to the balance
370377
if valWithdrawalAmount, ok := validatorIndexToWithdrawalAmount[valIdx]; ok {
371378
currentEpochValBalance.Add(currentEpochValBalance, valWithdrawalAmount)
372379
}
380+
// Check if there are consolidations and substract source balance
381+
if consolidations, ok := validatorIndexToProcessedConsolidation[valIdx]; ok {
382+
for _, consolidation := range consolidations {
383+
sourceBalance := big.NewInt(0).SetUint64(prevBalances[consolidation.SourceIndex])
384+
currentEpochValBalance.Sub(currentEpochValBalance, sourceBalance)
385+
}
386+
}
387+
373388
delta := big.NewInt(0).Sub(currentEpochValBalance, prevEpochValBalance)
374389

375390
if delta.Cmp(big.NewInt(0)) == -1 {
@@ -474,6 +489,41 @@ func isBitSet(input uint8, n int) bool {
474489
return (input & (1 << n)) > uint8(0)
475490
}
476491

492+
func GetProcessedConsolidations(
493+
prevBeaconState *spec.VersionedBeaconState,
494+
currentBeaconState *spec.VersionedBeaconState,
495+
) map[uint64][]*electra.PendingConsolidation {
496+
consolidations := make(map[uint64][]*electra.PendingConsolidation)
497+
498+
validators := GetValidators(currentBeaconState)
499+
prevPendingConsolidations := GetPendingConsolidations(prevBeaconState)
500+
currPendingConsolidations := GetPendingConsolidations(currentBeaconState)
501+
502+
if prevPendingConsolidations == nil {
503+
return consolidations
504+
}
505+
506+
// Set of current pending consolidations
507+
currPendingConsolidationsSet := make(map[string]bool)
508+
for _, consolidation := range currPendingConsolidations {
509+
key := fmt.Sprintf("%d-%d", consolidation.SourceIndex, consolidation.TargetIndex)
510+
currPendingConsolidationsSet[key] = true
511+
}
512+
513+
// If the consolidation is not in the current set, it was processed or source slashed
514+
for _, consolidation := range prevPendingConsolidations {
515+
key := fmt.Sprintf("%d-%d", consolidation.SourceIndex, consolidation.TargetIndex)
516+
if _, ok := currPendingConsolidationsSet[key]; !ok {
517+
sourceValidator := validators[consolidation.SourceIndex]
518+
if sourceValidator.Slashed {
519+
continue
520+
}
521+
consolidations[uint64(consolidation.TargetIndex)] = append(consolidations[uint64(consolidation.TargetIndex)], consolidation)
522+
}
523+
}
524+
return consolidations
525+
}
526+
477527
func logMetrics(
478528
metrics schemas.ValidatorPerformanceMetrics,
479529
poolName string) {
@@ -632,3 +682,15 @@ func GetCurrentSyncCommittee(beaconState *spec.VersionedBeaconState) []phase0.BL
632682
}
633683
return pubKeys
634684
}
685+
686+
func GetPendingConsolidations(beaconState *spec.VersionedBeaconState) []*electra.PendingConsolidation {
687+
var pendingConsolidations []*electra.PendingConsolidation
688+
if beaconState.Electra != nil {
689+
pendingConsolidations = beaconState.Electra.PendingConsolidations
690+
} else if beaconState.Fulu != nil {
691+
pendingConsolidations = beaconState.Fulu.PendingConsolidations
692+
} else {
693+
log.Fatal("Beacon state was empty")
694+
}
695+
return pendingConsolidations
696+
}

metrics/beaconstate_test.go

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77

88
"github.com/attestantio/go-eth2-client/spec"
99
"github.com/attestantio/go-eth2-client/spec/altair"
10+
"github.com/attestantio/go-eth2-client/spec/electra"
1011
"github.com/attestantio/go-eth2-client/spec/phase0"
1112

1213
"github.com/stretchr/testify/require"
@@ -87,7 +88,9 @@ func Test_GetValidatorsWithLessBalance(t *testing.T) {
8788
[]uint64{0, 1, 2, 3},
8889
prevBeaconState,
8990
currentBeaconState,
90-
map[uint64]*big.Int{})
91+
map[uint64]*big.Int{},
92+
map[uint64][]*electra.PendingConsolidation{},
93+
)
9194

9295
require.NoError(t, err)
9396
require.Equal(t, indexLessBalance, []uint64{0, 2})
@@ -118,7 +121,8 @@ func Test_GetValidatorsWithLessBalance_NonConsecutive(t *testing.T) {
118121
[]uint64{},
119122
prevBeaconState,
120123
currentBeaconState,
121-
map[uint64]*big.Int{})
124+
map[uint64]*big.Int{},
125+
map[uint64][]*electra.PendingConsolidation{})
122126

123127
require.Error(t, err)
124128
}
@@ -252,3 +256,35 @@ func Test_IsBitSet(t *testing.T) {
252256
is = isBitSet(5, 2)
253257
require.Equal(t, true, is)
254258
}
259+
260+
func Test_GetProcessedConsolidations(t *testing.T) {
261+
prevBeaconState := &spec.VersionedBeaconState{
262+
Electra: &electra.BeaconState{
263+
PendingConsolidations: []*electra.PendingConsolidation{
264+
{SourceIndex: 0, TargetIndex: 1},
265+
{SourceIndex: 2, TargetIndex: 1},
266+
},
267+
Validators: []*phase0.Validator{
268+
{Slashed: false},
269+
{Slashed: false},
270+
{Slashed: false},
271+
},
272+
},
273+
}
274+
currentBeaconState := &spec.VersionedBeaconState{
275+
Electra: &electra.BeaconState{
276+
PendingConsolidations: []*electra.PendingConsolidation{},
277+
Validators: []*phase0.Validator{
278+
{Slashed: false},
279+
{Slashed: false},
280+
{Slashed: true},
281+
},
282+
},
283+
}
284+
processedConsolidations := GetProcessedConsolidations(prevBeaconState, currentBeaconState)
285+
286+
require.Equal(t, len(processedConsolidations), 1)
287+
require.Equal(t, len(processedConsolidations[1]), 1)
288+
require.Equal(t, processedConsolidations[1][0].SourceIndex, phase0.ValidatorIndex(0))
289+
require.Equal(t, processedConsolidations[1][0].TargetIndex, phase0.ValidatorIndex(1))
290+
}

metrics/metrics.go

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,8 @@ func (a *Metrics) ProcessEpoch(
358358
// Map to quickly convert public keys to index
359359
valKeyToIndex := PopulateKeysToIndexesMap(currentBeaconState)
360360

361+
processedConsolidations := GetProcessedConsolidations(prevBeaconState, currentBeaconState)
362+
361363
relayRewardsPerPool, slotsWithMEVRewards, err := a.relayRewards.GetRelayRewards(currentEpoch)
362364
if err != nil {
363365
return nil, errors.Wrap(err, "error getting relay rewards")
@@ -384,7 +386,17 @@ func (a *Metrics) ProcessEpoch(
384386
if reward, ok := relayRewardsPerPool[poolName]; ok {
385387
relayRewards.Add(relayRewards, reward)
386388
}
387-
err = a.beaconState.Run(pubKeys, poolName, currentBeaconState, prevBeaconState, valKeyToIndex, relayRewards, validatorIndexToWithdrawalAmount, proposerTips)
389+
err = a.beaconState.Run(
390+
pubKeys,
391+
poolName,
392+
currentBeaconState,
393+
prevBeaconState,
394+
valKeyToIndex,
395+
relayRewards,
396+
validatorIndexToWithdrawalAmount,
397+
proposerTips,
398+
processedConsolidations,
399+
)
388400
if err != nil {
389401
return nil, errors.Wrap(err, "error running beacon state")
390402
}

0 commit comments

Comments
 (0)