mirror of
https://gitlab.com/pulsechaincom/prysm-pulse.git
synced 2025-01-16 06:58:20 +00:00
62 lines
1.9 KiB
Go
62 lines
1.9 KiB
Go
|
package stategen
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
|
||
|
"github.com/pkg/errors"
|
||
|
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
||
|
"github.com/prysmaticlabs/prysm/shared/bytesutil"
|
||
|
"go.opencensus.io/trace"
|
||
|
)
|
||
|
|
||
|
// This loads a post finalized beacon state from the hot section of the DB. If necessary it will
|
||
|
// replay blocks starting from the nearest epoch boundary. It returns the beacon state that
|
||
|
// corresponds to the input block root.
|
||
|
func (s *State) loadHotStateByRoot(ctx context.Context, blockRoot [32]byte) (*state.BeaconState, error) {
|
||
|
ctx, span := trace.StartSpan(ctx, "stateGen.loadHotStateByRoot")
|
||
|
defer span.End()
|
||
|
|
||
|
// Load the hot state cache.
|
||
|
cachedState := s.hotStateCache.Get(blockRoot)
|
||
|
if cachedState != nil {
|
||
|
return cachedState, nil
|
||
|
}
|
||
|
|
||
|
summary, err := s.beaconDB.StateSummary(ctx, blockRoot)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
if summary == nil {
|
||
|
return nil, errUnknownStateSummary
|
||
|
}
|
||
|
boundaryState, err := s.beaconDB.State(ctx, bytesutil.ToBytes32(summary.BoundaryRoot))
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
if boundaryState == nil {
|
||
|
return nil, errUnknownBoundaryState
|
||
|
}
|
||
|
|
||
|
// Don't need to replay the blocks if we're already on an epoch boundary,
|
||
|
// the target slot is the same as the state slot.
|
||
|
var hotState *state.BeaconState
|
||
|
targetSlot := summary.Slot
|
||
|
if targetSlot == boundaryState.Slot() {
|
||
|
hotState = boundaryState
|
||
|
} else {
|
||
|
blks, err := s.LoadBlocks(ctx, boundaryState.Slot()+1, targetSlot, bytesutil.ToBytes32(summary.Root))
|
||
|
if err != nil {
|
||
|
return nil, errors.Wrap(err, "could not load blocks for hot state using root")
|
||
|
}
|
||
|
hotState, err = s.ReplayBlocks(ctx, boundaryState, blks, targetSlot)
|
||
|
if err != nil {
|
||
|
return nil, errors.Wrap(err, "could not replay blocks for hot state using root")
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Save the copied state because the reference also returned in the end.
|
||
|
s.hotStateCache.Put(blockRoot, hotState.Copy())
|
||
|
|
||
|
return hotState, nil
|
||
|
}
|