Move SplitOffset to Sliceutil (#3606)

This commit is contained in:
terence tsao
2019-09-26 16:25:55 -07:00
committed by GitHub
parent 32ffb70a1a
commit b8bd28cca2
7 changed files with 55 additions and 50 deletions

View File

@@ -27,6 +27,7 @@ go_library(
"//shared/bytesutil:go_default_library",
"//shared/hashutil:go_default_library",
"//shared/params:go_default_library",
"//shared/sliceutil:go_default_library",
"@com_github_gogo_protobuf//proto:go_default_library",
"@com_github_pkg_errors//:go_default_library",
"@com_github_prysmaticlabs_go_bitfield//:go_default_library",
@@ -56,6 +57,7 @@ go_test(
"//proto/eth/v1alpha1:go_default_library",
"//shared/bytesutil:go_default_library",
"//shared/params:go_default_library",
"//shared/sliceutil:go_default_library",
"//shared/testutil:go_default_library",
"@com_github_prysmaticlabs_go_bitfield//:go_default_library",
"@com_github_prysmaticlabs_go_ssz//:go_default_library",

View File

@@ -11,6 +11,7 @@ import (
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/sliceutil"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
)
@@ -113,8 +114,8 @@ func ComputeCommittee(
totalCommittees uint64,
) ([]uint64, error) {
validatorCount := uint64(len(validatorIndices))
start := SplitOffset(validatorCount, totalCommittees, indexShard)
end := SplitOffset(validatorCount, totalCommittees, indexShard+1)
start := sliceutil.SplitOffset(validatorCount, totalCommittees, indexShard)
end := sliceutil.SplitOffset(validatorCount, totalCommittees, indexShard+1)
// Use cached shuffled indices list if we have seen the seed before.
cachedShuffledList, err := shuffledIndicesCache.IndicesByIndexSeed(indexShard, seed[:])

View File

@@ -10,6 +10,7 @@ import (
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/sliceutil"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
)
@@ -153,8 +154,8 @@ func TestComputeCommittee_WithoutCache(t *testing.T) {
if err != nil {
t.Errorf("could not compute committee: %v", err)
}
start := SplitOffset(validatorCount, committeeCount, shard)
end := SplitOffset(validatorCount, committeeCount, shard+1)
start := sliceutil.SplitOffset(validatorCount, committeeCount, shard)
end := sliceutil.SplitOffset(validatorCount, committeeCount, shard+1)
if !reflect.DeepEqual(committees[start:end], committee5) {
t.Error("committee has different shuffled indices")
@@ -166,8 +167,8 @@ func TestComputeCommittee_WithoutCache(t *testing.T) {
if err != nil {
t.Errorf("could not compute committee: %v", err)
}
start = SplitOffset(validatorCount, committeeCount, shard)
end = SplitOffset(validatorCount, committeeCount, shard+1)
start = sliceutil.SplitOffset(validatorCount, committeeCount, shard)
end = sliceutil.SplitOffset(validatorCount, committeeCount, shard+1)
if !reflect.DeepEqual(committees[start:end], committee9) {
t.Error("committee has different shuffled indices")

View File

@@ -7,6 +7,7 @@ import (
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/hashutil"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/sliceutil"
)
const seedSize = int8(32)
@@ -22,8 +23,8 @@ func SplitIndices(l []uint64, n uint64) [][]uint64 {
var divided [][]uint64
var lSize = uint64(len(l))
for i := uint64(0); i < n; i++ {
start := SplitOffset(lSize, n, i)
end := SplitOffset(lSize, n, i+1)
start := sliceutil.SplitOffset(lSize, n, i)
end := sliceutil.SplitOffset(lSize, n, i+1)
divided = append(divided, l[start:end])
}
return divided
@@ -125,19 +126,6 @@ func innerShuffledIndex(index uint64, indexCount uint64, seed [32]byte, shuffle
return index, nil
}
// SplitOffset returns (listsize * index) / chunks
//
// Spec pseudocode definition:
// def get_split_offset(list_size: int, chunks: int, index: int) -> int:
// """
// Returns a value such that for a list L, chunk count k and index i,
// split(L, k)[i] == L[get_split_offset(len(L), k, i): get_split_offset(len(L), k, i+1)]
// """
// return (list_size * index) // chunks
func SplitOffset(listSize uint64, chunks uint64, index uint64) uint64 {
return (listSize * index) / chunks
}
// ShuffleList returns list of shuffled indexes in a pseudorandom permutation `p` of `0...list_size - 1` with ``seed`` as entropy.
// We utilize 'swap or not' shuffling in this implementation; we are allocating the memory with the seed that stays
// constant between iterations instead of reallocating it each iteration as in the spec. This implementation is based

View File

@@ -6,6 +6,7 @@ import (
"testing"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/sliceutil"
)
func TestShuffleList_InvalidValidatorCount(t *testing.T) {
@@ -175,36 +176,9 @@ func TestSplitIndicesAndOffset_OK(t *testing.T) {
chunks := uint64(6)
split := SplitIndices(l, chunks)
for i := uint64(0); i < chunks; i++ {
if !reflect.DeepEqual(split[i], l[SplitOffset(uint64(len(l)), chunks, i):SplitOffset(uint64(len(l)), chunks, i+1)]) {
t.Errorf("Want: %v got: %v", l[SplitOffset(uint64(len(l)), chunks, i):SplitOffset(uint64(len(l)), chunks, i+1)], split[i])
if !reflect.DeepEqual(split[i], l[sliceutil.SplitOffset(uint64(len(l)), chunks, i):sliceutil.SplitOffset(uint64(len(l)), chunks, i+1)]) {
t.Errorf("Want: %v got: %v", l[sliceutil.SplitOffset(uint64(len(l)), chunks, i):sliceutil.SplitOffset(uint64(len(l)), chunks, i+1)], split[i])
break
}
}
}
func TestSplitOffset_OK(t *testing.T) {
testCases := []struct {
listSize uint64
chunks uint64
index uint64
offset uint64
}{
{30, 3, 2, 20},
{1000, 10, 60, 6000},
{2482, 10, 70, 17374},
{323, 98, 56, 184},
{273, 8, 6, 204},
{3274, 98, 256, 8552},
{23, 3, 2, 15},
{23, 3, 9, 69},
}
for _, tt := range testCases {
result := SplitOffset(tt.listSize, tt.chunks, tt.index)
if result != tt.offset {
t.Errorf("got %d, want %d", result, tt.offset)
}
}
}

View File

@@ -272,3 +272,17 @@ func SplitCommaSeparated(arr []string) []string {
}
return result
}
// SplitOffset returns the start index of a given list splits into chunks,
// it computes (listsize * index) / chunks.
//
// Spec pseudocode definition:
// def get_split_offset(list_size: int, chunks: int, index: int) -> int:
// """
// Returns a value such that for a list L, chunk count k and index i,
// split(L, k)[i] == L[get_split_offset(len(L), k, i): get_split_offset(len(L), k, i+1)]
// """
// return (list_size * index) // chunks
func SplitOffset(listSize uint64, chunks uint64, index uint64) uint64 {
return (listSize * index) / chunks
}

View File

@@ -378,3 +378,28 @@ func TestSplitCommaSeparated(t *testing.T) {
}
}
}
func TestSplitOffset_OK(t *testing.T) {
testCases := []struct {
listSize uint64
chunks uint64
index uint64
offset uint64
}{
{30, 3, 2, 20},
{1000, 10, 60, 6000},
{2482, 10, 70, 17374},
{323, 98, 56, 184},
{273, 8, 6, 204},
{3274, 98, 256, 8552},
{23, 3, 2, 15},
{23, 3, 9, 69},
}
for _, tt := range testCases {
result := SplitOffset(tt.listSize, tt.chunks, tt.index)
if result != tt.offset {
t.Errorf("got %d, want %d", result, tt.offset)
}
}
}