erigon-pulse/cl/beacon/synced_data/synced_data.go
2024-01-06 21:49:23 +01:00

82 lines
1.7 KiB
Go

package synced_data
import (
"sync"
"github.com/ledgerwatch/erigon/cl/clparams"
"github.com/ledgerwatch/erigon/cl/phase1/core/state"
"github.com/ledgerwatch/erigon/cl/utils"
"github.com/ledgerwatch/log/v3"
)
type SyncedDataManager struct {
enabled bool
cfg *clparams.BeaconChainConfig
headState *state.CachingBeaconState
mu sync.RWMutex
}
func NewSyncedDataManager(enabled bool, cfg *clparams.BeaconChainConfig) *SyncedDataManager {
return &SyncedDataManager{
enabled: enabled,
cfg: cfg,
}
}
func (s *SyncedDataManager) OnHeadState(newState *state.CachingBeaconState) (err error) {
if !s.enabled {
return
}
s.mu.Lock()
defer s.mu.Unlock()
if s.headState == nil {
s.headState, err = newState.Copy()
if err != nil {
return err
}
}
err = newState.CopyInto(s.headState)
if err != nil {
log.Error("failed to copy head state", "err", err)
}
return
}
func (s *SyncedDataManager) HeadState() (state *state.CachingBeaconState, cancel func()) {
if !s.enabled {
return nil, func() {}
}
s.mu.RLock()
return s.headState, s.mu.RUnlock
}
func (s *SyncedDataManager) Syncing() bool {
if !s.enabled {
return false
}
s.mu.RLock()
defer s.mu.RUnlock()
if s.headState == nil {
return true
}
headEpoch := utils.GetCurrentEpoch(s.headState.GenesisTime(), s.cfg.SecondsPerSlot, s.cfg.SlotsPerEpoch)
// surplusMargin, give it a go if we are within 2 epochs of the head
surplusMargin := s.cfg.SlotsPerEpoch * 2
return s.headState.Slot()+surplusMargin < headEpoch
}
func (s *SyncedDataManager) HeadSlot() uint64 {
if !s.enabled {
return 0
}
s.mu.RLock()
defer s.mu.RUnlock()
if s.headState == nil {
return 0
}
return s.headState.Slot()
}