Move ComputeProposerIndexWithValidators to test (#7460)

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
This commit is contained in:
terence tsao 2020-10-08 02:24:17 -07:00 committed by GitHub
parent d4e6ce6998
commit 703907bd99
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 36 additions and 61 deletions

View File

@ -216,10 +216,6 @@ func BeaconProposerIndex(state *stateTrie.BeaconState) (uint64, error) {
// ComputeProposerIndex returns the index sampled by effective balance, which is used to calculate proposer. // ComputeProposerIndex returns the index sampled by effective balance, which is used to calculate proposer.
// //
// This method is more efficient than ComputeProposerIndexWithValidators as it uses the read only validator
// abstraction to retrieve validator related data. Whereas the other method requires a whole copy of the validator
// set.
//
// Spec pseudocode definition: // Spec pseudocode definition:
// def compute_proposer_index(state: BeaconState, indices: Sequence[ValidatorIndex], seed: Hash) -> ValidatorIndex: // def compute_proposer_index(state: BeaconState, indices: Sequence[ValidatorIndex], seed: Hash) -> ValidatorIndex:
// """ // """
@ -266,57 +262,6 @@ func ComputeProposerIndex(bState *stateTrie.BeaconState, activeIndices []uint64,
} }
} }
// ComputeProposerIndexWithValidators returns the index sampled by effective balance, which is used to calculate proposer.
//
// Note: This method signature deviates slightly from the spec recommended definition. The full
// state object is not required to compute the proposer index.
//
// Spec pseudocode definition:
// def compute_proposer_index(state: BeaconState, indices: Sequence[ValidatorIndex], seed: Hash) -> ValidatorIndex:
// """
// Return from ``indices`` a random index sampled by effective balance.
// """
// assert len(indices) > 0
// MAX_RANDOM_BYTE = 2**8 - 1
// i = 0
// while True:
// candidate_index = indices[compute_shuffled_index(ValidatorIndex(i % len(indices)), len(indices), seed)]
// random_byte = hash(seed + int_to_bytes(i // 32, length=8))[i % 32]
// effective_balance = state.validators[candidate_index].effective_balance
// if effective_balance * MAX_RANDOM_BYTE >= MAX_EFFECTIVE_BALANCE * random_byte:
// return ValidatorIndex(candidate_index)
// i += 1
// Deprecated: Prefer using the beacon state with ComputeProposerIndex to avoid an unnecessary copy of the validator set.
func ComputeProposerIndexWithValidators(validators []*ethpb.Validator, activeIndices []uint64, seed [32]byte) (uint64, error) {
length := uint64(len(activeIndices))
if length == 0 {
return 0, errors.New("empty active indices list")
}
maxRandomByte := uint64(1<<8 - 1)
hashFunc := hashutil.CustomSHA256Hasher()
for i := uint64(0); ; i++ {
candidateIndex, err := ComputeShuffledIndex(i%length, length, seed, true /* shuffle */)
if err != nil {
return 0, err
}
candidateIndex = activeIndices[candidateIndex]
if candidateIndex >= uint64(len(validators)) {
return 0, errors.New("active index out of range")
}
b := append(seed[:], bytesutil.Bytes8(i/32)...)
randomByte := hashFunc(b)[i%32]
v := validators[candidateIndex]
var effectiveBal uint64
if v != nil {
effectiveBal = v.EffectiveBalance
}
if effectiveBal*maxRandomByte >= params.BeaconConfig().MaxEffectiveBalance*uint64(randomByte) {
return candidateIndex, nil
}
}
}
// Domain returns the domain version for BLS private key to sign and verify. // Domain returns the domain version for BLS private key to sign and verify.
// //
// Spec pseudocode definition: // Spec pseudocode definition:

View File

@ -1,18 +1,18 @@
package helpers package helpers
import ( import (
"errors"
"testing" "testing"
"github.com/prysmaticlabs/prysm/beacon-chain/cache"
"github.com/prysmaticlabs/prysm/shared/hashutil"
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
"github.com/prysmaticlabs/prysm/shared/testutil/require"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1" ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/beacon-chain/cache"
beaconstate "github.com/prysmaticlabs/prysm/beacon-chain/state" beaconstate "github.com/prysmaticlabs/prysm/beacon-chain/state"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1" pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/bytesutil" "github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/hashutil"
"github.com/prysmaticlabs/prysm/shared/params" "github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
"github.com/prysmaticlabs/prysm/shared/testutil/require"
) )
func TestIsActiveValidator_OK(t *testing.T) { func TestIsActiveValidator_OK(t *testing.T) {
@ -309,7 +309,7 @@ func TestComputeProposerIndex_Compatibility(t *testing.T) {
for i := uint64(0); i < params.BeaconConfig().SlotsPerEpoch; i++ { for i := uint64(0); i < params.BeaconConfig().SlotsPerEpoch; i++ {
seedWithSlot := append(seed[:], bytesutil.Bytes8(i)...) seedWithSlot := append(seed[:], bytesutil.Bytes8(i)...)
seedWithSlotHash := hashutil.Hash(seedWithSlot) seedWithSlotHash := hashutil.Hash(seedWithSlot)
index, err := ComputeProposerIndexWithValidators(state.Validators(), indices, seedWithSlotHash) index, err := computeProposerIndexWithValidators(state.Validators(), indices, seedWithSlotHash)
require.NoError(t, err) require.NoError(t, err)
wantedProposerIndices = append(wantedProposerIndices, index) wantedProposerIndices = append(wantedProposerIndices, index)
} }
@ -743,3 +743,33 @@ func TestIsIsEligibleForActivation(t *testing.T) {
}) })
} }
} }
func computeProposerIndexWithValidators(validators []*ethpb.Validator, activeIndices []uint64, seed [32]byte) (uint64, error) {
length := uint64(len(activeIndices))
if length == 0 {
return 0, errors.New("empty active indices list")
}
maxRandomByte := uint64(1<<8 - 1)
hashFunc := hashutil.CustomSHA256Hasher()
for i := uint64(0); ; i++ {
candidateIndex, err := ComputeShuffledIndex(i%length, length, seed, true /* shuffle */)
if err != nil {
return 0, err
}
candidateIndex = activeIndices[candidateIndex]
if candidateIndex >= uint64(len(validators)) {
return 0, errors.New("active index out of range")
}
b := append(seed[:], bytesutil.Bytes8(i/32)...)
randomByte := hashFunc(b)[i%32]
v := validators[candidateIndex]
var effectiveBal uint64
if v != nil {
effectiveBal = v.EffectiveBalance
}
if effectiveBal*maxRandomByte >= params.BeaconConfig().MaxEffectiveBalance*uint64(randomByte) {
return candidateIndex, nil
}
}
}