prysm-pulse/beacon-chain/state/stategen/setter.go
Raul Jordan d077483577
Add V3 Suffix to All Prysm Packages (#11083)
* v3 import renamings

* tidy

* fmt

* rev

* Update beacon-chain/core/epoch/precompute/reward_penalty_test.go

* Update beacon-chain/core/helpers/validators_test.go

* Update beacon-chain/db/alias.go

* Update beacon-chain/db/alias.go

* Update beacon-chain/db/alias.go

* Update beacon-chain/db/iface/BUILD.bazel

* Update beacon-chain/db/kv/kv.go

* Update beacon-chain/db/kv/state.go

* Update beacon-chain/rpc/prysm/v1alpha1/validator/attester_test.go

* Update beacon-chain/rpc/prysm/v1alpha1/validator/attester_test.go

* Update beacon-chain/sync/initial-sync/service.go

* fix deps

* fix bad replacements

* fix bad replacements

* change back

* gohashtree version

* fix deps

Co-authored-by: Nishant Das <nishdas93@gmail.com>
Co-authored-by: Potuz <potuz@prysmaticlabs.com>
2022-08-16 12:20:13 +00:00

138 lines
4.5 KiB
Go

package stategen
import (
"context"
"math"
"github.com/prysmaticlabs/prysm/v3/beacon-chain/state"
"github.com/prysmaticlabs/prysm/v3/config/params"
"github.com/prysmaticlabs/prysm/v3/encoding/bytesutil"
ethpb "github.com/prysmaticlabs/prysm/v3/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v3/time/slots"
"github.com/sirupsen/logrus"
"go.opencensus.io/trace"
)
// SaveState saves the state in the cache and/or DB.
func (s *State) SaveState(ctx context.Context, blockRoot [32]byte, st state.BeaconState) error {
ctx, span := trace.StartSpan(ctx, "stateGen.SaveState")
defer span.End()
return s.saveStateByRoot(ctx, blockRoot, st)
}
// ForceCheckpoint initiates a cold state save of the given block root's state. This method does not update the
// "last archived state" but simply saves the specified state from the root argument into the DB.
//
// The name "Checkpoint" isn't referring to checkpoint in the sense of our consensus type, but checkpoint for our historical states.
func (s *State) ForceCheckpoint(ctx context.Context, blockRoot []byte) error {
ctx, span := trace.StartSpan(ctx, "stateGen.ForceCheckpoint")
defer span.End()
root32 := bytesutil.ToBytes32(blockRoot)
// Before the first finalized checkpoint, the finalized root is zero hash.
// Return early if there hasn't been a finalized checkpoint.
if root32 == params.BeaconConfig().ZeroHash {
return nil
}
fs, err := s.loadStateByRoot(ctx, root32)
if err != nil {
return err
}
return s.beaconDB.SaveState(ctx, fs, root32)
}
// This saves a post beacon state. On the epoch boundary,
// it saves a full state. On an intermediate slot, it saves a back pointer to the
// nearest epoch boundary state.
func (s *State) saveStateByRoot(ctx context.Context, blockRoot [32]byte, st state.BeaconState) error {
ctx, span := trace.StartSpan(ctx, "stateGen.saveStateByRoot")
defer span.End()
// Duration can't be 0 to prevent panic for division.
duration := uint64(math.Max(float64(s.saveHotStateDB.duration), 1))
s.saveHotStateDB.lock.Lock()
if s.saveHotStateDB.enabled && st.Slot().Mod(duration) == 0 {
if err := s.beaconDB.SaveState(ctx, st, blockRoot); err != nil {
s.saveHotStateDB.lock.Unlock()
return err
}
s.saveHotStateDB.blockRootsOfSavedStates = append(s.saveHotStateDB.blockRootsOfSavedStates, blockRoot)
log.WithFields(logrus.Fields{
"slot": st.Slot(),
"totalHotStateSavedInDB": len(s.saveHotStateDB.blockRootsOfSavedStates),
}).Info("Saving hot state to DB")
}
s.saveHotStateDB.lock.Unlock()
// If the hot state is already in cache, one can be sure the state was processed and in the DB.
if s.hotStateCache.has(blockRoot) {
return nil
}
// Only on an epoch boundary slot, save epoch boundary state in epoch boundary root state cache.
if slots.IsEpochStart(st.Slot()) {
if err := s.epochBoundaryStateCache.put(blockRoot, st); err != nil {
return err
}
}
// On an intermediate slot, save state summary.
if err := s.beaconDB.SaveStateSummary(ctx, &ethpb.StateSummary{
Slot: st.Slot(),
Root: blockRoot[:],
}); err != nil {
return err
}
// Store the copied state in the hot state cache.
s.hotStateCache.put(blockRoot, st)
return nil
}
// EnableSaveHotStateToDB enters the mode that saves hot beacon state to the DB.
// This usually gets triggered when there's long duration since finality.
func (s *State) EnableSaveHotStateToDB(_ context.Context) {
s.saveHotStateDB.lock.Lock()
defer s.saveHotStateDB.lock.Unlock()
if s.saveHotStateDB.enabled {
return
}
s.saveHotStateDB.enabled = true
log.WithFields(logrus.Fields{
"enabled": s.saveHotStateDB.enabled,
"slotsInterval": s.saveHotStateDB.duration,
}).Warn("Entering mode to save hot states in DB")
}
// DisableSaveHotStateToDB exits the mode that saves beacon state to DB for the hot states.
// This usually gets triggered once there's finality after long duration since finality.
func (s *State) DisableSaveHotStateToDB(ctx context.Context) error {
s.saveHotStateDB.lock.Lock()
defer s.saveHotStateDB.lock.Unlock()
if !s.saveHotStateDB.enabled {
return nil
}
log.WithFields(logrus.Fields{
"enabled": s.saveHotStateDB.enabled,
"deletedHotStates": len(s.saveHotStateDB.blockRootsOfSavedStates),
}).Warn("Exiting mode to save hot states in DB")
// Delete previous saved states in DB as we are turning this mode off.
s.saveHotStateDB.enabled = false
if err := s.beaconDB.DeleteStates(ctx, s.saveHotStateDB.blockRootsOfSavedStates); err != nil {
return err
}
s.saveHotStateDB.blockRootsOfSavedStates = nil
return nil
}