mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-09 15:37:56 -05:00
Move SplitOffset to Sliceutil (#3606)
This commit is contained in:
@@ -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",
|
||||
|
||||
@@ -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[:])
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user