From 2616de1eb12412ded9045ce9a3ea6d2fad9ab4d2 Mon Sep 17 00:00:00 2001 From: Nishant Das Date: Fri, 8 Mar 2024 22:49:34 +0800 Subject: [PATCH] Check Unrealized Justification Balances In Spectests (#13710) * add them * Ensure activation epoch does not overflow * add them all in * better check for overflow * fix tests * fix tests --------- Co-authored-by: Potuz --- .../getters_participation_test.go | 6 ++--- .../stateutil/unrealized_justification.go | 17 ++++++++++++- .../unrealized_justification_test.go | 24 +++++++++---------- .../justification_and_finalization.go | 5 ++++ .../altair/rewards/rewards_penalties.go | 7 ++++++ .../justification_and_finalization.go | 5 ++++ .../bellatrix/rewards/rewards_penalties.go | 7 ++++++ .../justification_and_finalization.go | 5 ++++ .../capella/rewards/rewards_penalties.go | 7 ++++++ .../justification_and_finalization.go | 6 ++++- .../shared/deneb/rewards/rewards_penalties.go | 8 +++++++ 11 files changed, 80 insertions(+), 17 deletions(-) diff --git a/beacon-chain/state/state-native/getters_participation_test.go b/beacon-chain/state/state-native/getters_participation_test.go index c30fdaa80b..b5aac094ed 100644 --- a/beacon-chain/state/state-native/getters_participation_test.go +++ b/beacon-chain/state/state-native/getters_participation_test.go @@ -35,8 +35,8 @@ func TestState_UnrealizedCheckpointBalances(t *testing.T) { active, previous, current, err := state.UnrealizedCheckpointBalances() require.NoError(t, err) require.Equal(t, allActive, active) - require.Equal(t, uint64(0), current) - require.Equal(t, uint64(0), previous) + require.Equal(t, params.BeaconConfig().EffectiveBalanceIncrement, current) + require.Equal(t, params.BeaconConfig().EffectiveBalanceIncrement, previous) // Add some votes in the last two epochs: base.CurrentEpochParticipation[0] = 0xFF @@ -58,7 +58,7 @@ func TestState_UnrealizedCheckpointBalances(t *testing.T) { active, previous, current, err = state.UnrealizedCheckpointBalances() require.NoError(t, err) require.Equal(t, allActive, active) - require.Equal(t, uint64(0), current) + require.Equal(t, params.BeaconConfig().EffectiveBalanceIncrement, current) require.Equal(t, params.BeaconConfig().MaxEffectiveBalance, previous) } diff --git a/beacon-chain/state/stateutil/unrealized_justification.go b/beacon-chain/state/stateutil/unrealized_justification.go index 81d9b8aa2e..7ca4eac6b1 100644 --- a/beacon-chain/state/stateutil/unrealized_justification.go +++ b/beacon-chain/state/stateutil/unrealized_justification.go @@ -43,7 +43,7 @@ func UnrealizedCheckpointBalances(cp, pp []byte, validators ValReader, currentEp return 0, 0, 0, err } } - activePrevious := v.ActivationEpoch+1 <= currentEpoch && currentEpoch <= v.ExitEpoch + activePrevious := v.ActivationEpoch < currentEpoch && currentEpoch <= v.ExitEpoch if activePrevious && ((pp[i]>>targetIdx)&1) == 1 { prevTarget, err = math.Add64(prevTarget, v.EffectiveBalance) if err != nil { @@ -51,5 +51,20 @@ func UnrealizedCheckpointBalances(cp, pp []byte, validators ValReader, currentEp } } } + activeBalance, prevTarget, currentTarget = ensureLowerBound(activeBalance, prevTarget, currentTarget) return activeBalance, prevTarget, currentTarget, nil } + +func ensureLowerBound(activeCurrEpoch, prevTargetAttested, currTargetAttested uint64) (uint64, uint64, uint64) { + ebi := params.BeaconConfig().EffectiveBalanceIncrement + if ebi > activeCurrEpoch { + activeCurrEpoch = ebi + } + if ebi > prevTargetAttested { + prevTargetAttested = ebi + } + if ebi > currTargetAttested { + currTargetAttested = ebi + } + return activeCurrEpoch, prevTargetAttested, currTargetAttested +} diff --git a/beacon-chain/state/stateutil/unrealized_justification_test.go b/beacon-chain/state/stateutil/unrealized_justification_test.go index f6a3500c51..e87c240ecc 100644 --- a/beacon-chain/state/stateutil/unrealized_justification_test.go +++ b/beacon-chain/state/stateutil/unrealized_justification_test.go @@ -29,8 +29,8 @@ func TestState_UnrealizedCheckpointBalances(t *testing.T) { active, previous, current, err := UnrealizedCheckpointBalances(cp, pp, NewValSliceReader(validators), 0) require.NoError(tt, err) require.Equal(tt, expectedActive, active) - require.Equal(tt, uint64(0), current) - require.Equal(tt, uint64(0), previous) + require.Equal(tt, params.BeaconConfig().EffectiveBalanceIncrement, current) + require.Equal(tt, params.BeaconConfig().EffectiveBalanceIncrement, previous) }) t.Run("bad votes in last two epochs", func(tt *testing.T) { @@ -39,8 +39,8 @@ func TestState_UnrealizedCheckpointBalances(t *testing.T) { active, previous, current, err := UnrealizedCheckpointBalances(cp, pp, NewValSliceReader(validators), 1) require.NoError(tt, err) require.Equal(tt, expectedActive, active) - require.Equal(tt, uint64(0), current) - require.Equal(tt, uint64(0), previous) + require.Equal(tt, params.BeaconConfig().EffectiveBalanceIncrement, current) + require.Equal(tt, params.BeaconConfig().EffectiveBalanceIncrement, previous) }) t.Run("two votes in last epoch", func(tt *testing.T) { @@ -50,7 +50,7 @@ func TestState_UnrealizedCheckpointBalances(t *testing.T) { require.NoError(tt, err) require.Equal(tt, expectedActive, active) require.Equal(tt, 2*params.BeaconConfig().MaxEffectiveBalance, current) - require.Equal(tt, uint64(0), previous) + require.Equal(tt, params.BeaconConfig().EffectiveBalanceIncrement, previous) }) t.Run("two votes in previous epoch", func(tt *testing.T) { @@ -59,7 +59,7 @@ func TestState_UnrealizedCheckpointBalances(t *testing.T) { active, previous, current, err := UnrealizedCheckpointBalances(cp, pp, NewValSliceReader(validators), 1) require.NoError(tt, err) require.Equal(tt, expectedActive, active) - require.Equal(tt, uint64(0), current) + require.Equal(tt, params.BeaconConfig().EffectiveBalanceIncrement, current) require.Equal(tt, 2*params.BeaconConfig().MaxEffectiveBalance, previous) }) @@ -118,8 +118,8 @@ func TestState_MVSlice_UnrealizedCheckpointBalances(t *testing.T) { active, previous, current, err := UnrealizedCheckpointBalances(cp, pp, NewValMultiValueSliceReader(mv, &testObject{id: 0}), 0) require.NoError(tt, err) require.Equal(tt, expectedActive, active) - require.Equal(tt, uint64(0), current) - require.Equal(tt, uint64(0), previous) + require.Equal(tt, params.BeaconConfig().EffectiveBalanceIncrement, current) + require.Equal(tt, params.BeaconConfig().EffectiveBalanceIncrement, previous) }) t.Run("bad votes in last two epochs", func(tt *testing.T) { @@ -128,8 +128,8 @@ func TestState_MVSlice_UnrealizedCheckpointBalances(t *testing.T) { active, previous, current, err := UnrealizedCheckpointBalances(cp, pp, NewValMultiValueSliceReader(mv, &testObject{id: 0}), 1) require.NoError(tt, err) require.Equal(tt, expectedActive, active) - require.Equal(tt, uint64(0), current) - require.Equal(tt, uint64(0), previous) + require.Equal(tt, params.BeaconConfig().EffectiveBalanceIncrement, current) + require.Equal(tt, params.BeaconConfig().EffectiveBalanceIncrement, previous) }) t.Run("two votes in last epoch", func(tt *testing.T) { @@ -139,7 +139,7 @@ func TestState_MVSlice_UnrealizedCheckpointBalances(t *testing.T) { require.NoError(tt, err) require.Equal(tt, expectedActive, active) require.Equal(tt, 2*params.BeaconConfig().MaxEffectiveBalance, current) - require.Equal(tt, uint64(0), previous) + require.Equal(tt, params.BeaconConfig().EffectiveBalanceIncrement, previous) }) t.Run("two votes in previous epoch", func(tt *testing.T) { @@ -148,7 +148,7 @@ func TestState_MVSlice_UnrealizedCheckpointBalances(t *testing.T) { active, previous, current, err := UnrealizedCheckpointBalances(cp, pp, NewValMultiValueSliceReader(mv, &testObject{id: 0}), 1) require.NoError(tt, err) require.Equal(tt, expectedActive, active) - require.Equal(tt, uint64(0), current) + require.Equal(tt, params.BeaconConfig().EffectiveBalanceIncrement, current) require.Equal(tt, 2*params.BeaconConfig().MaxEffectiveBalance, previous) }) diff --git a/testing/spectest/shared/altair/epoch_processing/justification_and_finalization.go b/testing/spectest/shared/altair/epoch_processing/justification_and_finalization.go index 2b7ad59efa..75e4859b16 100644 --- a/testing/spectest/shared/altair/epoch_processing/justification_and_finalization.go +++ b/testing/spectest/shared/altair/epoch_processing/justification_and_finalization.go @@ -35,6 +35,11 @@ func processJustificationAndFinalizationPrecomputeWrapper(t *testing.T, st state require.NoError(t, err) _, bp, err = altair.ProcessEpochParticipation(ctx, st, bp, vp) require.NoError(t, err) + activeBal, targetPrevious, targetCurrent, err := st.UnrealizedCheckpointBalances() + require.NoError(t, err) + require.Equal(t, bp.ActiveCurrentEpoch, activeBal) + require.Equal(t, bp.CurrentEpochTargetAttested, targetCurrent) + require.Equal(t, bp.PrevEpochTargetAttested, targetPrevious) st, err = precompute.ProcessJustificationAndFinalizationPreCompute(st, bp) require.NoError(t, err, "Could not process justification") diff --git a/testing/spectest/shared/altair/rewards/rewards_penalties.go b/testing/spectest/shared/altair/rewards/rewards_penalties.go index ec4a7fca62..3162f5f086 100644 --- a/testing/spectest/shared/altair/rewards/rewards_penalties.go +++ b/testing/spectest/shared/altair/rewards/rewards_penalties.go @@ -76,6 +76,13 @@ func runPrecomputeRewardsAndPenaltiesTest(t *testing.T, testFolderPath string) { require.NoError(t, err) vp, bp, err = altair.ProcessEpochParticipation(ctx, preBeaconState, bp, vp) require.NoError(t, err) + + activeBal, targetPrevious, targetCurrent, err := preBeaconState.UnrealizedCheckpointBalances() + require.NoError(t, err) + require.Equal(t, bp.ActiveCurrentEpoch, activeBal) + require.Equal(t, bp.CurrentEpochTargetAttested, targetCurrent) + require.Equal(t, bp.PrevEpochTargetAttested, targetPrevious) + deltas, err := altair.AttestationsDelta(preBeaconState, bp, vp) require.NoError(t, err) diff --git a/testing/spectest/shared/bellatrix/epoch_processing/justification_and_finalization.go b/testing/spectest/shared/bellatrix/epoch_processing/justification_and_finalization.go index 8ec021a386..36f8d6c032 100644 --- a/testing/spectest/shared/bellatrix/epoch_processing/justification_and_finalization.go +++ b/testing/spectest/shared/bellatrix/epoch_processing/justification_and_finalization.go @@ -35,6 +35,11 @@ func processJustificationAndFinalizationPrecomputeWrapper(t *testing.T, st state require.NoError(t, err) _, bp, err = altair.ProcessEpochParticipation(ctx, st, bp, vp) require.NoError(t, err) + activeBal, targetPrevious, targetCurrent, err := st.UnrealizedCheckpointBalances() + require.NoError(t, err) + require.Equal(t, bp.ActiveCurrentEpoch, activeBal) + require.Equal(t, bp.CurrentEpochTargetAttested, targetCurrent) + require.Equal(t, bp.PrevEpochTargetAttested, targetPrevious) st, err = precompute.ProcessJustificationAndFinalizationPreCompute(st, bp) require.NoError(t, err, "Could not process justification") diff --git a/testing/spectest/shared/bellatrix/rewards/rewards_penalties.go b/testing/spectest/shared/bellatrix/rewards/rewards_penalties.go index 3ae1f613eb..624d73b3f2 100644 --- a/testing/spectest/shared/bellatrix/rewards/rewards_penalties.go +++ b/testing/spectest/shared/bellatrix/rewards/rewards_penalties.go @@ -80,6 +80,13 @@ func runPrecomputeRewardsAndPenaltiesTest(t *testing.T, testFolderPath string) { require.NoError(t, err) vp, bp, err = altair.ProcessEpochParticipation(ctx, preBeaconState, bp, vp) require.NoError(t, err) + + activeBal, targetPrevious, targetCurrent, err := preBeaconState.UnrealizedCheckpointBalances() + require.NoError(t, err) + require.Equal(t, bp.ActiveCurrentEpoch, activeBal) + require.Equal(t, bp.CurrentEpochTargetAttested, targetCurrent) + require.Equal(t, bp.PrevEpochTargetAttested, targetPrevious) + deltas, err := altair.AttestationsDelta(preBeaconState, bp, vp) require.NoError(t, err) diff --git a/testing/spectest/shared/capella/epoch_processing/justification_and_finalization.go b/testing/spectest/shared/capella/epoch_processing/justification_and_finalization.go index bbb5e5b78d..b818d5f34e 100644 --- a/testing/spectest/shared/capella/epoch_processing/justification_and_finalization.go +++ b/testing/spectest/shared/capella/epoch_processing/justification_and_finalization.go @@ -35,6 +35,11 @@ func processJustificationAndFinalizationPrecomputeWrapper(t *testing.T, st state require.NoError(t, err) _, bp, err = altair.ProcessEpochParticipation(ctx, st, bp, vp) require.NoError(t, err) + activeBal, targetPrevious, targetCurrent, err := st.UnrealizedCheckpointBalances() + require.NoError(t, err) + require.Equal(t, bp.ActiveCurrentEpoch, activeBal) + require.Equal(t, bp.CurrentEpochTargetAttested, targetCurrent) + require.Equal(t, bp.PrevEpochTargetAttested, targetPrevious) st, err = precompute.ProcessJustificationAndFinalizationPreCompute(st, bp) require.NoError(t, err, "Could not process justification") diff --git a/testing/spectest/shared/capella/rewards/rewards_penalties.go b/testing/spectest/shared/capella/rewards/rewards_penalties.go index cdb60a4710..1651cd6463 100644 --- a/testing/spectest/shared/capella/rewards/rewards_penalties.go +++ b/testing/spectest/shared/capella/rewards/rewards_penalties.go @@ -80,6 +80,13 @@ func runPrecomputeRewardsAndPenaltiesTest(t *testing.T, testFolderPath string) { require.NoError(t, err) vp, bp, err = altair.ProcessEpochParticipation(ctx, preBeaconState, bp, vp) require.NoError(t, err) + + activeBal, targetPrevious, targetCurrent, err := preBeaconState.UnrealizedCheckpointBalances() + require.NoError(t, err) + require.Equal(t, bp.ActiveCurrentEpoch, activeBal) + require.Equal(t, bp.CurrentEpochTargetAttested, targetCurrent) + require.Equal(t, bp.PrevEpochTargetAttested, targetPrevious) + deltas, err := altair.AttestationsDelta(preBeaconState, bp, vp) require.NoError(t, err) diff --git a/testing/spectest/shared/deneb/epoch_processing/justification_and_finalization.go b/testing/spectest/shared/deneb/epoch_processing/justification_and_finalization.go index b6f9bb2434..574feddc5d 100644 --- a/testing/spectest/shared/deneb/epoch_processing/justification_and_finalization.go +++ b/testing/spectest/shared/deneb/epoch_processing/justification_and_finalization.go @@ -32,7 +32,11 @@ func processJustificationAndFinalizationPrecomputeWrapper(t *testing.T, st state require.NoError(t, err) _, bp, err = altair.ProcessEpochParticipation(ctx, st, bp, vp) require.NoError(t, err) - + activeBal, targetPrevious, targetCurrent, err := st.UnrealizedCheckpointBalances() + require.NoError(t, err) + require.Equal(t, bp.ActiveCurrentEpoch, activeBal) + require.Equal(t, bp.CurrentEpochTargetAttested, targetCurrent) + require.Equal(t, bp.PrevEpochTargetAttested, targetPrevious) st, err = precompute.ProcessJustificationAndFinalizationPreCompute(st, bp) require.NoError(t, err, "Could not process justification") diff --git a/testing/spectest/shared/deneb/rewards/rewards_penalties.go b/testing/spectest/shared/deneb/rewards/rewards_penalties.go index abc8369dd0..41bda166ce 100644 --- a/testing/spectest/shared/deneb/rewards/rewards_penalties.go +++ b/testing/spectest/shared/deneb/rewards/rewards_penalties.go @@ -70,8 +70,16 @@ func runPrecomputeRewardsAndPenaltiesTest(t *testing.T, testFolderPath string) { vp, bp, err := altair.InitializePrecomputeValidators(ctx, preBeaconState) require.NoError(t, err) + vp, bp, err = altair.ProcessEpochParticipation(ctx, preBeaconState, bp, vp) require.NoError(t, err) + + activeBal, targetPrevious, targetCurrent, err := preBeaconState.UnrealizedCheckpointBalances() + require.NoError(t, err) + require.Equal(t, bp.ActiveCurrentEpoch, activeBal) + require.Equal(t, bp.CurrentEpochTargetAttested, targetCurrent) + require.Equal(t, bp.PrevEpochTargetAttested, targetPrevious) + deltas, err := altair.AttestationsDelta(preBeaconState, bp, vp) require.NoError(t, err)