Electra: Properly Calculate Proposer Probabilities for MaxEB (#14010)

* adding small change and tests for max eb spec change

* gaz

---------

Co-authored-by: Preston Van Loon <pvanloon@offchainlabs.com>
This commit is contained in:
james-prysm
2024-06-28 17:24:32 -05:00
committed by GitHub
parent 78cf75a0ed
commit 91c55c6880
2 changed files with 67 additions and 7 deletions

View File

@@ -17,6 +17,7 @@ import (
"github.com/prysmaticlabs/prysm/v5/crypto/hash"
"github.com/prysmaticlabs/prysm/v5/encoding/bytesutil"
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v5/runtime/version"
"github.com/prysmaticlabs/prysm/v5/time/slots"
log "github.com/sirupsen/logrus"
"go.opencensus.io/trace"
@@ -357,10 +358,10 @@ func BeaconProposerIndexAtSlot(ctx context.Context, state state.ReadOnlyBeaconSt
// candidate_index = indices[compute_shuffled_index(i % total, total, seed)]
// random_byte = hash(seed + uint_to_bytes(uint64(i // 32)))[i % 32]
// effective_balance = state.validators[candidate_index].effective_balance
// if effective_balance * MAX_RANDOM_BYTE >= MAX_EFFECTIVE_BALANCE * random_byte:
// if effective_balance * MAX_RANDOM_BYTE >= MAX_EFFECTIVE_BALANCE_ELECTRA * random_byte: #[Modified in Electra:EIP7251]
// return candidate_index
// i += 1
func ComputeProposerIndex(bState state.ReadOnlyValidators, activeIndices []primitives.ValidatorIndex, seed [32]byte) (primitives.ValidatorIndex, error) {
func ComputeProposerIndex(bState state.ReadOnlyBeaconState, activeIndices []primitives.ValidatorIndex, seed [32]byte) (primitives.ValidatorIndex, error) {
length := uint64(len(activeIndices))
if length == 0 {
return 0, errors.New("empty active indices list")
@@ -385,7 +386,12 @@ func ComputeProposerIndex(bState state.ReadOnlyValidators, activeIndices []primi
}
effectiveBal := v.EffectiveBalance()
if effectiveBal*maxRandomByte >= params.BeaconConfig().MaxEffectiveBalance*uint64(randomByte) {
maxEB := params.BeaconConfig().MaxEffectiveBalance
if bState.Version() >= version.Electra {
maxEB = params.BeaconConfig().MaxEffectiveBalanceElectra
}
if effectiveBal*maxRandomByte >= maxEB*uint64(randomByte) {
return candidateIndex, nil
}
}

View File

@@ -597,10 +597,11 @@ func TestComputeProposerIndex(t *testing.T) {
seed [32]byte
}
tests := []struct {
name string
args args
want primitives.ValidatorIndex
wantedErr string
name string
isElectraOrAbove bool
args args
want primitives.ValidatorIndex
wantedErr string
}{
{
name: "all_active_indices",
@@ -682,6 +683,54 @@ func TestComputeProposerIndex(t *testing.T) {
},
want: 7,
},
{
name: "electra_probability_changes",
isElectraOrAbove: true,
args: args{
validators: []*ethpb.Validator{
{EffectiveBalance: params.BeaconConfig().MaxEffectiveBalance},
{EffectiveBalance: params.BeaconConfig().MaxEffectiveBalance},
{EffectiveBalance: params.BeaconConfig().MaxEffectiveBalance},
{EffectiveBalance: params.BeaconConfig().MaxEffectiveBalanceElectra},
{EffectiveBalance: params.BeaconConfig().MaxEffectiveBalance},
},
indices: []primitives.ValidatorIndex{3},
seed: seed,
},
want: 3,
},
{
name: "electra_probability_changes_all_active",
isElectraOrAbove: true,
args: args{
validators: []*ethpb.Validator{
{EffectiveBalance: params.BeaconConfig().MaxEffectiveBalanceElectra},
{EffectiveBalance: params.BeaconConfig().MaxEffectiveBalanceElectra},
{EffectiveBalance: params.BeaconConfig().MaxEffectiveBalance}, // skip this one
{EffectiveBalance: params.BeaconConfig().MaxEffectiveBalanceElectra},
{EffectiveBalance: params.BeaconConfig().MaxEffectiveBalanceElectra},
},
indices: []primitives.ValidatorIndex{0, 1, 2, 3, 4},
seed: seed,
},
want: 4,
},
{
name: "electra_probability_returns_first_validator_with_criteria",
isElectraOrAbove: true,
args: args{
validators: []*ethpb.Validator{
{EffectiveBalance: 1},
{EffectiveBalance: params.BeaconConfig().MaxEffectiveBalanceElectra},
{EffectiveBalance: 1},
{EffectiveBalance: 1},
{EffectiveBalance: params.BeaconConfig().MaxEffectiveBalanceElectra},
},
indices: []primitives.ValidatorIndex{1},
seed: seed,
},
want: 1,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
@@ -690,6 +739,11 @@ func TestComputeProposerIndex(t *testing.T) {
bState := &ethpb.BeaconState{Validators: tt.args.validators}
stTrie, err := state_native.InitializeFromProtoUnsafePhase0(bState)
require.NoError(t, err)
if tt.isElectraOrAbove {
stTrie, err = state_native.InitializeFromProtoUnsafeElectra(&ethpb.BeaconStateElectra{Validators: tt.args.validators})
require.NoError(t, err)
}
got, err := helpers.ComputeProposerIndex(stTrie, tt.args.indices, tt.args.seed)
if tt.wantedErr != "" {
assert.ErrorContains(t, tt.wantedErr, err)