2019-09-27 02:51:39 +00:00
|
|
|
package cache
|
|
|
|
|
|
|
|
import (
|
2020-03-19 04:41:05 +00:00
|
|
|
"math"
|
2019-09-27 02:51:39 +00:00
|
|
|
"reflect"
|
2019-12-16 18:14:21 +00:00
|
|
|
"sort"
|
2019-09-27 02:51:39 +00:00
|
|
|
"strconv"
|
|
|
|
"testing"
|
2019-11-11 22:03:44 +00:00
|
|
|
|
2019-12-16 18:14:21 +00:00
|
|
|
"github.com/prysmaticlabs/prysm/shared/bytesutil"
|
2019-11-11 22:03:44 +00:00
|
|
|
"github.com/prysmaticlabs/prysm/shared/params"
|
2019-09-27 02:51:39 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
func TestCommitteeKeyFn_OK(t *testing.T) {
|
2019-12-16 18:14:21 +00:00
|
|
|
item := &Committees{
|
|
|
|
CommitteeCount: 1,
|
|
|
|
Seed: [32]byte{'A'},
|
|
|
|
ShuffledIndices: []uint64{1, 2, 3, 4, 5},
|
2019-09-27 02:51:39 +00:00
|
|
|
}
|
|
|
|
|
2019-12-16 18:14:21 +00:00
|
|
|
k, err := committeeKeyFn(item)
|
2019-09-27 02:51:39 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
2019-12-16 18:14:21 +00:00
|
|
|
if k != key(item.Seed) {
|
|
|
|
t.Errorf("Incorrect hash k: %s, expected %s", k, key(item.Seed))
|
2019-09-27 02:51:39 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestCommitteeKeyFn_InvalidObj(t *testing.T) {
|
|
|
|
_, err := committeeKeyFn("bad")
|
|
|
|
if err != ErrNotCommittee {
|
|
|
|
t.Errorf("Expected error %v, got %v", ErrNotCommittee, err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestCommitteeCache_CommitteesByEpoch(t *testing.T) {
|
2019-12-16 18:14:21 +00:00
|
|
|
cache := NewCommitteesCache()
|
2019-09-27 02:51:39 +00:00
|
|
|
|
2019-12-16 18:14:21 +00:00
|
|
|
item := &Committees{
|
|
|
|
ShuffledIndices: []uint64{1, 2, 3, 4, 5, 6},
|
|
|
|
Seed: [32]byte{'A'},
|
|
|
|
CommitteeCount: 3,
|
2019-09-27 02:51:39 +00:00
|
|
|
}
|
|
|
|
|
2019-12-16 18:14:21 +00:00
|
|
|
slot := params.BeaconConfig().SlotsPerEpoch
|
2019-11-11 22:03:44 +00:00
|
|
|
committeeIndex := uint64(1)
|
2019-12-16 18:14:21 +00:00
|
|
|
indices, err := cache.Committee(slot, item.Seed, committeeIndex)
|
2019-09-27 02:51:39 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
if indices != nil {
|
|
|
|
t.Error("Expected committee not to exist in empty cache")
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := cache.AddCommitteeShuffledList(item); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
2019-11-11 22:03:44 +00:00
|
|
|
wantedIndex := uint64(0)
|
2019-12-16 18:14:21 +00:00
|
|
|
indices, err = cache.Committee(slot, item.Seed, wantedIndex)
|
2019-09-27 02:51:39 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
2019-11-11 22:03:44 +00:00
|
|
|
|
|
|
|
start, end := startEndIndices(item, wantedIndex)
|
2019-12-16 18:14:21 +00:00
|
|
|
if !reflect.DeepEqual(indices, item.ShuffledIndices[start:end]) {
|
2019-09-27 02:51:39 +00:00
|
|
|
t.Errorf(
|
|
|
|
"Expected fetched active indices to be %v, got %v",
|
|
|
|
indices,
|
2019-12-16 18:14:21 +00:00
|
|
|
item.ShuffledIndices[start:end],
|
2019-09-27 02:51:39 +00:00
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-12-16 18:14:21 +00:00
|
|
|
func TestCommitteeCache_ActiveIndices(t *testing.T) {
|
|
|
|
cache := NewCommitteesCache()
|
2019-09-27 02:51:39 +00:00
|
|
|
|
2019-12-16 18:14:21 +00:00
|
|
|
item := &Committees{Seed: [32]byte{'A'}, SortedIndices: []uint64{1, 2, 3, 4, 5, 6}}
|
|
|
|
indices, err := cache.ActiveIndices(item.Seed)
|
2019-09-27 02:51:39 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
2019-12-16 18:14:21 +00:00
|
|
|
if indices != nil {
|
|
|
|
t.Error("Expected committee count not to exist in empty cache")
|
2019-09-27 02:51:39 +00:00
|
|
|
}
|
|
|
|
|
2019-12-16 18:14:21 +00:00
|
|
|
if err := cache.AddCommitteeShuffledList(item); err != nil {
|
2019-09-27 02:51:39 +00:00
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2019-12-16 18:14:21 +00:00
|
|
|
indices, err = cache.ActiveIndices(item.Seed)
|
2019-09-27 02:51:39 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
2019-12-16 18:14:21 +00:00
|
|
|
if !reflect.DeepEqual(indices, item.SortedIndices) {
|
|
|
|
t.Error("Did not receive correct active indices from cache")
|
2019-09-27 02:51:39 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-01-16 15:03:49 +00:00
|
|
|
func TestCommitteeCache_AddProposerIndicesList(t *testing.T) {
|
2020-01-14 04:08:32 +00:00
|
|
|
cache := NewCommitteesCache()
|
|
|
|
|
2020-01-16 15:03:49 +00:00
|
|
|
seed := [32]byte{'A'}
|
|
|
|
indices := []uint64{1, 2, 3, 4, 5}
|
|
|
|
indices, err := cache.ProposerIndices(seed)
|
2020-01-14 04:08:32 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
if indices != nil {
|
|
|
|
t.Error("Expected committee count not to exist in empty cache")
|
|
|
|
}
|
2020-01-16 15:03:49 +00:00
|
|
|
if err := cache.AddProposerIndicesList(seed, indices); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
received, err := cache.ProposerIndices(seed)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
if !reflect.DeepEqual(indices, received) {
|
|
|
|
t.Error("Did not receive correct proposer indices from cache")
|
|
|
|
}
|
2020-01-14 04:08:32 +00:00
|
|
|
|
2020-01-16 15:03:49 +00:00
|
|
|
item := &Committees{Seed: [32]byte{'B'}, SortedIndices: []uint64{1, 2, 3, 4, 5, 6}}
|
2020-01-14 04:08:32 +00:00
|
|
|
if err := cache.AddCommitteeShuffledList(item); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
indices, err = cache.ProposerIndices(item.Seed)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
2020-01-16 15:03:49 +00:00
|
|
|
if indices != nil {
|
|
|
|
t.Error("Expected committee count not to exist in empty cache")
|
|
|
|
}
|
|
|
|
if err := cache.AddProposerIndicesList(item.Seed, indices); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
received, err = cache.ProposerIndices(item.Seed)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
if !reflect.DeepEqual(indices, received) {
|
2020-01-14 04:08:32 +00:00
|
|
|
t.Error("Did not receive correct proposer indices from cache")
|
|
|
|
}
|
2020-01-16 15:03:49 +00:00
|
|
|
|
2020-01-14 04:08:32 +00:00
|
|
|
}
|
|
|
|
|
2019-12-16 18:14:21 +00:00
|
|
|
func TestCommitteeCache_CanRotate(t *testing.T) {
|
|
|
|
cache := NewCommitteesCache()
|
2019-09-29 19:10:11 +00:00
|
|
|
|
2019-12-16 18:14:21 +00:00
|
|
|
// Should rotate out all the epochs except 190 through 199.
|
|
|
|
for i := 100; i < 200; i++ {
|
|
|
|
s := []byte(strconv.Itoa(i))
|
|
|
|
item := &Committees{Seed: bytesutil.ToBytes32(s)}
|
|
|
|
if err := cache.AddCommitteeShuffledList(item); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
2019-09-29 19:10:11 +00:00
|
|
|
}
|
|
|
|
|
2019-12-16 18:14:21 +00:00
|
|
|
k := cache.CommitteeCache.ListKeys()
|
|
|
|
if len(k) != maxCommitteesCacheSize {
|
|
|
|
t.Errorf("wanted: %d, got: %d", maxCommitteesCacheSize, len(k))
|
2019-09-29 19:10:11 +00:00
|
|
|
}
|
|
|
|
|
2019-12-16 18:14:21 +00:00
|
|
|
sort.Slice(k, func(i, j int) bool {
|
|
|
|
return k[i] < k[j]
|
|
|
|
})
|
|
|
|
s := bytesutil.ToBytes32([]byte(strconv.Itoa(190)))
|
|
|
|
if k[0] != key(s) {
|
|
|
|
t.Error("incorrect key received for slot 190")
|
2019-09-29 19:10:11 +00:00
|
|
|
}
|
2019-12-16 18:14:21 +00:00
|
|
|
s = bytesutil.ToBytes32([]byte(strconv.Itoa(199)))
|
|
|
|
if k[len(k)-1] != key(s) {
|
|
|
|
t.Error("incorrect key received for slot 199")
|
2019-09-27 02:51:39 +00:00
|
|
|
}
|
|
|
|
}
|
2020-03-19 04:41:05 +00:00
|
|
|
|
|
|
|
func TestCommitteeCacheOutOfRange(t *testing.T) {
|
|
|
|
cache := NewCommitteesCache()
|
|
|
|
seed := bytesutil.ToBytes32([]byte("foo"))
|
2020-04-14 16:41:09 +00:00
|
|
|
err := cache.CommitteeCache.Add(&Committees{
|
2020-03-19 04:41:05 +00:00
|
|
|
CommitteeCount: 1,
|
|
|
|
Seed: seed,
|
|
|
|
ShuffledIndices: []uint64{0},
|
|
|
|
SortedIndices: []uint64{},
|
|
|
|
ProposerIndices: []uint64{},
|
|
|
|
})
|
2020-04-14 16:41:09 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Error(err)
|
|
|
|
}
|
|
|
|
_, err = cache.Committee(0, seed, math.MaxUint64) // Overflow!
|
2020-03-19 04:41:05 +00:00
|
|
|
if err == nil {
|
|
|
|
t.Fatal("Did not fail as expected")
|
|
|
|
}
|
|
|
|
}
|