mirror of
https://gitlab.com/pulsechaincom/prysm-pulse.git
synced 2024-12-25 21:07:18 +00:00
110 lines
3.3 KiB
Go
110 lines
3.3 KiB
Go
package cache
|
|
|
|
import (
|
|
"errors"
|
|
"strconv"
|
|
"sync"
|
|
|
|
"github.com/prometheus/client_golang/prometheus"
|
|
"github.com/prometheus/client_golang/prometheus/promauto"
|
|
"github.com/prysmaticlabs/prysm/shared/featureconfig"
|
|
"github.com/prysmaticlabs/prysm/shared/params"
|
|
"k8s.io/client-go/tools/cache"
|
|
)
|
|
|
|
var (
|
|
// ErrNotTotalBalanceInfo will be returned when a cache object is not a pointer to
|
|
// a TotalBalanceByEpoch struct.
|
|
ErrNotTotalBalanceInfo = errors.New("object is not a total balance obj")
|
|
|
|
// maxTotalBalanceListSize defines the max number of total balance can cache.
|
|
maxTotalBalanceListSize = 1000
|
|
|
|
// Metrics.
|
|
totalBalanceCacheMiss = promauto.NewCounter(prometheus.CounterOpts{
|
|
Name: "total_balance_cache_miss",
|
|
Help: "The number of total balance requests that aren't present in the cache.",
|
|
})
|
|
totalBalanceCacheHit = promauto.NewCounter(prometheus.CounterOpts{
|
|
Name: "total_balance_cache_hit",
|
|
Help: "The number of total balance requests that are present in the cache.",
|
|
})
|
|
)
|
|
|
|
// TotalBalanceByEpoch defines the total validator balance per epoch.
|
|
type TotalBalanceByEpoch struct {
|
|
Epoch uint64
|
|
TotalBalance uint64
|
|
}
|
|
|
|
// TotalBalanceCache is a struct with 1 queue for looking up total balance by epoch.
|
|
type TotalBalanceCache struct {
|
|
totalBalanceCache *cache.FIFO
|
|
lock sync.RWMutex
|
|
}
|
|
|
|
// totalBalanceKeyFn takes the epoch as the key for the total balance of a given epoch.
|
|
func totalBalanceKeyFn(obj interface{}) (string, error) {
|
|
tInfo, ok := obj.(*TotalBalanceByEpoch)
|
|
if !ok {
|
|
return "", ErrNotTotalBalanceInfo
|
|
}
|
|
|
|
return strconv.Itoa(int(tInfo.Epoch)), nil
|
|
}
|
|
|
|
// NewTotalBalanceCache creates a new total balance cache for storing/accessing total validator balance.
|
|
func NewTotalBalanceCache() *TotalBalanceCache {
|
|
return &TotalBalanceCache{
|
|
totalBalanceCache: cache.NewFIFO(totalBalanceKeyFn),
|
|
}
|
|
}
|
|
|
|
// TotalBalanceInEpoch fetches TotalBalanceByEpoch by epoch. Returns true with a
|
|
// reference to the TotalBalanceInEpoch info, if exists. Otherwise returns false, nil.
|
|
func (c *TotalBalanceCache) TotalBalanceInEpoch(epoch uint64) (uint64, error) {
|
|
if !featureconfig.FeatureConfig().EnableTotalBalanceCache {
|
|
// Return a miss result if cache is not enabled.
|
|
totalBalanceCacheMiss.Inc()
|
|
return params.BeaconConfig().FarFutureEpoch, nil
|
|
}
|
|
|
|
c.lock.RLock()
|
|
defer c.lock.RUnlock()
|
|
obj, exists, err := c.totalBalanceCache.GetByKey(strconv.Itoa(int(epoch)))
|
|
if err != nil {
|
|
return params.BeaconConfig().FarFutureEpoch, err
|
|
}
|
|
|
|
if exists {
|
|
totalBalanceCacheHit.Inc()
|
|
} else {
|
|
totalBalanceCacheMiss.Inc()
|
|
return params.BeaconConfig().FarFutureEpoch, nil
|
|
}
|
|
|
|
tInfo, ok := obj.(*TotalBalanceByEpoch)
|
|
if !ok {
|
|
return params.BeaconConfig().FarFutureEpoch, ErrNotTotalBalanceInfo
|
|
}
|
|
|
|
return tInfo.TotalBalance, nil
|
|
}
|
|
|
|
// AddTotalBalance adds TotalBalanceByEpoch object to the cache. This method also trims the least
|
|
// recently added TotalBalanceByEpoch object if the cache size has ready the max cache size limit.
|
|
func (c *TotalBalanceCache) AddTotalBalance(totalBalance *TotalBalanceByEpoch) error {
|
|
if !featureconfig.FeatureConfig().EnableTotalBalanceCache {
|
|
return nil
|
|
}
|
|
|
|
c.lock.Lock()
|
|
defer c.lock.Unlock()
|
|
if err := c.totalBalanceCache.AddIfNotPresent(totalBalance); err != nil {
|
|
return err
|
|
}
|
|
|
|
trim(c.totalBalanceCache, maxTotalBalanceListSize)
|
|
return nil
|
|
}
|