prysm-pulse/beacon-chain/state/stategen/migrate.go
terence tsao 7f7866ff2a
Micro optimizations on new-state-mgmt service for initial syncing (#5241)
* Starting a quick PoC

* Rate limit to one epoch worth of blocks in memory

* Proof of concept working

* Quick comment out

* Save previous finalized checkpoint

* Test

* Minor fixes

* More run time fixes

* Remove panic

* Feature flag

* Removed unused methods

* Fixed tests

* E2e test

* comment

* Compatible with current initial sync

* Starting

* New cache

* Cache getters and setters

* It should be part of state gen

* Need to use cache for DB

* Don't have to use finalized state

* Rm unused file

* some changes to memory mgmt when using mempool

* More run time fixes

* Can sync to head

* Feedback

* Revert "some changes to memory mgmt when using mempool"

This reverts commit f5b3e7ff4714fef9f0397007f519a45fa259ad24.

* Fixed sync tests

* Fixed existing tests

* Test for state summary getter

* Gaz

* Fix kafka passthrough

* Fixed inputs

* Gaz

* Fixed build

* Fixed visibility

* Trying without the ignore

* Didn't work..

* Fix kafka

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
2020-03-30 17:10:45 -05:00

100 lines
3.3 KiB
Go

package stategen
import (
"context"
"encoding/hex"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
"github.com/prysmaticlabs/prysm/beacon-chain/db/filters"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/sirupsen/logrus"
"go.opencensus.io/trace"
)
// MigrateToCold advances the split point in between the cold and hot state sections.
// It moves the recent finalized states from the hot section to the cold section and
// only preserve the ones that's on archived point.
func (s *State) MigrateToCold(ctx context.Context, finalizedSlot uint64, finalizedRoot [32]byte) error {
ctx, span := trace.StartSpan(ctx, "stateGen.MigrateToCold")
defer span.End()
// Verify migration is sensible. The new finalized point must increase the current split slot, and
// on an epoch boundary for hot state summary scheme to work.
currentSplitSlot := s.splitInfo.slot
if currentSplitSlot > finalizedSlot {
return nil
}
if !helpers.IsEpochStart(finalizedSlot) {
return nil
}
// Migrate all state summary objects from cache to DB.
if err := s.beaconDB.SaveStateSummaries(ctx, s.stateSummaryCache.GetAll()); err != nil {
return err
}
s.stateSummaryCache.Clear()
// Move the states between split slot to finalized slot from hot section to the cold section.
filter := filters.NewFilter().SetStartSlot(currentSplitSlot).SetEndSlot(finalizedSlot - 1)
blockRoots, err := s.beaconDB.BlockRoots(ctx, filter)
if err != nil {
return err
}
for _, r := range blockRoots {
stateSummary, err := s.beaconDB.StateSummary(ctx, r)
if err != nil {
return err
}
if stateSummary == nil || stateSummary.Slot == 0 {
continue
}
archivedPointIndex := stateSummary.Slot / s.slotsPerArchivedPoint
if stateSummary.Slot%s.slotsPerArchivedPoint == 0 {
if !s.beaconDB.HasState(ctx, r) {
recoveredArchivedState, err := s.ComputeStateUpToSlot(ctx, stateSummary.Slot)
if err != nil {
return err
}
if err := s.beaconDB.SaveState(ctx, recoveredArchivedState.Copy(), r); err != nil {
return err
}
}
if err := s.beaconDB.SaveArchivedPointRoot(ctx, r, archivedPointIndex); err != nil {
return err
}
if err := s.beaconDB.SaveLastArchivedIndex(ctx, archivedPointIndex); err != nil {
return err
}
log.WithFields(logrus.Fields{
"slot": stateSummary.Slot,
"archiveIndex": archivedPointIndex,
"root": hex.EncodeToString(bytesutil.Trunc(r[:])),
}).Info("Saved archived point during state migration")
} else {
// Do not delete the current finalized state in case user wants to
// switch back to old state service, deleting the recent finalized state
// could cause issue switching back.
if s.beaconDB.HasState(ctx, r) && r != finalizedRoot {
if err := s.beaconDB.DeleteState(ctx, r); err != nil {
return err
}
log.WithFields(logrus.Fields{
"slot": stateSummary.Slot,
"root": hex.EncodeToString(bytesutil.Trunc(r[:])),
}).Info("Deleted state during migration")
}
}
}
// Update the split slot and root.
s.splitInfo = &splitSlotAndRoot{slot: finalizedSlot, root: finalizedRoot}
log.WithFields(logrus.Fields{
"slot": s.splitInfo.slot,
"root": hex.EncodeToString(bytesutil.Trunc(s.splitInfo.root[:])),
}).Info("Set hot and cold state split point")
return nil
}