2021-08-24 07:54:04 +00:00
|
|
|
package cache
|
|
|
|
|
|
|
|
import (
|
|
|
|
"sync"
|
|
|
|
|
|
|
|
lru "github.com/hashicorp/golang-lru"
|
|
|
|
types "github.com/prysmaticlabs/eth2-types"
|
|
|
|
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
2021-09-14 23:11:25 +00:00
|
|
|
lruwrpr "github.com/prysmaticlabs/prysm/cache/lru"
|
2022-02-02 17:51:24 +00:00
|
|
|
"github.com/prysmaticlabs/prysm/runtime/version"
|
2021-08-24 07:54:04 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
// SyncCommitteeHeadStateCache for the latest head state requested by a sync committee participant.
|
|
|
|
type SyncCommitteeHeadStateCache struct {
|
|
|
|
cache *lru.Cache
|
|
|
|
lock sync.RWMutex
|
|
|
|
}
|
|
|
|
|
|
|
|
// NewSyncCommitteeHeadState initializes a LRU cache for `SyncCommitteeHeadState` with size of 1.
|
2021-08-26 05:01:09 +00:00
|
|
|
func NewSyncCommitteeHeadState() *SyncCommitteeHeadStateCache {
|
2021-09-02 10:36:54 +00:00
|
|
|
c := lruwrpr.New(1) // only need size of 1 to avoid redundant state copies, hashing, and slot processing.
|
2021-08-26 05:01:09 +00:00
|
|
|
return &SyncCommitteeHeadStateCache{cache: c}
|
2021-08-24 07:54:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Put `slot` as key and `state` as value onto the cache.
|
2021-08-26 05:01:09 +00:00
|
|
|
func (c *SyncCommitteeHeadStateCache) Put(slot types.Slot, st state.BeaconState) error {
|
2021-08-24 07:54:04 +00:00
|
|
|
c.lock.Lock()
|
|
|
|
defer c.lock.Unlock()
|
2021-08-26 05:01:09 +00:00
|
|
|
// Make sure that the provided state is non nil
|
|
|
|
// and is of the correct type.
|
|
|
|
if st == nil || st.IsNil() {
|
|
|
|
return ErrNilValueProvided
|
|
|
|
}
|
2021-12-13 18:04:37 +00:00
|
|
|
|
2022-02-08 09:30:06 +00:00
|
|
|
if st.Version() == version.Phase0 {
|
2021-08-26 05:01:09 +00:00
|
|
|
return ErrIncorrectType
|
|
|
|
}
|
2021-12-13 18:04:37 +00:00
|
|
|
|
2021-08-24 07:54:04 +00:00
|
|
|
c.cache.Add(slot, st)
|
2021-08-26 05:01:09 +00:00
|
|
|
return nil
|
2021-08-24 07:54:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Get `state` using `slot` as key. Return nil if nothing is found.
|
|
|
|
func (c *SyncCommitteeHeadStateCache) Get(slot types.Slot) (state.BeaconState, error) {
|
|
|
|
c.lock.RLock()
|
|
|
|
defer c.lock.RUnlock()
|
|
|
|
val, exists := c.cache.Get(slot)
|
2021-08-26 05:01:09 +00:00
|
|
|
if !exists {
|
2021-08-24 07:54:04 +00:00
|
|
|
return nil, ErrNotFound
|
|
|
|
}
|
2022-02-02 17:51:24 +00:00
|
|
|
st, ok := val.(state.BeaconState)
|
2021-08-26 05:01:09 +00:00
|
|
|
if !ok {
|
2022-02-02 17:51:24 +00:00
|
|
|
return nil, ErrIncorrectType
|
|
|
|
}
|
|
|
|
switch st.Version() {
|
|
|
|
case version.Altair, version.Bellatrix:
|
|
|
|
default:
|
|
|
|
return nil, ErrIncorrectType
|
2021-08-26 05:01:09 +00:00
|
|
|
}
|
|
|
|
return st, nil
|
2021-08-24 07:54:04 +00:00
|
|
|
}
|