Part 1 of caching improvement - ShuffledIndices function (#3605)

This commit is contained in:
terence tsao
2019-09-26 16:45:40 -07:00
committed by GitHub
parent b8bd28cca2
commit d7891fca88
2 changed files with 74 additions and 4 deletions

View File

@@ -269,7 +269,7 @@ func CommitteeAssignment(
// ShardDelta returns the minimum number of shards get processed in one epoch.
//
// Note: if you already have the committee count,
// use ShardDeltaFromCommitteeCount as CommitteeCount (specifically
// use shardDeltaFromCommitteeCount as CommitteeCount (specifically
// ActiveValidatorCount) iterates over the entire validator set.
//
// Spec pseudocode definition:
@@ -283,14 +283,14 @@ func ShardDelta(beaconState *pb.BeaconState, epoch uint64) (uint64, error) {
if err != nil {
return 0, errors.Wrap(err, "could not get committee count")
}
return ShardDeltaFromCommitteeCount(committeeCount), nil
return shardDeltaFromCommitteeCount(committeeCount), nil
}
// ShardDeltaFromCommitteeCount returns the number of shards that get processed
// shardDeltaFromCommitteeCount returns the number of shards that get processed
// in one epoch. This method is the inner logic of ShardDelta.
// Returns the minimum of the committeeCount and maximum shard delta which is
// defined as SHARD_COUNT - SHARD_COUNT // SLOTS_PER_EPOCH.
func ShardDeltaFromCommitteeCount(committeeCount uint64) uint64 {
func shardDeltaFromCommitteeCount(committeeCount uint64) uint64 {
shardCount := params.BeaconConfig().ShardCount
maxShardDelta := shardCount - shardCount/params.BeaconConfig().SlotsPerEpoch
if committeeCount < maxShardDelta {
@@ -448,6 +448,32 @@ func CompactCommitteesRoot(state *pb.BeaconState, epoch uint64) ([32]byte, error
}
// ShuffledIndices uses input beacon state and returns the shuffled indices of the input epoch,
// the shuffled indices then can be used to break up into committees.
func ShuffledIndices(state *pb.BeaconState, epoch uint64) ([]uint64, error) {
seed, err := Seed(state, epoch)
if err != nil {
return nil, errors.Wrapf(err, "could not get seed for epoch %d", epoch)
}
indices, err := ActiveValidatorIndices(state, epoch)
if err != nil {
return nil, errors.Wrapf(err, "could not get active indices %d", epoch)
}
validatorCount := uint64(len(indices))
shuffledIndices := make([]uint64, validatorCount)
for i := 0; i < len(shuffledIndices); i++ {
permutedIndex, err := ShuffledIndex(uint64(i), validatorCount, seed)
if err != nil {
return []uint64{}, errors.Wrapf(err, "could not get shuffled index at index %d", i)
}
shuffledIndices[i] = indices[permutedIndex]
}
return shuffledIndices, nil
}
// compressValidator compacts all the validator data such as validator index, slashing info and balance
// into a single uint64 field.
//

View File

@@ -748,6 +748,50 @@ func TestCompactCommitteesRoot_OK(t *testing.T) {
}
}
func TestShuffledIndices_ShuffleRightLength(t *testing.T) {
ClearAllCaches()
valiatorCount := 1000
validators := make([]*ethpb.Validator, valiatorCount)
indices := make([]uint64, valiatorCount)
for i := 0; i < valiatorCount; i++ {
validators[i] = &ethpb.Validator{
ExitEpoch: params.BeaconConfig().FarFutureEpoch,
}
indices[i] = uint64(i)
}
state := &pb.BeaconState{
Validators: validators,
RandaoMixes: make([][]byte, params.BeaconConfig().EpochsPerHistoricalVector),
ActiveIndexRoots: make([][]byte, params.BeaconConfig().EpochsPerHistoricalVector),
}
// Test for current epoch
shuffledIndices, err := ShuffledIndices(state, 0)
if err != nil {
t.Fatal(err)
}
if len(shuffledIndices) != valiatorCount {
t.Errorf("Incorrect shuffled indices count, wanted: %d, got: %d",
valiatorCount, len(shuffledIndices))
}
if reflect.DeepEqual(indices, shuffledIndices) {
t.Error("Shuffling did not happen")
}
// Test for next epoch
shuffledIndices, err = ShuffledIndices(state, 1)
if err != nil {
t.Fatal(err)
}
if len(shuffledIndices) != valiatorCount {
t.Errorf("Incorrect shuffled indices count, wanted: %d, got: %d",
valiatorCount, len(shuffledIndices))
}
if reflect.DeepEqual(indices, shuffledIndices) {
t.Error("Shuffling did not happen")
}
}
func TestCompressValidator(t *testing.T) {
tests := []struct {
validator *ethpb.Validator