mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-10 16:08:26 -05:00
Remove Shard Committees 4 - Validator Registries Processing (#1368)
This commit is contained in:
@@ -383,7 +383,8 @@ func winningRoot(
|
||||
return winnerRoot, nil
|
||||
}
|
||||
|
||||
// randaoMix returns the randao mix of a given slot.
|
||||
// randaoMix returns the randao mix (xor'ed seed)
|
||||
// of a given slot. It is used to shuffle validators.
|
||||
//
|
||||
// Spec pseudocode definition:
|
||||
// def get_randao_mix(state: BeaconState,
|
||||
|
||||
@@ -235,7 +235,7 @@ func TestPrevEpochBoundaryAttestations(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestHeadAttestations_Ok(t *testing.T) {
|
||||
func TestHeadAttestationsOk(t *testing.T) {
|
||||
if params.BeaconConfig().EpochLength != 64 {
|
||||
t.Errorf("EpochLength should be 64 for these tests to pass")
|
||||
}
|
||||
@@ -270,7 +270,7 @@ func TestHeadAttestations_Ok(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestHeadAttestations_NotOk(t *testing.T) {
|
||||
func TestHeadAttestationsNotOk(t *testing.T) {
|
||||
if params.BeaconConfig().EpochLength != 64 {
|
||||
t.Errorf("EpochLength should be 64 for these tests to pass")
|
||||
}
|
||||
@@ -284,7 +284,7 @@ func TestHeadAttestations_NotOk(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestWinningRoot_Ok(t *testing.T) {
|
||||
func TestWinningRootOk(t *testing.T) {
|
||||
defaultBalance := params.BeaconConfig().MaxDeposit
|
||||
|
||||
ShardCommittees := []*pb.ShardCommitteeArray{
|
||||
@@ -346,7 +346,7 @@ func TestWinningRoot_Ok(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestWinningRoot_OutOfBound(t *testing.T) {
|
||||
func TestWinningRootOutOfBound(t *testing.T) {
|
||||
ShardCommittees := []*pb.ShardCommitteeArray{
|
||||
{ArrayShardCommittee: []*pb.ShardCommittee{
|
||||
{Shard: 1, Committee: []uint32{}},
|
||||
@@ -374,7 +374,7 @@ func TestWinningRoot_OutOfBound(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestAttestingValidators_Ok(t *testing.T) {
|
||||
func TestAttestingValidatorsOk(t *testing.T) {
|
||||
defaultBalance := params.BeaconConfig().MaxDeposit
|
||||
|
||||
ShardCommittees := []*pb.ShardCommitteeArray{
|
||||
@@ -450,7 +450,7 @@ func TestAttestingValidators_CantGetWinningRoot(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestTotalAttestingBalance_Ok(t *testing.T) {
|
||||
func TestTotalAttestingBalanceOk(t *testing.T) {
|
||||
ShardCommittees := []*pb.ShardCommitteeArray{
|
||||
{ArrayShardCommittee: []*pb.ShardCommittee{
|
||||
{Shard: 1, Committee: []uint32{0, 1, 2, 3, 4, 5, 6, 7}},
|
||||
@@ -494,7 +494,7 @@ func TestTotalAttestingBalance_Ok(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestTotalAttestingBalance_NotOfBound(t *testing.T) {
|
||||
func TestTotalAttestingBalanceOutOfBound(t *testing.T) {
|
||||
ShardCommittees := []*pb.ShardCommitteeArray{
|
||||
{ArrayShardCommittee: []*pb.ShardCommittee{
|
||||
{Shard: 1, Committee: []uint32{}},
|
||||
@@ -539,7 +539,7 @@ func TestTotalBalance(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestInclusionSlot_Ok(t *testing.T) {
|
||||
func TestInclusionSlotOk(t *testing.T) {
|
||||
ShardCommittees := []*pb.ShardCommitteeArray{
|
||||
{ArrayShardCommittee: []*pb.ShardCommittee{
|
||||
{Shard: 1, Committee: []uint32{0, 1, 2, 3, 4, 5, 6, 7}},
|
||||
@@ -567,7 +567,7 @@ func TestInclusionSlot_Ok(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestInclusionSlot_BadBitfield(t *testing.T) {
|
||||
func TestInclusionSlotBadBitfield(t *testing.T) {
|
||||
ShardCommittees := []*pb.ShardCommitteeArray{
|
||||
{ArrayShardCommittee: []*pb.ShardCommittee{
|
||||
{Shard: 1, Committee: []uint32{1}},
|
||||
@@ -588,7 +588,7 @@ func TestInclusionSlot_BadBitfield(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestInclusionSlot_NotFound(t *testing.T) {
|
||||
func TestInclusionSlotNotFound(t *testing.T) {
|
||||
ShardCommittees := []*pb.ShardCommitteeArray{
|
||||
{ArrayShardCommittee: []*pb.ShardCommittee{
|
||||
{Shard: 1, Committee: []uint32{1}},
|
||||
@@ -604,7 +604,7 @@ func TestInclusionSlot_NotFound(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestInclusionDistance_Ok(t *testing.T) {
|
||||
func TestInclusionDistanceOk(t *testing.T) {
|
||||
ShardCommittees := []*pb.ShardCommitteeArray{
|
||||
{ArrayShardCommittee: []*pb.ShardCommittee{
|
||||
{Shard: 1, Committee: []uint32{0, 1, 2, 3, 4, 5, 6, 7}},
|
||||
@@ -633,7 +633,7 @@ func TestInclusionDistance_Ok(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestInclusionDistance_BadBitfield(t *testing.T) {
|
||||
func TestInclusionDistanceBadBitfield(t *testing.T) {
|
||||
ShardCommittees := []*pb.ShardCommitteeArray{
|
||||
{ArrayShardCommittee: []*pb.ShardCommittee{
|
||||
{Shard: 1, Committee: []uint32{1}},
|
||||
@@ -654,7 +654,7 @@ func TestInclusionDistance_BadBitfield(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestInclusionDistance_NotFound(t *testing.T) {
|
||||
func TestInclusionDistanceNotFound(t *testing.T) {
|
||||
ShardCommittees := []*pb.ShardCommitteeArray{
|
||||
{ArrayShardCommittee: []*pb.ShardCommittee{
|
||||
{Shard: 1, Committee: []uint32{1}},
|
||||
@@ -670,7 +670,7 @@ func TestInclusionDistance_NotFound(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestRandaoMix_Ok(t *testing.T) {
|
||||
func TestRandaoMixOk(t *testing.T) {
|
||||
randaoMixes := make([][]byte, config.LatestRandaoMixesLength)
|
||||
for i := 0; i < len(randaoMixes); i++ {
|
||||
intInBytes := make([]byte, 32)
|
||||
@@ -708,12 +708,12 @@ func TestRandaoMix_Ok(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestRandaoMix_OutOfBound(t *testing.T) {
|
||||
want := fmt.Sprintf(
|
||||
func TestRandaoMixOutOfBound(t *testing.T) {
|
||||
wanted := fmt.Sprintf(
|
||||
"input randaoMix slot %d out of bounds: %d <= slot < %d",
|
||||
100, 0, 0,
|
||||
)
|
||||
if _, err := randaoMix(&pb.BeaconState{}, 100); !strings.Contains(err.Error(), want) {
|
||||
t.Errorf("Expected: %s, received: %s", want, err.Error())
|
||||
if _, err := randaoMix(&pb.BeaconState{}, 100); !strings.Contains(err.Error(), wanted) {
|
||||
t.Errorf("Expected: %s, received: %s", wanted, err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@ import (
|
||||
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/validators"
|
||||
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
||||
bytesutil "github.com/prysmaticlabs/prysm/shared/bytes"
|
||||
"github.com/prysmaticlabs/prysm/shared/mathutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/params"
|
||||
)
|
||||
@@ -200,50 +199,48 @@ func ProcessEjections(state *pb.BeaconState) (*pb.BeaconState, error) {
|
||||
return state, nil
|
||||
}
|
||||
|
||||
// ProcessValidatorRegistry computes and sets new validator registry fields,
|
||||
// reshuffles shard committees and returns the recomputed state.
|
||||
// ProcessPrevSlotShard computes and sets current epoch's calculation slot
|
||||
// and start shard to previous epoch. Then it returns the updated state.
|
||||
//
|
||||
// Spec pseudocode definition:
|
||||
// Set state.shard_committees_at_slots[:EPOCH_LENGTH] = state.shard_committees_at_slots[EPOCH_LENGTH:].
|
||||
// Set state.shard_committees_at_slots[EPOCH_LENGTH:] =
|
||||
// get_new_shuffling(state.latest_randao_mixes[(state.slot - SEED_LOOKAHEAD) %
|
||||
// LATEST_RANDAO_MIXES_LENGTH], state.validator_registry, next_start_shard, state.slot)
|
||||
// where next_start_shard = (state.shard_committees_at_slots[-1][-1].shard + 1) % SHARD_COUNT
|
||||
// Set state.previous_epoch_randao_mix = state.current_epoch_randao_mix
|
||||
// Set state.current_epoch_calculation_slot = state.slot
|
||||
func ProcessPrevSlotShard(state *pb.BeaconState) *pb.BeaconState {
|
||||
state.PreviousEpochCalculationSlot = state.CurrentEpochCalculationSlot
|
||||
state.PreviousEpochStartShard = state.CurrentEpochStartShard
|
||||
return state
|
||||
}
|
||||
|
||||
// ProcessValidatorRegistry computes and sets new validator registry fields,
|
||||
// reshuffles shard committees and returns the recomputed state with the updated registry.
|
||||
//
|
||||
// Spec pseudocode definition:
|
||||
// Set state.previous_epoch_randao_mix = state.current_epoch_randao_mix
|
||||
// Set state.current_epoch_calculation_slot = state.slot
|
||||
// Set state.current_epoch_start_shard = (state.current_epoch_start_shard + get_current_epoch_committees_per_slot(state) * EPOCH_LENGTH) % SHARD_COUNT
|
||||
// Set state.current_epoch_randao_mix = get_randao_mix(state, state.current_epoch_calculation_slot - SEED_LOOKAHEAD)
|
||||
func ProcessValidatorRegistry(
|
||||
state *pb.BeaconState) (*pb.BeaconState, error) {
|
||||
|
||||
epochLength := int(config.EpochLength)
|
||||
randaoMixesLength := config.LatestRandaoMixesLength
|
||||
seedLookahead := config.SeedLookahead
|
||||
shardCount := config.ShardCount
|
||||
state.PreviousEpochRandaoMixHash32 = state.CurrentEpochRandaoMixHash32
|
||||
state.CurrentEpochCalculationSlot = state.Slot
|
||||
|
||||
state, err := validators.UpdateRegistry(state)
|
||||
nextStartShard := (state.CurrentEpochStartShard +
|
||||
validators.CurrCommitteesCountPerSlot(state)*config.EpochLength) %
|
||||
config.EpochLength
|
||||
state.CurrentEpochStartShard = nextStartShard
|
||||
|
||||
shardCommittees := state.ShardCommitteesAtSlots
|
||||
lastSlot := len(shardCommittees) - 1
|
||||
lastCommittee := len(shardCommittees[lastSlot].ArrayShardCommittee) - 1
|
||||
nextStartShard := (shardCommittees[lastSlot].ArrayShardCommittee[lastCommittee].Shard + 1) %
|
||||
shardCount
|
||||
|
||||
randaoHash32 := bytesutil.ToBytes32(state.LatestRandaoMixesHash32S[(state.Slot-
|
||||
uint64(seedLookahead))%randaoMixesLength])
|
||||
|
||||
for i := 0; i < epochLength; i++ {
|
||||
state.ShardCommitteesAtSlots[i] = state.ShardCommitteesAtSlots[epochLength+i]
|
||||
var randaoMixSlot uint64
|
||||
if state.CurrentEpochCalculationSlot > config.SeedLookahead {
|
||||
randaoMixSlot = state.CurrentEpochCalculationSlot -
|
||||
config.SeedLookahead
|
||||
}
|
||||
newShuffledCommittees, err := validators.ShuffleValidatorRegistryToCommittees(
|
||||
randaoHash32,
|
||||
state.ValidatorRegistry,
|
||||
nextStartShard,
|
||||
state.Slot,
|
||||
)
|
||||
mix, err := randaoMix(state, randaoMixSlot)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not shuffle validator registry for commtitees: %v", err)
|
||||
return nil, fmt.Errorf("could not get randao mix: %v", err)
|
||||
}
|
||||
state.CurrentEpochRandaoMixHash32 = mix
|
||||
|
||||
for i := 0; i < epochLength; i++ {
|
||||
state.ShardCommitteesAtSlots[epochLength+i] = newShuffledCommittees[i]
|
||||
}
|
||||
return state, nil
|
||||
}
|
||||
|
||||
@@ -252,40 +249,31 @@ func ProcessValidatorRegistry(
|
||||
// validator registry update did not happen.
|
||||
//
|
||||
// Spec pseudocode definition:
|
||||
// Set state.shard_committees_at_slots[:EPOCH_LENGTH] = state.shard_committees_at_slots[EPOCH_LENGTH:]
|
||||
// Let epochs_since_last_registry_change =
|
||||
// (state.slot - state.validator_registry_latest_change_slot) // EPOCH_LENGTH
|
||||
// If epochs_since_last_registry_change is an exact power of 2:
|
||||
// state.shard_committees_at_slots[EPOCH_LENGTH:] =
|
||||
// get_shuffling(state.latest_randao_mixes[(state.slot - SEED_LOOKAHEAD)
|
||||
// % LATEST_RANDAO_MIXES_LENGTH], state.validator_registry, start_shard, state.slot)
|
||||
func ProcessPartialValidatorRegistry(
|
||||
state *pb.BeaconState) (*pb.BeaconState, error) {
|
||||
// Set state.previous_epoch_calculation_slot = state.current_epoch_calculation_slot
|
||||
// Set state.previous_epoch_start_shard = state.current_epoch_start_shard
|
||||
// Let epochs_since_last_registry_change = (state.slot - state.validator_registry_latest_change_slot)
|
||||
// EPOCH_LENGTH.
|
||||
// If epochs_since_last_registry_change is an exact power of 2,
|
||||
// set state.current_epoch_calculation_slot = state.slot
|
||||
// set state.current_epoch_randao_mix = state.latest_randao_mixes[
|
||||
// (state.current_epoch_calculation_slot - SEED_LOOKAHEAD) %
|
||||
// LATEST_RANDAO_MIXES_LENGTH].
|
||||
func ProcessPartialValidatorRegistry(state *pb.BeaconState) *pb.BeaconState {
|
||||
epochsSinceLastRegistryChange := (state.Slot - state.ValidatorRegistryUpdateSlot) /
|
||||
config.EpochLength
|
||||
|
||||
epochLength := int(config.EpochLength)
|
||||
randaoMixesLength := config.LatestRandaoMixesLength
|
||||
seedLookahead := config.SeedLookahead
|
||||
randaoHash32 := bytesutil.ToBytes32(state.LatestRandaoMixesHash32S[(state.Slot-uint64(seedLookahead))%randaoMixesLength])
|
||||
for i := 0; i < epochLength; i++ {
|
||||
state.ShardCommitteesAtSlots[i] = state.ShardCommitteesAtSlots[epochLength+i]
|
||||
}
|
||||
epochsSinceLastRegistryChange := (state.Slot - state.ValidatorRegistryUpdateSlot) / uint64(epochLength)
|
||||
startShard := state.ShardCommitteesAtSlots[0].ArrayShardCommittee[0].Shard
|
||||
if mathutil.IsPowerOf2(epochsSinceLastRegistryChange) {
|
||||
newShuffledCommittees, err := validators.ShuffleValidatorRegistryToCommittees(
|
||||
randaoHash32,
|
||||
state.ValidatorRegistry,
|
||||
startShard,
|
||||
state.Slot,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not shuffle validator registry for commtitees: %v", err)
|
||||
}
|
||||
for i := 0; i < epochLength; i++ {
|
||||
state.ShardCommitteesAtSlots[epochLength+i] = newShuffledCommittees[i]
|
||||
state.CurrentEpochCalculationSlot = state.Slot
|
||||
|
||||
var randaoIndex uint64
|
||||
if state.CurrentEpochCalculationSlot > config.SeedLookahead {
|
||||
randaoIndex = state.CurrentEpochCalculationSlot - config.SeedLookahead
|
||||
}
|
||||
|
||||
randaoMix := state.LatestRandaoMixesHash32S[randaoIndex%config.LatestRandaoMixesLength]
|
||||
state.CurrentEpochRandaoMixHash32 = randaoMix
|
||||
}
|
||||
return state, nil
|
||||
return state
|
||||
}
|
||||
|
||||
// CleanupAttestations removes any attestation in state's latest attestations
|
||||
|
||||
@@ -223,7 +223,7 @@ func TestProcessFinalization(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestProcessCrosslinks_Ok(t *testing.T) {
|
||||
func TestProcessCrosslinksOk(t *testing.T) {
|
||||
shardCommitteesAtSlot := []*pb.ShardCommitteeArray{
|
||||
{ArrayShardCommittee: []*pb.ShardCommittee{
|
||||
{Shard: 1, Committee: []uint32{0, 1, 2, 3, 4, 5, 6, 7}},
|
||||
@@ -273,7 +273,7 @@ func TestProcessCrosslinks_Ok(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestProcessCrosslinks_NoRoot(t *testing.T) {
|
||||
func TestProcessCrosslinksNoRoot(t *testing.T) {
|
||||
shardCommitteesAtSlot := []*pb.ShardCommitteeArray{
|
||||
{ArrayShardCommittee: []*pb.ShardCommittee{
|
||||
{Shard: 1, Committee: []uint32{0, 1, 2, 3, 4, 5, 6, 7}},
|
||||
@@ -297,7 +297,7 @@ func TestProcessCrosslinks_NoRoot(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestProcessEjections_Ok(t *testing.T) {
|
||||
func TestProcessEjectionsOk(t *testing.T) {
|
||||
var ShardCommittees []*pb.ShardCommitteeArray
|
||||
for i := uint64(0); i < params.BeaconConfig().EpochLength*2; i++ {
|
||||
ShardCommittees = append(ShardCommittees, &pb.ShardCommitteeArray{
|
||||
@@ -374,121 +374,67 @@ func TestCanNotProcessValidatorRegistry(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestProcessValidatorRegistry(t *testing.T) {
|
||||
epochLength := params.BeaconConfig().EpochLength
|
||||
shardCommittees := make([]*pb.ShardCommitteeArray, epochLength*2)
|
||||
for i := 0; i < len(shardCommittees); i++ {
|
||||
shardCommittees[i] = &pb.ShardCommitteeArray{
|
||||
ArrayShardCommittee: []*pb.ShardCommittee{{Shard: uint64(i)}},
|
||||
}
|
||||
}
|
||||
|
||||
func TestProcessPrevSlotShardOk(t *testing.T) {
|
||||
state := &pb.BeaconState{
|
||||
Slot: 64,
|
||||
ValidatorRegistryUpdateSlot: 1,
|
||||
ShardCommitteesAtSlots: shardCommittees,
|
||||
LatestRandaoMixesHash32S: [][]byte{{'A'}},
|
||||
}
|
||||
copiedState := proto.Clone(state).(*pb.BeaconState)
|
||||
newState, err := ProcessValidatorRegistry(copiedState)
|
||||
if err != nil {
|
||||
t.Fatalf("Could not execute ProcessValidatorRegistry: %v", err)
|
||||
CurrentEpochCalculationSlot: 1,
|
||||
CurrentEpochStartShard: 2,
|
||||
}
|
||||
|
||||
if newState.ShardCommitteesAtSlots[0].ArrayShardCommittee[0].Shard != state.ShardCommitteesAtSlots[epochLength].ArrayShardCommittee[0].Shard {
|
||||
t.Errorf("Incorrect rotation for shard committees, wanted shard: %d, got shard: %d",
|
||||
state.ShardCommitteesAtSlots[0].ArrayShardCommittee[0].Shard,
|
||||
newState.ShardCommitteesAtSlots[epochLength].ArrayShardCommittee[0].Shard)
|
||||
newState := ProcessPrevSlotShard(
|
||||
proto.Clone(state).(*pb.BeaconState))
|
||||
|
||||
if newState.PreviousEpochCalculationSlot != state.CurrentEpochCalculationSlot {
|
||||
t.Errorf("Incorret prev epoch calculation slot: Wanted: %d, got: %d",
|
||||
newState.PreviousEpochCalculationSlot, state.CurrentEpochCalculationSlot)
|
||||
}
|
||||
if newState.PreviousEpochStartShard != state.CurrentEpochStartShard {
|
||||
t.Errorf("Incorret prev epoch start shard: Wanted: %d, got: %d",
|
||||
newState.PreviousEpochStartShard, state.CurrentEpochStartShard)
|
||||
}
|
||||
}
|
||||
|
||||
func TestProcessValidatorRegistry_ReachedUpperBound(t *testing.T) {
|
||||
epochLength := params.BeaconConfig().EpochLength
|
||||
shardCommittees := make([]*pb.ShardCommitteeArray, epochLength*2)
|
||||
for i := 0; i < len(shardCommittees); i++ {
|
||||
shardCommittees[i] = &pb.ShardCommitteeArray{
|
||||
ArrayShardCommittee: []*pb.ShardCommittee{{Shard: uint64(i)}},
|
||||
}
|
||||
}
|
||||
validators := make([]*pb.ValidatorRecord, 1<<params.BeaconConfig().MaxNumLog2Validators-1)
|
||||
balances := make([]uint64, 1<<params.BeaconConfig().MaxNumLog2Validators-1)
|
||||
validator := &pb.ValidatorRecord{ExitSlot: params.BeaconConfig().FarFutureSlot}
|
||||
for i := 0; i < len(validators); i++ {
|
||||
validators[i] = validator
|
||||
balances[i] = params.BeaconConfig().MaxDepositInGwei
|
||||
}
|
||||
func TestProcessValidatorRegistryOk(t *testing.T) {
|
||||
offset := uint64(1)
|
||||
state := &pb.BeaconState{
|
||||
Slot: 64,
|
||||
ValidatorRegistryUpdateSlot: 1,
|
||||
ShardCommitteesAtSlots: shardCommittees,
|
||||
LatestRandaoMixesHash32S: [][]byte{{'A'}},
|
||||
ValidatorRegistry: validators,
|
||||
ValidatorBalances: balances,
|
||||
Slot: config.SeedLookahead + offset,
|
||||
LatestRandaoMixesHash32S: [][]byte{{'A'}, {'B'}},
|
||||
CurrentEpochRandaoMixHash32: []byte{'C'},
|
||||
}
|
||||
|
||||
if _, err := ProcessValidatorRegistry(state); err == nil {
|
||||
t.Fatalf("ProcessValidatorRegistry should have failed with upperbound")
|
||||
newState, err := ProcessValidatorRegistry(
|
||||
proto.Clone(state).(*pb.BeaconState))
|
||||
if err != nil {
|
||||
t.Fatalf("Could not execute ProcessValidatorRegistry: %v", err)
|
||||
}
|
||||
if !bytes.Equal(newState.PreviousEpochRandaoMixHash32, state.CurrentEpochRandaoMixHash32) {
|
||||
t.Errorf("Incorret prev epoch randao mix hash: Wanted: %v, got: %v",
|
||||
state.CurrentEpochRandaoMixHash32, newState.PreviousEpochRandaoMixHash32)
|
||||
}
|
||||
if newState.CurrentEpochCalculationSlot != state.Slot {
|
||||
t.Errorf("Incorret curr epoch calculation slot: Wanted: %d, got: %d",
|
||||
newState.CurrentEpochCalculationSlot, state.Slot)
|
||||
}
|
||||
if !bytes.Equal(newState.CurrentEpochRandaoMixHash32, state.LatestRandaoMixesHash32S[offset]) {
|
||||
t.Errorf("Incorret current epoch randao mix hash: Wanted: %v, got: %v",
|
||||
state.LatestRandaoMixesHash32S[offset], newState.CurrentEpochRandaoMixHash32)
|
||||
}
|
||||
}
|
||||
|
||||
func TestProcessPartialValidatorRegistry(t *testing.T) {
|
||||
epochLength := params.BeaconConfig().EpochLength
|
||||
shardCommittees := make([]*pb.ShardCommitteeArray, epochLength*2)
|
||||
for i := 0; i < len(shardCommittees); i++ {
|
||||
shardCommittees[i] = &pb.ShardCommitteeArray{
|
||||
ArrayShardCommittee: []*pb.ShardCommittee{{Shard: uint64(i)}},
|
||||
}
|
||||
}
|
||||
|
||||
offset := uint64(1)
|
||||
state := &pb.BeaconState{
|
||||
Slot: 64,
|
||||
ValidatorRegistryUpdateSlot: 1,
|
||||
ShardCommitteesAtSlots: shardCommittees,
|
||||
LatestRandaoMixesHash32S: [][]byte{{'A'}},
|
||||
Slot: config.SeedLookahead + offset,
|
||||
ValidatorRegistryUpdateSlot: offset,
|
||||
LatestRandaoMixesHash32S: [][]byte{{'A'}, {'B'}},
|
||||
}
|
||||
copiedState := proto.Clone(state).(*pb.BeaconState)
|
||||
newState, err := ProcessPartialValidatorRegistry(copiedState)
|
||||
if err != nil {
|
||||
t.Fatalf("Could not execute ProcessValidatorRegistryNoUpdate: %v", err)
|
||||
newState := ProcessPartialValidatorRegistry(copiedState)
|
||||
if newState.CurrentEpochCalculationSlot != state.Slot {
|
||||
t.Errorf("Incorrect CurrentEpochCalculationSlot, wanted: %d, got: %d",
|
||||
state.Slot, newState.CurrentEpochCalculationSlot)
|
||||
}
|
||||
if newState.ValidatorRegistryUpdateSlot != state.ValidatorRegistryUpdateSlot {
|
||||
t.Errorf("Incorrect ValidatorRegistryUpdateSlot, wanted: %d, got: %d",
|
||||
state.ValidatorRegistryUpdateSlot, newState.ValidatorRegistryUpdateSlot)
|
||||
}
|
||||
|
||||
if newState.ShardCommitteesAtSlots[0].ArrayShardCommittee[0].Shard != state.ShardCommitteesAtSlots[epochLength].ArrayShardCommittee[0].Shard {
|
||||
t.Errorf("Incorrect rotation for shard committees, wanted shard: %d, got shard: %d",
|
||||
state.ShardCommitteesAtSlots[0].ArrayShardCommittee[0].Shard,
|
||||
newState.ShardCommitteesAtSlots[epochLength].ArrayShardCommittee[0].Shard)
|
||||
}
|
||||
}
|
||||
|
||||
func TestProcessPartialValidatorRegistry_ReachedUpperBound(t *testing.T) {
|
||||
epochLength := params.BeaconConfig().EpochLength
|
||||
shardCommittees := make([]*pb.ShardCommitteeArray, epochLength*2)
|
||||
for i := 0; i < len(shardCommittees); i++ {
|
||||
shardCommittees[i] = &pb.ShardCommitteeArray{
|
||||
ArrayShardCommittee: []*pb.ShardCommittee{{Shard: uint64(i)}},
|
||||
}
|
||||
}
|
||||
validators := make([]*pb.ValidatorRecord, 1<<params.BeaconConfig().MaxNumLog2Validators-1)
|
||||
balances := make([]uint64, 1<<params.BeaconConfig().MaxNumLog2Validators-1)
|
||||
validator := &pb.ValidatorRecord{ExitSlot: params.BeaconConfig().FarFutureSlot}
|
||||
for i := 0; i < len(validators); i++ {
|
||||
validators[i] = validator
|
||||
balances[i] = params.BeaconConfig().MaxDepositInGwei
|
||||
}
|
||||
state := &pb.BeaconState{
|
||||
Slot: 64,
|
||||
ValidatorRegistryUpdateSlot: 1,
|
||||
ShardCommitteesAtSlots: shardCommittees,
|
||||
LatestRandaoMixesHash32S: [][]byte{{'A'}},
|
||||
ValidatorRegistry: validators,
|
||||
ValidatorBalances: balances,
|
||||
}
|
||||
|
||||
if _, err := ProcessPartialValidatorRegistry(state); err == nil {
|
||||
t.Fatalf("ProcessValidatorRegistry should have failed with upperbound")
|
||||
if !bytes.Equal(newState.CurrentEpochRandaoMixHash32, state.LatestRandaoMixesHash32S[offset]) {
|
||||
t.Errorf("Incorret current epoch randao mix hash: Wanted: %v, got: %v",
|
||||
state.LatestRandaoMixesHash32S[offset], newState.CurrentEpochRandaoMixHash32)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -290,18 +290,15 @@ func ProcessEpoch(state *pb.BeaconState) (*pb.BeaconState, error) {
|
||||
}
|
||||
|
||||
// Process validator registry.
|
||||
state = e.ProcessPrevSlotShard(state)
|
||||
state = v.ProcessPenaltiesAndExits(state)
|
||||
if e.CanProcessValidatorRegistry(state) {
|
||||
state = v.ProcessPenaltiesAndExits(state)
|
||||
state, err = e.ProcessValidatorRegistry(state)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not process validator registry: %v", err)
|
||||
}
|
||||
} else {
|
||||
state = v.ProcessPenaltiesAndExits(state)
|
||||
state, err = e.ProcessPartialValidatorRegistry(state)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not process partial validator registry: %v", err)
|
||||
}
|
||||
state = e.ProcessPartialValidatorRegistry(state)
|
||||
}
|
||||
|
||||
// Clean up processed attestations.
|
||||
|
||||
@@ -6,7 +6,6 @@ import (
|
||||
"testing"
|
||||
|
||||
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
||||
"github.com/prysmaticlabs/prysm/shared/params"
|
||||
)
|
||||
|
||||
func TestProcessBlock_IncorrectSlot(t *testing.T) {
|
||||
@@ -758,95 +757,3 @@ func TestProcessEpoch_CantProcessEjections(t *testing.T) {
|
||||
t.Errorf("Expected: %s, received: %v", want, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestProcessEpoch_CantProcessValidators(t *testing.T) {
|
||||
defaultBalance := config.MaxDepositInGwei
|
||||
|
||||
var shardCommittees []*pb.ShardCommitteeArray
|
||||
for i := uint64(0); i < config.EpochLength*2; i++ {
|
||||
shardCommittees = append(shardCommittees, &pb.ShardCommitteeArray{
|
||||
ArrayShardCommittee: []*pb.ShardCommittee{
|
||||
{Committee: []uint32{}},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
var randaoHashes [][]byte
|
||||
for i := uint64(0); i < 4*config.EpochLength; i++ {
|
||||
randaoHashes = append(randaoHashes, []byte{byte(i)})
|
||||
}
|
||||
|
||||
size := 1<<(params.BeaconConfig().RandBytes*8) - 1
|
||||
validators := make([]*pb.ValidatorRecord, size)
|
||||
validatorBalances := make([]uint64, size)
|
||||
validator := &pb.ValidatorRecord{ExitSlot: params.BeaconConfig().FarFutureSlot}
|
||||
for i := 0; i < size; i++ {
|
||||
validators[i] = validator
|
||||
validatorBalances[i] = defaultBalance
|
||||
}
|
||||
|
||||
state := &pb.BeaconState{
|
||||
Slot: 4 * config.EpochLength,
|
||||
ValidatorBalances: validatorBalances,
|
||||
ShardCommitteesAtSlots: shardCommittees,
|
||||
LatestBlockRootHash32S: make([][]byte, config.LatestBlockRootsLength),
|
||||
ValidatorRegistry: validators,
|
||||
LatestRandaoMixesHash32S: randaoHashes,
|
||||
LatestAttestations: []*pb.PendingAttestationRecord{
|
||||
{Data: &pb.AttestationData{}, ParticipationBitfield: []byte{}}},
|
||||
FinalizedSlot: 1,
|
||||
LatestCrosslinks: []*pb.CrosslinkRecord{{Slot: 1}},
|
||||
}
|
||||
|
||||
want := fmt.Sprint(
|
||||
"could not shuffle validator registry for commtitees: input list exceeded upper bound and reached modulo bias",
|
||||
)
|
||||
if _, err := ProcessEpoch(state); !strings.Contains(err.Error(), want) {
|
||||
t.Errorf("Expected: %s, received: %v", want, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestProcessEpoch_CantProcessPartialValidators(t *testing.T) {
|
||||
defaultBalance := config.MaxDepositInGwei
|
||||
|
||||
var shardCommittees []*pb.ShardCommitteeArray
|
||||
for i := uint64(0); i < config.EpochLength*2; i++ {
|
||||
shardCommittees = append(shardCommittees, &pb.ShardCommitteeArray{
|
||||
ArrayShardCommittee: []*pb.ShardCommittee{
|
||||
{Shard: 1, Committee: []uint32{}},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
var randaoHashes [][]byte
|
||||
for i := uint64(0); i < 4*config.EpochLength; i++ {
|
||||
randaoHashes = append(randaoHashes, []byte{byte(i)})
|
||||
}
|
||||
|
||||
size := 1<<(params.BeaconConfig().RandBytes*8) - 1
|
||||
validators := make([]*pb.ValidatorRecord, size)
|
||||
validatorBalances := make([]uint64, size)
|
||||
validator := &pb.ValidatorRecord{ExitSlot: params.BeaconConfig().FarFutureSlot}
|
||||
for i := 0; i < size; i++ {
|
||||
validators[i] = validator
|
||||
validatorBalances[i] = defaultBalance
|
||||
}
|
||||
|
||||
state := &pb.BeaconState{
|
||||
Slot: 4 * config.EpochLength,
|
||||
ValidatorBalances: validatorBalances,
|
||||
ShardCommitteesAtSlots: shardCommittees,
|
||||
LatestBlockRootHash32S: make([][]byte, config.LatestBlockRootsLength),
|
||||
ValidatorRegistry: validators,
|
||||
LatestRandaoMixesHash32S: randaoHashes,
|
||||
LatestAttestations: []*pb.PendingAttestationRecord{
|
||||
{Data: &pb.AttestationData{}, ParticipationBitfield: []byte{}},
|
||||
}}
|
||||
|
||||
want := fmt.Sprint(
|
||||
"could not shuffle validator registry for commtitees: input list exceeded upper bound and reached modulo bias",
|
||||
)
|
||||
if _, err := ProcessEpoch(state); !strings.Contains(err.Error(), want) {
|
||||
t.Errorf("Expected: %s, received: %v", want, err)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user