github.com/prysmaticlabs/prysm@v1.4.4/beacon-chain/cache/proposer_indices.go (about) 1 // +build !libfuzzer 2 3 package cache 4 5 import ( 6 "sync" 7 8 "github.com/prometheus/client_golang/prometheus" 9 "github.com/prometheus/client_golang/prometheus/promauto" 10 types "github.com/prysmaticlabs/eth2-types" 11 "k8s.io/client-go/tools/cache" 12 ) 13 14 var ( 15 // maxProposerIndicesCacheSize defines the max number of proposer indices on per block root basis can cache. 16 // Due to reorgs and long finality, it's good to keep the old cache around for quickly switch over. 17 maxProposerIndicesCacheSize = uint64(8) 18 19 // ProposerIndicesCacheMiss tracks the number of proposerIndices requests that aren't present in the cache. 20 ProposerIndicesCacheMiss = promauto.NewCounter(prometheus.CounterOpts{ 21 Name: "proposer_indices_cache_miss", 22 Help: "The number of proposer indices requests that aren't present in the cache.", 23 }) 24 // ProposerIndicesCacheHit tracks the number of proposerIndices requests that are in the cache. 25 ProposerIndicesCacheHit = promauto.NewCounter(prometheus.CounterOpts{ 26 Name: "proposer_indices_cache_hit", 27 Help: "The number of proposer indices requests that are present in the cache.", 28 }) 29 ) 30 31 // ProposerIndicesCache is a struct with 1 queue for looking up proposer indices by root. 32 type ProposerIndicesCache struct { 33 ProposerIndicesCache *cache.FIFO 34 lock sync.RWMutex 35 } 36 37 // proposerIndicesKeyFn takes the block root as the key to retrieve proposer indices in a given epoch. 38 func proposerIndicesKeyFn(obj interface{}) (string, error) { 39 info, ok := obj.(*ProposerIndices) 40 if !ok { 41 return "", ErrNotProposerIndices 42 } 43 44 return key(info.BlockRoot), nil 45 } 46 47 // NewProposerIndicesCache creates a new proposer indices cache for storing/accessing proposer index assignments of an epoch. 48 func NewProposerIndicesCache() *ProposerIndicesCache { 49 return &ProposerIndicesCache{ 50 ProposerIndicesCache: cache.NewFIFO(proposerIndicesKeyFn), 51 } 52 } 53 54 // AddProposerIndices adds ProposerIndices object to the cache. 55 // This method also trims the least recently list if the cache size has ready the max cache size limit. 56 func (c *ProposerIndicesCache) AddProposerIndices(p *ProposerIndices) error { 57 c.lock.Lock() 58 defer c.lock.Unlock() 59 60 if err := c.ProposerIndicesCache.AddIfNotPresent(p); err != nil { 61 return err 62 } 63 trim(c.ProposerIndicesCache, maxProposerIndicesCacheSize) 64 return nil 65 } 66 67 // HasProposerIndices returns the proposer indices of a block root seed. 68 func (c *ProposerIndicesCache) HasProposerIndices(r [32]byte) (bool, error) { 69 c.lock.RLock() 70 defer c.lock.RUnlock() 71 _, exists, err := c.ProposerIndicesCache.GetByKey(key(r)) 72 if err != nil { 73 return false, err 74 } 75 return exists, nil 76 } 77 78 // ProposerIndices returns the proposer indices of a block root seed. 79 func (c *ProposerIndicesCache) ProposerIndices(r [32]byte) ([]types.ValidatorIndex, error) { 80 c.lock.RLock() 81 defer c.lock.RUnlock() 82 obj, exists, err := c.ProposerIndicesCache.GetByKey(key(r)) 83 if err != nil { 84 return nil, err 85 } 86 87 if exists { 88 ProposerIndicesCacheHit.Inc() 89 } else { 90 ProposerIndicesCacheMiss.Inc() 91 return nil, nil 92 } 93 94 item, ok := obj.(*ProposerIndices) 95 if !ok { 96 return nil, ErrNotProposerIndices 97 } 98 99 return item.ProposerIndices, nil 100 }