Skip to content

Commit

Permalink
Change To LRU from FIFO Cache (#8996)
Browse files Browse the repository at this point in the history
* change to lru

* fix tests

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
  • Loading branch information
nisdas and rauljordan authored Jun 10, 2021
1 parent 6eb0061 commit 7a6ce27
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 30 deletions.
40 changes: 17 additions & 23 deletions beacon-chain/cache/committee.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ import (
"errors"
"sync"

lru "github.com/hashicorp/golang-lru"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
types "github.com/prysmaticlabs/eth2-types"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/sliceutil"
"k8s.io/client-go/tools/cache"
)

var (
Expand All @@ -33,7 +33,7 @@ var (

// CommitteeCache is a struct with 1 queue for looking up shuffled indices list by seed.
type CommitteeCache struct {
CommitteeCache *cache.FIFO
CommitteeCache *lru.Cache
lock sync.RWMutex
}

Expand All @@ -43,14 +43,19 @@ func committeeKeyFn(obj interface{}) (string, error) {
if !ok {
return "", ErrNotCommittee
}

return key(info.Seed), nil
}

// NewCommitteesCache creates a new committee cache for storing/accessing shuffled indices of a committee.
func NewCommitteesCache() *CommitteeCache {
cCache, err := lru.New(int(maxCommitteesCacheSize))
// An error is only returned if the size of the cache is
// <= 0.
if err != nil {
panic(err)
}
return &CommitteeCache{
CommitteeCache: cache.NewFIFO(committeeKeyFn),
CommitteeCache: cCache,
}
}

Expand All @@ -60,11 +65,7 @@ func (c *CommitteeCache) Committee(slot types.Slot, seed [32]byte, index types.C
c.lock.RLock()
defer c.lock.RUnlock()

obj, exists, err := c.CommitteeCache.GetByKey(key(seed))
if err != nil {
return nil, err
}

obj, exists := c.CommitteeCache.Get(key(seed))
if exists {
CommitteeCacheHit.Inc()
} else {
Expand Down Expand Up @@ -97,22 +98,19 @@ func (c *CommitteeCache) Committee(slot types.Slot, seed [32]byte, index types.C
func (c *CommitteeCache) AddCommitteeShuffledList(committees *Committees) error {
c.lock.Lock()
defer c.lock.Unlock()

if err := c.CommitteeCache.AddIfNotPresent(committees); err != nil {
key, err := committeeKeyFn(committees)
if err != nil {
return err
}
trim(c.CommitteeCache, maxCommitteesCacheSize)
_ = c.CommitteeCache.Add(key, committees)
return nil
}

// ActiveIndices returns the active indices of a given seed stored in cache.
func (c *CommitteeCache) ActiveIndices(seed [32]byte) ([]types.ValidatorIndex, error) {
c.lock.RLock()
defer c.lock.RUnlock()
obj, exists, err := c.CommitteeCache.GetByKey(key(seed))
if err != nil {
return nil, err
}
obj, exists := c.CommitteeCache.Get(key(seed))

if exists {
CommitteeCacheHit.Inc()
Expand All @@ -133,11 +131,7 @@ func (c *CommitteeCache) ActiveIndices(seed [32]byte) ([]types.ValidatorIndex, e
func (c *CommitteeCache) ActiveIndicesCount(seed [32]byte) (int, error) {
c.lock.RLock()
defer c.lock.RUnlock()
obj, exists, err := c.CommitteeCache.GetByKey(key(seed))
if err != nil {
return 0, err
}

obj, exists := c.CommitteeCache.Get(key(seed))
if exists {
CommitteeCacheHit.Inc()
} else {
Expand All @@ -155,8 +149,8 @@ func (c *CommitteeCache) ActiveIndicesCount(seed [32]byte) (int, error) {

// HasEntry returns true if the committee cache has a value.
func (c *CommitteeCache) HasEntry(seed string) bool {
_, ok, err := c.CommitteeCache.GetByKey(seed)
return err == nil && ok
_, ok := c.CommitteeCache.Get(seed)
return ok
}

func startEndIndices(c *Committees, index uint64) (uint64, uint64) {
Expand Down
4 changes: 2 additions & 2 deletions beacon-chain/cache/committee_fuzz_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func TestCommitteeCache_FuzzCommitteesByEpoch(t *testing.T) {
require.NoError(t, err)
}

assert.Equal(t, maxCommitteesCacheSize, uint64(len(cache.CommitteeCache.ListKeys())), "Incorrect key size")
assert.Equal(t, maxCommitteesCacheSize, uint64(len(cache.CommitteeCache.Keys())), "Incorrect key size")
}

func TestCommitteeCache_FuzzActiveIndices(t *testing.T) {
Expand All @@ -49,5 +49,5 @@ func TestCommitteeCache_FuzzActiveIndices(t *testing.T) {
assert.DeepEqual(t, c.SortedIndices, indices)
}

assert.Equal(t, maxCommitteesCacheSize, uint64(len(cache.CommitteeCache.ListKeys())), "Incorrect key size")
assert.Equal(t, maxCommitteesCacheSize, uint64(len(cache.CommitteeCache.Keys())), "Incorrect key size")
}
12 changes: 7 additions & 5 deletions beacon-chain/cache/committee_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,11 +100,11 @@ func TestCommitteeCache_CanRotate(t *testing.T) {
require.NoError(t, cache.AddCommitteeShuffledList(item))
}

k := cache.CommitteeCache.ListKeys()
k := cache.CommitteeCache.Keys()
assert.Equal(t, maxCommitteesCacheSize, uint64(len(k)))

sort.Slice(k, func(i, j int) bool {
return k[i] < k[j]
return k[i].(string) < k[j].(string)
})
wanted := end - int(maxCommitteesCacheSize)
s := bytesutil.ToBytes32([]byte(strconv.Itoa(wanted)))
Expand All @@ -117,13 +117,15 @@ func TestCommitteeCache_CanRotate(t *testing.T) {
func TestCommitteeCacheOutOfRange(t *testing.T) {
cache := NewCommitteesCache()
seed := bytesutil.ToBytes32([]byte("foo"))
err := cache.CommitteeCache.Add(&Committees{
comms := &Committees{
CommitteeCount: 1,
Seed: seed,
ShuffledIndices: []types.ValidatorIndex{0},
SortedIndices: []types.ValidatorIndex{},
})
require.NoError(t, err)
}
key, err := committeeKeyFn(comms)
assert.NoError(t, err)
_ = cache.CommitteeCache.Add(key, comms)

_, err = cache.Committee(0, seed, math.MaxUint64) // Overflow!
require.NotNil(t, err, "Did not fail as expected")
Expand Down

0 comments on commit 7a6ce27

Please sign in to comment.