mirror of
https://gitlab.com/pulsechaincom/prysm-pulse.git
synced 2024-12-25 12:57:18 +00:00
Fix loading historical blocks to replay cold state (#6956)
* Replay: cold state only uses finalized blocks * Replay: regression test * Merge refs/heads/master into fix-finalized-replay
This commit is contained in:
parent
8b9138a76a
commit
537fe3f721
@ -116,6 +116,7 @@ func (s *State) LoadBlocks(ctx context.Context, startSlot uint64, endSlot uint64
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
blockRoots, err := s.beaconDB.BlockRoots(ctx, filter)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -327,20 +328,21 @@ func (s *State) processStateUpTo(ctx context.Context, state *state.BeaconState,
|
||||
if state.Slot() >= slot {
|
||||
return state, nil
|
||||
}
|
||||
|
||||
lastBlockRoot, lastBlockSlot, err := s.lastSavedBlock(ctx, slot)
|
||||
_, lastBlockSlot, err := s.lastSavedBlock(ctx, slot)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not get last saved block")
|
||||
}
|
||||
|
||||
// Short circuit if no block was saved, replay using slots only.
|
||||
if lastBlockSlot == 0 {
|
||||
return s.ReplayBlocks(ctx, state, []*ethpb.SignedBeaconBlock{}, slot)
|
||||
}
|
||||
|
||||
blks, err := s.LoadBlocks(ctx, state.Slot()+1, lastBlockSlot, lastBlockRoot)
|
||||
blks, err := s.loadFinalizedBlocks(ctx, state.Slot()+1, lastBlockSlot)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not load blocks")
|
||||
}
|
||||
|
||||
state, err = s.ReplayBlocks(ctx, state, blks, slot)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not replay blocks")
|
||||
@ -348,3 +350,27 @@ func (s *State) processStateUpTo(ctx context.Context, state *state.BeaconState,
|
||||
|
||||
return state, nil
|
||||
}
|
||||
|
||||
// Given the start slot and the end slot, this returns the finalized beacon blocks in between.
|
||||
// Since hot states don't have finalized blocks, this should ONLY be used for replaying cold state.
|
||||
func (s *State) loadFinalizedBlocks(ctx context.Context, startSlot uint64, endSlot uint64) ([]*ethpb.SignedBeaconBlock, error) {
|
||||
f := filters.NewFilter().SetStartSlot(startSlot).SetEndSlot(endSlot)
|
||||
bs, err := s.beaconDB.Blocks(ctx, f)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
bRoots, err := s.beaconDB.BlockRoots(ctx, f)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(bs) != len(bRoots) {
|
||||
return nil, errors.New("length of blocks and roots don't match")
|
||||
}
|
||||
fbs := make([]*ethpb.SignedBeaconBlock, 0, len(bs))
|
||||
for i := len(bs) - 1; i >= 0; i-- {
|
||||
if s.beaconDB.IsFinalizedBlock(ctx, bRoots[i]) {
|
||||
fbs = append(fbs, bs[i])
|
||||
}
|
||||
}
|
||||
return fbs, nil
|
||||
}
|
||||
|
@ -697,3 +697,26 @@ func tree4(db db.Database, genesisRoot []byte) ([][32]byte, []*ethpb.SignedBeaco
|
||||
|
||||
return [][32]byte{r0, r21, r22, r23, r24}, returnedBlocks, nil
|
||||
}
|
||||
|
||||
func TestLoadFinalizedBlocks(t *testing.T) {
|
||||
db, _ := testDB.SetupDB(t)
|
||||
ctx := context.Background()
|
||||
s := &State{
|
||||
beaconDB: db,
|
||||
}
|
||||
gBlock := ðpb.SignedBeaconBlock{}
|
||||
gRoot, err := stateutil.BlockRoot(gBlock.Block)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, db.SaveBlock(ctx, gBlock))
|
||||
roots, _, err := tree1(db, gRoot[:])
|
||||
require.NoError(t, err)
|
||||
|
||||
filteredBlocks, err := s.loadFinalizedBlocks(ctx, 0, 8)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 0, len(filteredBlocks))
|
||||
require.NoError(t, db.SaveStateSummary(ctx, &pb.StateSummary{Root: roots[8][:]}))
|
||||
|
||||
require.NoError(t, s.beaconDB.SaveFinalizedCheckpoint(ctx, ðpb.Checkpoint{Root: roots[8][:]}))
|
||||
filteredBlocks, err = s.loadFinalizedBlocks(ctx, 0, 8)
|
||||
require.Equal(t, 10, len(filteredBlocks))
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user