2022-05-04 06:15:09 +00:00
|
|
|
//go:build !fuzz
|
|
|
|
|
2019-09-27 02:51:39 +00:00
|
|
|
package cache
|
|
|
|
|
|
|
|
import (
|
2021-09-26 15:27:57 +00:00
|
|
|
"context"
|
2020-03-19 04:41:05 +00:00
|
|
|
"math"
|
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
|
|
|
|
2024-02-15 05:46:47 +00:00
|
|
|
"github.com/prysmaticlabs/prysm/v5/config/params"
|
|
|
|
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
|
|
|
"github.com/prysmaticlabs/prysm/v5/encoding/bytesutil"
|
|
|
|
"github.com/prysmaticlabs/prysm/v5/testing/assert"
|
|
|
|
"github.com/prysmaticlabs/prysm/v5/testing/require"
|
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'},
|
2023-01-26 14:40:12 +00:00
|
|
|
ShuffledIndices: []primitives.ValidatorIndex{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)
|
2020-07-16 19:34:08 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
assert.Equal(t, key(item.Seed), k)
|
2019-09-27 02:51:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestCommitteeKeyFn_InvalidObj(t *testing.T) {
|
|
|
|
_, err := committeeKeyFn("bad")
|
2020-07-16 19:34:08 +00:00
|
|
|
assert.Equal(t, ErrNotCommittee, err)
|
2019-09-27 02:51:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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{
|
2023-01-26 14:40:12 +00:00
|
|
|
ShuffledIndices: []primitives.ValidatorIndex{1, 2, 3, 4, 5, 6},
|
2019-12-16 18:14:21 +00:00
|
|
|
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
|
2023-01-26 14:40:12 +00:00
|
|
|
committeeIndex := primitives.CommitteeIndex(1)
|
2021-09-26 15:27:57 +00:00
|
|
|
indices, err := cache.Committee(context.Background(), slot, item.Seed, committeeIndex)
|
2020-07-16 19:34:08 +00:00
|
|
|
require.NoError(t, err)
|
2019-09-27 02:51:39 +00:00
|
|
|
if indices != nil {
|
|
|
|
t.Error("Expected committee not to exist in empty cache")
|
|
|
|
}
|
2022-05-31 00:38:37 +00:00
|
|
|
require.NoError(t, cache.AddCommitteeShuffledList(context.Background(), item))
|
2019-09-27 02:51:39 +00:00
|
|
|
|
2023-01-26 14:40:12 +00:00
|
|
|
wantedIndex := primitives.CommitteeIndex(0)
|
2021-09-26 15:27:57 +00:00
|
|
|
indices, err = cache.Committee(context.Background(), slot, item.Seed, wantedIndex)
|
2020-07-16 19:34:08 +00:00
|
|
|
require.NoError(t, err)
|
2019-11-11 22:03:44 +00:00
|
|
|
|
2021-02-18 20:11:20 +00:00
|
|
|
start, end := startEndIndices(item, uint64(wantedIndex))
|
2020-07-16 19:34:08 +00:00
|
|
|
assert.DeepEqual(t, item.ShuffledIndices[start:end], indices)
|
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
|
|
|
|
2023-01-26 14:40:12 +00:00
|
|
|
item := &Committees{Seed: [32]byte{'A'}, SortedIndices: []primitives.ValidatorIndex{1, 2, 3, 4, 5, 6}}
|
2021-09-26 15:27:57 +00:00
|
|
|
indices, err := cache.ActiveIndices(context.Background(), item.Seed)
|
2020-07-16 19:34:08 +00:00
|
|
|
require.NoError(t, err)
|
2019-12-16 18:14:21 +00:00
|
|
|
if indices != nil {
|
2020-07-16 19:34:08 +00:00
|
|
|
t.Error("Expected committee not to exist in empty cache")
|
2019-09-27 02:51:39 +00:00
|
|
|
}
|
|
|
|
|
2022-05-31 00:38:37 +00:00
|
|
|
require.NoError(t, cache.AddCommitteeShuffledList(context.Background(), item))
|
2019-09-27 02:51:39 +00:00
|
|
|
|
2021-09-26 15:27:57 +00:00
|
|
|
indices, err = cache.ActiveIndices(context.Background(), item.Seed)
|
2020-07-16 19:34:08 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
assert.DeepEqual(t, item.SortedIndices, indices)
|
2019-09-27 02:51:39 +00:00
|
|
|
}
|
|
|
|
|
2020-06-14 22:24:49 +00:00
|
|
|
func TestCommitteeCache_ActiveCount(t *testing.T) {
|
|
|
|
cache := NewCommitteesCache()
|
|
|
|
|
2023-01-26 14:40:12 +00:00
|
|
|
item := &Committees{Seed: [32]byte{'A'}, SortedIndices: []primitives.ValidatorIndex{1, 2, 3, 4, 5, 6}}
|
2021-09-26 15:27:57 +00:00
|
|
|
count, err := cache.ActiveIndicesCount(context.Background(), item.Seed)
|
2020-07-16 19:34:08 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
assert.Equal(t, 0, count, "Expected active count not to exist in empty cache")
|
2020-06-14 22:24:49 +00:00
|
|
|
|
2022-05-31 00:38:37 +00:00
|
|
|
require.NoError(t, cache.AddCommitteeShuffledList(context.Background(), item))
|
2020-06-14 22:24:49 +00:00
|
|
|
|
2021-09-26 15:27:57 +00:00
|
|
|
count, err = cache.ActiveIndicesCount(context.Background(), item.Seed)
|
2020-07-16 19:34:08 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
assert.Equal(t, len(item.SortedIndices), count)
|
2020-06-14 22:24:49 +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.
|
2020-08-17 03:17:46 +00:00
|
|
|
start := 100
|
|
|
|
end := 200
|
|
|
|
for i := start; i < end; i++ {
|
2019-12-16 18:14:21 +00:00
|
|
|
s := []byte(strconv.Itoa(i))
|
|
|
|
item := &Committees{Seed: bytesutil.ToBytes32(s)}
|
2022-05-31 00:38:37 +00:00
|
|
|
require.NoError(t, cache.AddCommitteeShuffledList(context.Background(), item))
|
2019-09-29 19:10:11 +00:00
|
|
|
}
|
|
|
|
|
2021-06-10 21:53:34 +00:00
|
|
|
k := cache.CommitteeCache.Keys()
|
2022-03-11 09:34:30 +00:00
|
|
|
assert.Equal(t, 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 {
|
2021-06-10 21:53:34 +00:00
|
|
|
return k[i].(string) < k[j].(string)
|
2019-12-16 18:14:21 +00:00
|
|
|
})
|
2022-05-19 04:38:04 +00:00
|
|
|
wanted := end - maxCommitteesCacheSize
|
2020-08-17 03:17:46 +00:00
|
|
|
s := bytesutil.ToBytes32([]byte(strconv.Itoa(wanted)))
|
2020-07-16 19:34:08 +00:00
|
|
|
assert.Equal(t, key(s), k[0], "incorrect key received for slot 190")
|
|
|
|
|
2019-12-16 18:14:21 +00:00
|
|
|
s = bytesutil.ToBytes32([]byte(strconv.Itoa(199)))
|
2020-07-16 19:34:08 +00:00
|
|
|
assert.Equal(t, key(s), k[len(k)-1], "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"))
|
2021-06-10 21:53:34 +00:00
|
|
|
comms := &Committees{
|
2020-03-19 04:41:05 +00:00
|
|
|
CommitteeCount: 1,
|
|
|
|
Seed: seed,
|
2023-01-26 14:40:12 +00:00
|
|
|
ShuffledIndices: []primitives.ValidatorIndex{0},
|
|
|
|
SortedIndices: []primitives.ValidatorIndex{},
|
2021-06-10 21:53:34 +00:00
|
|
|
}
|
|
|
|
key, err := committeeKeyFn(comms)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
_ = cache.CommitteeCache.Add(key, comms)
|
2020-07-16 19:34:08 +00:00
|
|
|
|
2021-09-26 15:27:57 +00:00
|
|
|
_, err = cache.Committee(context.Background(), 0, seed, math.MaxUint64) // Overflow!
|
2020-07-16 19:34:08 +00:00
|
|
|
require.NotNil(t, err, "Did not fail as expected")
|
2020-03-19 04:41:05 +00:00
|
|
|
}
|
2022-05-31 00:38:37 +00:00
|
|
|
|
|
|
|
func TestCommitteeCache_DoesNothingWhenCancelledContext(t *testing.T) {
|
|
|
|
cache := NewCommitteesCache()
|
|
|
|
|
2023-01-26 14:40:12 +00:00
|
|
|
item := &Committees{Seed: [32]byte{'A'}, SortedIndices: []primitives.ValidatorIndex{1, 2, 3, 4, 5, 6}}
|
2022-05-31 00:38:37 +00:00
|
|
|
count, err := cache.ActiveIndicesCount(context.Background(), item.Seed)
|
|
|
|
require.NoError(t, err)
|
|
|
|
assert.Equal(t, 0, count, "Expected active count not to exist in empty cache")
|
|
|
|
|
|
|
|
cancelled, cancel := context.WithCancel(context.Background())
|
|
|
|
cancel()
|
|
|
|
require.ErrorIs(t, cache.AddCommitteeShuffledList(cancelled, item), context.Canceled)
|
|
|
|
|
|
|
|
count, err = cache.ActiveIndicesCount(context.Background(), item.Seed)
|
|
|
|
require.NoError(t, err)
|
|
|
|
assert.Equal(t, 0, count)
|
|
|
|
}
|