mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-08 21:08:10 -05:00
Handle missing archived index (#5899)
* Make `archivedRoot` handle missing root case * Regression tests * Fixed existing tests * Removed debug log * Merge refs/heads/master into handle-missing-archived-index * Merge refs/heads/master into handle-missing-archived-index * More comments on the look back * Merge branch 'handle-missing-archived-index' of github.com:prysmaticlabs/prysm into handle-missing-archived-index * Merge refs/heads/master into handle-missing-archived-index
This commit is contained in:
@@ -63,7 +63,10 @@ func (s *State) loadColdStateBySlot(ctx context.Context, slot uint64) (*state.Be
|
||||
return nil, err
|
||||
}
|
||||
if archivedState == nil {
|
||||
archivedRoot := s.archivedRoot(ctx, slot)
|
||||
archivedRoot, err := s.archivedRoot(ctx, slot)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
archivedState, err = s.recoverStateByRoot(ctx, archivedRoot)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -83,6 +83,9 @@ func TestLoadColdStateByRoot_CanGet(t *testing.T) {
|
||||
if err := service.beaconDB.SaveGenesisBlockRoot(ctx, blkRoot); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if service.beaconDB.SaveBlock(ctx, blk) != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := service.beaconDB.SaveState(ctx, beaconState, blkRoot); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -121,6 +124,9 @@ func TestLoadColdStateBySlot_CanGet(t *testing.T) {
|
||||
if err := service.beaconDB.SaveGenesisBlockRoot(ctx, blkRoot); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if service.beaconDB.SaveBlock(ctx, blk) != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := service.beaconDB.SaveState(ctx, beaconState, blkRoot); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
@@ -41,6 +41,12 @@ func TestStateByRoot_ColdState(t *testing.T) {
|
||||
if err := service.beaconDB.SaveState(ctx, beaconState, bRoot); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := service.beaconDB.SaveBlock(ctx, b); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := service.beaconDB.SaveGenesisBlockRoot(ctx, bRoot); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
r := [32]byte{'a'}
|
||||
if err := service.beaconDB.SaveStateSummary(ctx, &pb.StateSummary{
|
||||
Root: r[:],
|
||||
|
||||
@@ -308,18 +308,38 @@ func (s *State) genesisRoot(ctx context.Context) ([32]byte, error) {
|
||||
return stateutil.BlockRoot(b.Block)
|
||||
}
|
||||
|
||||
// This retrieves the archived root in the DB.
|
||||
func (s *State) archivedRoot(ctx context.Context, slot uint64) [32]byte {
|
||||
// This returns the highest archived root based on input slot in the DB.
|
||||
// If the archived root is not available at that exact input slot due to an event of skip block,
|
||||
// this will look back and return the last available archived root (ie. the one with the highest slot below input slot).
|
||||
func (s *State) archivedRoot(ctx context.Context, slot uint64) ([32]byte, error) {
|
||||
archivedIndex := uint64(0)
|
||||
if slot/params.BeaconConfig().SlotsPerArchivedPoint > 1 {
|
||||
archivedIndex = slot/params.BeaconConfig().SlotsPerArchivedPoint - 1
|
||||
}
|
||||
return s.beaconDB.ArchivedPointRoot(ctx, archivedIndex)
|
||||
|
||||
for archivedIndex > 0 {
|
||||
if ctx.Err() != nil {
|
||||
return [32]byte{}, ctx.Err()
|
||||
}
|
||||
if s.beaconDB.HasArchivedPoint(ctx, archivedIndex) {
|
||||
return s.beaconDB.ArchivedPointRoot(ctx, archivedIndex), nil
|
||||
}
|
||||
archivedIndex--
|
||||
}
|
||||
|
||||
if archivedIndex == 0 {
|
||||
return s.genesisRoot(ctx)
|
||||
}
|
||||
|
||||
return [32]byte{}, errUnknownArchivedState
|
||||
}
|
||||
|
||||
// This retrieves the archived state in the DB.
|
||||
func (s *State) archivedState(ctx context.Context, slot uint64) (*state.BeaconState, error) {
|
||||
archivedRoot := s.archivedRoot(ctx, slot)
|
||||
archivedRoot, err := s.archivedRoot(ctx, slot)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return s.beaconDB.State(ctx, archivedRoot)
|
||||
}
|
||||
|
||||
|
||||
@@ -534,35 +534,85 @@ func TestLastSavedState_NoSavedBlockState(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestArchivedRoot_CanGet(t *testing.T) {
|
||||
func TestArchivedRoot_CanGetSpecificIndex(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
db := testDB.SetupDB(t)
|
||||
service := New(db, cache.NewStateSummaryCache())
|
||||
|
||||
r := [32]byte{'a'}
|
||||
if err := db.SaveArchivedPointRoot(ctx, r, 0); err != nil {
|
||||
if err := db.SaveArchivedPointRoot(ctx, r, 1); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
got, err := service.archivedRoot(ctx, params.BeaconConfig().SlotsPerArchivedPoint*2)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
got := service.archivedRoot(ctx, params.BeaconConfig().SlotsPerArchivedPoint)
|
||||
if r != got {
|
||||
t.Error("Did not get wanted root")
|
||||
}
|
||||
}
|
||||
|
||||
func TestArchivedState_CanGet(t *testing.T) {
|
||||
func TestArchivedRoot_CanGetOlderOlder(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
db := testDB.SetupDB(t)
|
||||
service := New(db, cache.NewStateSummaryCache())
|
||||
|
||||
r := [32]byte{'a'}
|
||||
if err := db.SaveArchivedPointRoot(ctx, r, 0); err != nil {
|
||||
if err := db.SaveArchivedPointRoot(ctx, r, 10); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
r = [32]byte{'b'}
|
||||
if err := db.SaveArchivedPointRoot(ctx, r, 11); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
got, err := service.archivedRoot(ctx, 100000)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if r != got {
|
||||
t.Error("Did not get wanted root")
|
||||
}
|
||||
}
|
||||
|
||||
func TestArchivedRoot_CanGetGenesisIndex(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
db := testDB.SetupDB(t)
|
||||
service := New(db, cache.NewStateSummaryCache())
|
||||
|
||||
gBlock := ðpb.SignedBeaconBlock{Block: ðpb.BeaconBlock{}}
|
||||
gRoot, err := stateutil.BlockRoot(gBlock.Block)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := db.SaveBlock(ctx, gBlock); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := db.SaveGenesisBlockRoot(ctx, gRoot); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
got, err := service.archivedRoot(ctx, 100000)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if gRoot != got {
|
||||
t.Error("Did not get wanted root")
|
||||
}
|
||||
}
|
||||
|
||||
func TestArchivedState_CanGetSpecificIndex(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
db := testDB.SetupDB(t)
|
||||
service := New(db, cache.NewStateSummaryCache())
|
||||
|
||||
r := [32]byte{'a'}
|
||||
if err := db.SaveArchivedPointRoot(ctx, r, 1); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
beaconState, _ := testutil.DeterministicGenesisState(t, 32)
|
||||
if err := db.SaveState(ctx, beaconState, r); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
got, err := service.archivedState(ctx, params.BeaconConfig().SlotsPerArchivedPoint)
|
||||
got, err := service.archivedState(ctx, params.BeaconConfig().SlotsPerArchivedPoint*2)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user