prysm-pulse/slasher/cache/flat_span_cache.go
Victor Farazdagi a8e501b3cf
ETH2 Types: Epoch (#8373)
* update deps

* update deps

* update protos/*

* update deps

* reset protos

* update protos

* update shared/params/config

* update protos

* update /shared

* update shared/slotutil and shared/testutil

* update beacon-chain/core/helpers

* updates beacon-chain/state

* update beacon-chain/forkchoice

* update beacon-chain/blockchain

* update beacon-chain/cache

* update beacon-chain/core

* update beacon-chain/db

* update beacon-chain/node

* update beacon-chain/p2p

* update beacon-chain/rpc

* update beacon-chain/sync

* go mod tidy

* make sure that beacon-chain build suceeds

* go fmt

* update e2e tests

* update slasher

* remove redundant alias

* update validator

* gazelle

* fix build errors in unit tests

* go fmt

* update deps

* update fuzz/BUILD.bazel

* fix unit tests

* more unit test fixes

* fix blockchain UTs

* more unit test fixes
2021-02-09 10:05:22 +00:00

73 lines
2.2 KiB
Go

package cache
import (
lru "github.com/hashicorp/golang-lru"
"github.com/prysmaticlabs/eth2-types"
slashertypes "github.com/prysmaticlabs/prysm/slasher/detection/attestations/types"
)
// EpochFlatSpansCache is used to store the spans needed on a per-epoch basis for slashing detection.
type EpochFlatSpansCache struct {
cache *lru.Cache
}
// NewEpochFlatSpansCache initializes the underlying cache with the given size and on evict function.
func NewEpochFlatSpansCache(size int, onEvicted func(key interface{}, value interface{})) (*EpochFlatSpansCache, error) {
if size != 0 {
epochSpansCacheSize = size
}
cache, err := lru.NewWithEvict(epochSpansCacheSize, onEvicted)
if err != nil {
return nil, err
}
return &EpochFlatSpansCache{cache: cache}, nil
}
// Get returns an ok bool and the cached value for the requested epoch key, if any.
func (c *EpochFlatSpansCache) Get(epoch types.Epoch) (*slashertypes.EpochStore, bool) {
item, exists := c.cache.Get(epoch)
if exists && item != nil {
epochSpansCacheHit.Inc()
return item.(*slashertypes.EpochStore), true
}
epochSpansCacheMiss.Inc()
return &slashertypes.EpochStore{}, false
}
// Set the response in the cache.
func (c *EpochFlatSpansCache) Set(epoch types.Epoch, epochSpans *slashertypes.EpochStore) {
_ = c.cache.Add(epoch, epochSpans)
}
// Delete removes an epoch from the cache and returns if it existed or not.
// Performs the onEviction function before removal.
func (c *EpochFlatSpansCache) Delete(epoch types.Epoch) bool {
return c.cache.Remove(epoch)
}
// PruneOldest removes the oldest key from the span cache, calling its OnEvict function.
func (c *EpochFlatSpansCache) PruneOldest() uint64 {
if c.cache.Len() == epochSpansCacheSize {
epoch, _, _ := c.cache.RemoveOldest()
return epoch.(uint64)
}
return 0
}
// Has returns true if the key exists in the cache.
func (c *EpochFlatSpansCache) Has(epoch types.Epoch) bool {
return c.cache.Contains(epoch)
}
// Purge removes all keys from the SpanCache and evicts all current data.
func (c *EpochFlatSpansCache) Purge() {
log.Info("Saving all cached data to DB, please wait for completion.")
c.cache.Purge()
}
// Length returns the number of cached items.
func (c *EpochFlatSpansCache) Length() int {
return c.cache.Len()
}