Skip to content

Commit

Permalink
Caplin: keep reusing the same beacon state in ForkchoiceStore acros…
Browse files Browse the repository at this point in the history
…s reorgs (#12833)
  • Loading branch information
Giulio2002 authored Nov 22, 2024
1 parent 65a7f51 commit 7f8a584
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 9 deletions.
21 changes: 14 additions & 7 deletions cl/phase1/forkchoice/fork_graph/fork_graph_disk.go
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ func (f *forkGraphDisk) AddChainSegment(signedBlock *cltypes.SignedBeaconBlock,
return nil, BelowAnchor, nil
}

newState, err := f.GetState(block.ParentRoot, false)
newState, err := f.getState(block.ParentRoot, false, true)
if err != nil {
return nil, LogisticError, fmt.Errorf("AddChainSegment: %w, parentRoot; %x", err, block.ParentRoot)
}
Expand Down Expand Up @@ -249,7 +249,7 @@ func (f *forkGraphDisk) AddChainSegment(signedBlock *cltypes.SignedBeaconBlock,
// Add block to list of invalid blocks
log.Warn("Invalid beacon block", "slot", block.Slot, "blockRoot", blockRoot, "reason", invalidBlockErr)
f.badBlocks.Store(libcommon.Hash(blockRoot), struct{}{})
f.currentState = nil
//f.currentState = nil

return nil, InvalidBlock, invalidBlockErr
}
Expand Down Expand Up @@ -296,8 +296,8 @@ func (f *forkGraphDisk) AddChainSegment(signedBlock *cltypes.SignedBeaconBlock,
f.finalizedCheckpoints.Store(libcommon.Hash(blockRoot), newState.FinalizedCheckpoint())
if newState.Slot() > f.highestSeen {
f.highestSeen = newState.Slot()
f.currentState = newState
}
f.currentState = newState
return newState, Success, nil
}

Expand All @@ -317,8 +317,11 @@ func (f *forkGraphDisk) getBlock(blockRoot libcommon.Hash) (*cltypes.SignedBeaco

return obj.(*cltypes.SignedBeaconBlock), true
}

func (f *forkGraphDisk) GetState(blockRoot libcommon.Hash, alwaysCopy bool) (*state.CachingBeaconState, error) {
return f.getState(blockRoot, alwaysCopy, false)
}

func (f *forkGraphDisk) getState(blockRoot libcommon.Hash, alwaysCopy bool, addChainSegment bool) (*state.CachingBeaconState, error) {
if f.currentState != nil && !alwaysCopy {
currentStateBlockRoot, err := f.currentState.BlockRoot()
if err != nil {
Expand All @@ -333,16 +336,20 @@ func (f *forkGraphDisk) GetState(blockRoot libcommon.Hash, alwaysCopy bool) (*st
blocksInTheWay := []*cltypes.SignedBeaconBlock{}
// Use the parent root as a reverse iterator.
currentIteratorRoot := blockRoot
var copyReferencedState *state.CachingBeaconState
var copyReferencedState, outState *state.CachingBeaconState
var err error
if addChainSegment {
outState = f.currentState
}

// try and find the point of recconection
for copyReferencedState == nil {
block, isSegmentPresent := f.getBlock(currentIteratorRoot)
if !isSegmentPresent {
// check if it is in the header
bHeader, ok := f.GetHeader(currentIteratorRoot)
if ok && bHeader.Slot%dumpSlotFrequency == 0 {
copyReferencedState, err = f.readBeaconStateFromDisk(currentIteratorRoot)
copyReferencedState, err = f.readBeaconStateFromDisk(currentIteratorRoot, outState)
if err != nil {
log.Trace("Could not retrieve state: Missing header", "missing", currentIteratorRoot, "err", err)
copyReferencedState = nil
Expand All @@ -353,7 +360,7 @@ func (f *forkGraphDisk) GetState(blockRoot libcommon.Hash, alwaysCopy bool) (*st
return nil, nil
}
if block.Block.Slot%dumpSlotFrequency == 0 {
copyReferencedState, err = f.readBeaconStateFromDisk(currentIteratorRoot)
copyReferencedState, err = f.readBeaconStateFromDisk(currentIteratorRoot, outState)
if err != nil {
log.Trace("Could not retrieve state: Missing header", "missing", currentIteratorRoot, "err", err)
}
Expand Down
8 changes: 6 additions & 2 deletions cl/phase1/forkchoice/fork_graph/fork_graph_disk_fs.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ func getBeaconStateCacheFilename(blockRoot libcommon.Hash) string {
return fmt.Sprintf("%x.cache", blockRoot)
}

func (f *forkGraphDisk) readBeaconStateFromDisk(blockRoot libcommon.Hash) (bs *state.CachingBeaconState, err error) {
func (f *forkGraphDisk) readBeaconStateFromDisk(blockRoot libcommon.Hash, out *state.CachingBeaconState) (bs *state.CachingBeaconState, err error) {
var file afero.File
f.stateDumpLock.Lock()
defer f.stateDumpLock.Unlock()
Expand Down Expand Up @@ -77,7 +77,11 @@ func (f *forkGraphDisk) readBeaconStateFromDisk(blockRoot libcommon.Hash) (bs *s
return nil, fmt.Errorf("failed to read snappy buffer: %w, root: %x", err, blockRoot)
}
f.sszBuffer = f.sszBuffer[:n]
bs = state.New(f.beaconCfg)
if out == nil {
bs = state.New(f.beaconCfg)
} else {
bs = out
}

if err = bs.DecodeSSZ(f.sszBuffer, int(v[0])); err != nil {
return nil, fmt.Errorf("failed to decode beacon state: %w, root: %x, len: %d, decLen: %d, bs: %+v", err, blockRoot, n, len(f.sszBuffer), bs)
Expand Down

0 comments on commit 7f8a584

Please sign in to comment.