Skip to content

Commit

Permalink
Electra: updated compute_proposer_index
Browse files Browse the repository at this point in the history
  • Loading branch information
prestonvanloon committed Jun 28, 2024
1 parent 78cf75a commit 125935b
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 14 deletions.
1 change: 1 addition & 0 deletions beacon-chain/core/helpers/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ go_test(
"//crypto/hash:go_default_library",
"//encoding/bytesutil:go_default_library",
"//proto/prysm/v1alpha1:go_default_library",
"//runtime/version:go_default_library",
"//testing/assert:go_default_library",
"//testing/require:go_default_library",
"//testing/util:go_default_library",
Expand Down
13 changes: 10 additions & 3 deletions beacon-chain/core/helpers/validators.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -357,10 +358,11 @@ 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:
// # [Modified in Electra:EIP7251]
// if effective_balance * MAX_RANDOM_BYTE >= MAX_EFFECTIVE_BALANCE_ELECTRA * random_byte:
// 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")
Expand All @@ -385,7 +387,12 @@ func ComputeProposerIndex(bState state.ReadOnlyValidators, activeIndices []primi
}
effectiveBal := v.EffectiveBalance()

if effectiveBal*maxRandomByte >= params.BeaconConfig().MaxEffectiveBalance*uint64(randomByte) {
maxEB := params.BeaconConfig().MaxEffectiveBalanceElectra
if bState.Version() < version.Electra {
maxEB = params.BeaconConfig().MaxEffectiveBalance
}

if effectiveBal*maxRandomByte >= maxEB*uint64(randomByte) {
return candidateIndex, nil
}
}
Expand Down
84 changes: 73 additions & 11 deletions beacon-chain/core/helpers/validators_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,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/testing/assert"
"github.com/prysmaticlabs/prysm/v5/testing/require"
)
Expand Down Expand Up @@ -595,6 +596,7 @@ func TestComputeProposerIndex(t *testing.T) {
validators []*ethpb.Validator
indices []primitives.ValidatorIndex
seed [32]byte
minVersion int
}
tests := []struct {
name string
Expand Down Expand Up @@ -682,21 +684,81 @@ func TestComputeProposerIndex(t *testing.T) {
},
want: 7,
},
{
name: "all_active_indices_above_min_activation_balance",
args: args{
validators: []*ethpb.Validator{
{EffectiveBalance: params.BeaconConfig().MaxEffectiveBalanceElectra},
{EffectiveBalance: params.BeaconConfig().MaxEffectiveBalanceElectra},
{EffectiveBalance: params.BeaconConfig().MaxEffectiveBalanceElectra},
{EffectiveBalance: params.BeaconConfig().MaxEffectiveBalanceElectra},
{EffectiveBalance: params.BeaconConfig().MaxEffectiveBalanceElectra},
},
indices: []primitives.ValidatorIndex{0, 1, 2, 3, 4},
seed: seed,
minVersion: version.Electra,
},
want: 2,
},
{
name: "second_half_active_above_min_activation_balance",
args: args{
validators: []*ethpb.Validator{
{EffectiveBalance: params.BeaconConfig().MaxEffectiveBalanceElectra},
{EffectiveBalance: params.BeaconConfig().MaxEffectiveBalanceElectra},
{EffectiveBalance: params.BeaconConfig().MaxEffectiveBalanceElectra},
{EffectiveBalance: params.BeaconConfig().MaxEffectiveBalanceElectra},
{EffectiveBalance: params.BeaconConfig().MaxEffectiveBalanceElectra},
{EffectiveBalance: params.BeaconConfig().MaxEffectiveBalanceElectra},
{EffectiveBalance: params.BeaconConfig().MaxEffectiveBalanceElectra},
{EffectiveBalance: params.BeaconConfig().MaxEffectiveBalanceElectra},
{EffectiveBalance: params.BeaconConfig().MaxEffectiveBalanceElectra},
{EffectiveBalance: params.BeaconConfig().MaxEffectiveBalanceElectra},
},
indices: []primitives.ValidatorIndex{5, 6, 7, 8, 9},
seed: seed,
minVersion: version.Electra,
},
want: 7,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
helpers.ClearCache()
t.Run("phase0", func(t *testing.T) {
if tt.args.minVersion > version.Phase0 {
t.Skip("scenario does not apply to phase0")
}
helpers.ClearCache()
bState := &ethpb.BeaconState{Validators: tt.args.validators}
stTrie, err := state_native.InitializeFromProtoUnsafePhase0(bState)
require.NoError(t, err)
got, err := helpers.ComputeProposerIndex(stTrie, tt.args.indices, tt.args.seed)
if tt.wantedErr != "" {
assert.ErrorContains(t, tt.wantedErr, err)
return
}
assert.NoError(t, err, "received unexpected error")
assert.Equal(t, tt.want, got, "ComputeProposerIndex()")
})
t.Run("electra", func(t *testing.T) {
if tt.args.minVersion > version.Electra {
t.Skip("scenario does not apply to electra")
}
helpers.ClearCache()
bState := &ethpb.BeaconStateElectra{Validators: tt.args.validators}
stTrie, err := state_native.InitializeFromProtoUnsafeElectra(bState)
require.NoError(t, err)

bState := &ethpb.BeaconState{Validators: tt.args.validators}
stTrie, err := state_native.InitializeFromProtoUnsafePhase0(bState)
require.NoError(t, err)
got, err := helpers.ComputeProposerIndex(stTrie, tt.args.indices, tt.args.seed)
if tt.wantedErr != "" {
assert.ErrorContains(t, tt.wantedErr, err)
return
}
assert.NoError(t, err, "received unexpected error")
assert.Equal(t, tt.want, got, "ComputeProposerIndex()")
require.Equal(t, stTrie.Version(), version.Electra)

got, err := helpers.ComputeProposerIndex(stTrie, tt.args.indices, tt.args.seed)
if tt.wantedErr != "" {
assert.ErrorContains(t, tt.wantedErr, err)
return
}
assert.NoError(t, err, "received unexpected error")
assert.Equal(t, tt.want, got, "ComputeProposerIndex()")
})
})
}
}
Expand Down

0 comments on commit 125935b

Please sign in to comment.