github.com/prysmaticlabs/prysm@v1.4.4/beacon-chain/state/stategen/getter_test.go (about)

     1  package stategen
     2  
     3  import (
     4  	"context"
     5  	"testing"
     6  
     7  	types "github.com/prysmaticlabs/eth2-types"
     8  	"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
     9  	testDB "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
    10  	pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
    11  	"github.com/prysmaticlabs/prysm/proto/eth/v1alpha1/wrapper"
    12  	"github.com/prysmaticlabs/prysm/shared/bytesutil"
    13  	"github.com/prysmaticlabs/prysm/shared/params"
    14  	"github.com/prysmaticlabs/prysm/shared/testutil"
    15  	"github.com/prysmaticlabs/prysm/shared/testutil/assert"
    16  	"github.com/prysmaticlabs/prysm/shared/testutil/require"
    17  )
    18  
    19  func TestStateByRoot_ColdState(t *testing.T) {
    20  	ctx := context.Background()
    21  	beaconDB := testDB.SetupDB(t)
    22  
    23  	service := New(beaconDB)
    24  	service.finalizedInfo.slot = 2
    25  	service.slotsPerArchivedPoint = 1
    26  
    27  	b := testutil.NewBeaconBlock()
    28  	b.Block.Slot = 1
    29  	require.NoError(t, beaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(b)))
    30  	bRoot, err := b.Block.HashTreeRoot()
    31  	require.NoError(t, err)
    32  	beaconState, _ := testutil.DeterministicGenesisState(t, 32)
    33  	require.NoError(t, beaconState.SetSlot(1))
    34  	require.NoError(t, service.beaconDB.SaveState(ctx, beaconState, bRoot))
    35  	require.NoError(t, service.beaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(b)))
    36  	require.NoError(t, service.beaconDB.SaveGenesisBlockRoot(ctx, bRoot))
    37  	loadedState, err := service.StateByRoot(ctx, bRoot)
    38  	require.NoError(t, err)
    39  	require.DeepSSZEqual(t, loadedState.InnerStateUnsafe(), beaconState.InnerStateUnsafe())
    40  }
    41  
    42  func TestStateByRoot_HotStateUsingEpochBoundaryCacheNoReplay(t *testing.T) {
    43  	ctx := context.Background()
    44  	beaconDB := testDB.SetupDB(t)
    45  
    46  	service := New(beaconDB)
    47  
    48  	beaconState, _ := testutil.DeterministicGenesisState(t, 32)
    49  	require.NoError(t, beaconState.SetSlot(10))
    50  	blk := testutil.NewBeaconBlock()
    51  	blkRoot, err := blk.Block.HashTreeRoot()
    52  	require.NoError(t, err)
    53  	require.NoError(t, service.beaconDB.SaveStateSummary(ctx, &pb.StateSummary{Root: blkRoot[:]}))
    54  	require.NoError(t, service.epochBoundaryStateCache.put(blkRoot, beaconState))
    55  	loadedState, err := service.StateByRoot(ctx, blkRoot)
    56  	require.NoError(t, err)
    57  	assert.Equal(t, types.Slot(10), loadedState.Slot(), "Did not correctly load state")
    58  }
    59  
    60  func TestStateByRoot_HotStateUsingEpochBoundaryCacheWithReplay(t *testing.T) {
    61  	ctx := context.Background()
    62  	beaconDB := testDB.SetupDB(t)
    63  
    64  	service := New(beaconDB)
    65  
    66  	beaconState, _ := testutil.DeterministicGenesisState(t, 32)
    67  	blk := testutil.NewBeaconBlock()
    68  	blkRoot, err := blk.Block.HashTreeRoot()
    69  	require.NoError(t, err)
    70  	require.NoError(t, service.epochBoundaryStateCache.put(blkRoot, beaconState))
    71  	targetSlot := types.Slot(10)
    72  	targetBlock := testutil.NewBeaconBlock()
    73  	targetBlock.Block.Slot = 11
    74  	targetBlock.Block.ParentRoot = blkRoot[:]
    75  	targetBlock.Block.ProposerIndex = 8
    76  	require.NoError(t, service.beaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(targetBlock)))
    77  	targetRoot, err := targetBlock.Block.HashTreeRoot()
    78  	require.NoError(t, err)
    79  	require.NoError(t, service.beaconDB.SaveStateSummary(ctx, &pb.StateSummary{Slot: targetSlot, Root: targetRoot[:]}))
    80  	loadedState, err := service.StateByRoot(ctx, targetRoot)
    81  	require.NoError(t, err)
    82  	assert.Equal(t, targetSlot, loadedState.Slot(), "Did not correctly load state")
    83  }
    84  
    85  func TestStateByRoot_HotStateCached(t *testing.T) {
    86  	ctx := context.Background()
    87  	beaconDB := testDB.SetupDB(t)
    88  
    89  	service := New(beaconDB)
    90  
    91  	beaconState, _ := testutil.DeterministicGenesisState(t, 32)
    92  	r := [32]byte{'A'}
    93  	require.NoError(t, service.beaconDB.SaveStateSummary(ctx, &pb.StateSummary{Root: r[:]}))
    94  	service.hotStateCache.put(r, beaconState)
    95  
    96  	loadedState, err := service.StateByRoot(ctx, r)
    97  	require.NoError(t, err)
    98  	require.DeepSSZEqual(t, loadedState.InnerStateUnsafe(), beaconState.InnerStateUnsafe())
    99  }
   100  
   101  func TestStateByRootInitialSync_UseEpochStateCache(t *testing.T) {
   102  	ctx := context.Background()
   103  	beaconDB := testDB.SetupDB(t)
   104  
   105  	service := New(beaconDB)
   106  
   107  	beaconState, _ := testutil.DeterministicGenesisState(t, 32)
   108  	targetSlot := types.Slot(10)
   109  	require.NoError(t, beaconState.SetSlot(targetSlot))
   110  	blk := testutil.NewBeaconBlock()
   111  	blkRoot, err := blk.Block.HashTreeRoot()
   112  	require.NoError(t, err)
   113  	require.NoError(t, service.epochBoundaryStateCache.put(blkRoot, beaconState))
   114  	loadedState, err := service.StateByRootInitialSync(ctx, blkRoot)
   115  	require.NoError(t, err)
   116  	assert.Equal(t, targetSlot, loadedState.Slot(), "Did not correctly load state")
   117  }
   118  
   119  func TestStateByRootInitialSync_UseCache(t *testing.T) {
   120  	ctx := context.Background()
   121  	beaconDB := testDB.SetupDB(t)
   122  
   123  	service := New(beaconDB)
   124  
   125  	beaconState, _ := testutil.DeterministicGenesisState(t, 32)
   126  	r := [32]byte{'A'}
   127  	require.NoError(t, service.beaconDB.SaveStateSummary(ctx, &pb.StateSummary{Root: r[:]}))
   128  	service.hotStateCache.put(r, beaconState)
   129  
   130  	loadedState, err := service.StateByRootInitialSync(ctx, r)
   131  	require.NoError(t, err)
   132  	require.DeepSSZEqual(t, loadedState.InnerStateUnsafe(), beaconState.InnerStateUnsafe())
   133  	if service.hotStateCache.has(r) {
   134  		t.Error("Hot state cache was not invalidated")
   135  	}
   136  }
   137  
   138  func TestStateByRootInitialSync_CanProcessUpTo(t *testing.T) {
   139  	ctx := context.Background()
   140  	beaconDB := testDB.SetupDB(t)
   141  	service := New(beaconDB)
   142  
   143  	beaconState, _ := testutil.DeterministicGenesisState(t, 32)
   144  	blk := testutil.NewBeaconBlock()
   145  	blkRoot, err := blk.Block.HashTreeRoot()
   146  	require.NoError(t, err)
   147  	require.NoError(t, service.epochBoundaryStateCache.put(blkRoot, beaconState))
   148  	targetSlot := types.Slot(10)
   149  	targetBlk := testutil.NewBeaconBlock()
   150  	targetBlk.Block.Slot = 11
   151  	targetBlk.Block.ParentRoot = blkRoot[:]
   152  	targetRoot, err := targetBlk.Block.HashTreeRoot()
   153  	require.NoError(t, err)
   154  	require.NoError(t, service.beaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(targetBlk)))
   155  	require.NoError(t, service.beaconDB.SaveStateSummary(ctx, &pb.StateSummary{Slot: targetSlot, Root: targetRoot[:]}))
   156  
   157  	loadedState, err := service.StateByRootInitialSync(ctx, targetRoot)
   158  	require.NoError(t, err)
   159  	assert.Equal(t, targetSlot, loadedState.Slot(), "Did not correctly load state")
   160  }
   161  
   162  func TestStateBySlot_ColdState(t *testing.T) {
   163  	ctx := context.Background()
   164  	beaconDB := testDB.SetupDB(t)
   165  
   166  	service := New(beaconDB)
   167  	service.slotsPerArchivedPoint = params.BeaconConfig().SlotsPerEpoch * 2
   168  	service.finalizedInfo.slot = service.slotsPerArchivedPoint + 1
   169  
   170  	beaconState, pks := testutil.DeterministicGenesisState(t, 32)
   171  	genesisStateRoot, err := beaconState.HashTreeRoot(ctx)
   172  	require.NoError(t, err)
   173  	genesis := blocks.NewGenesisBlock(genesisStateRoot[:])
   174  	assert.NoError(t, beaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(genesis)))
   175  	gRoot, err := genesis.Block.HashTreeRoot()
   176  	require.NoError(t, err)
   177  	assert.NoError(t, beaconDB.SaveState(ctx, beaconState, gRoot))
   178  	assert.NoError(t, beaconDB.SaveGenesisBlockRoot(ctx, gRoot))
   179  
   180  	b, err := testutil.GenerateFullBlock(beaconState, pks, testutil.DefaultBlockGenConfig(), 1)
   181  	require.NoError(t, err)
   182  	require.NoError(t, beaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(b)))
   183  	bRoot, err := b.Block.HashTreeRoot()
   184  	require.NoError(t, err)
   185  	require.NoError(t, beaconDB.SaveState(ctx, beaconState, bRoot))
   186  	require.NoError(t, beaconDB.SaveGenesisBlockRoot(ctx, bRoot))
   187  
   188  	r := [32]byte{}
   189  	require.NoError(t, service.beaconDB.SaveStateSummary(ctx, &pb.StateSummary{Slot: service.slotsPerArchivedPoint, Root: r[:]}))
   190  
   191  	slot := types.Slot(20)
   192  	loadedState, err := service.StateBySlot(ctx, slot)
   193  	require.NoError(t, err)
   194  	assert.Equal(t, slot, loadedState.Slot(), "Did not correctly save state")
   195  }
   196  
   197  func TestStateBySlot_HotStateDB(t *testing.T) {
   198  	ctx := context.Background()
   199  	beaconDB := testDB.SetupDB(t)
   200  
   201  	service := New(beaconDB)
   202  
   203  	beaconState, _ := testutil.DeterministicGenesisState(t, 32)
   204  	genesisStateRoot, err := beaconState.HashTreeRoot(ctx)
   205  	require.NoError(t, err)
   206  	genesis := blocks.NewGenesisBlock(genesisStateRoot[:])
   207  	assert.NoError(t, beaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(genesis)))
   208  	gRoot, err := genesis.Block.HashTreeRoot()
   209  	require.NoError(t, err)
   210  	assert.NoError(t, beaconDB.SaveState(ctx, beaconState, gRoot))
   211  	assert.NoError(t, beaconDB.SaveGenesisBlockRoot(ctx, gRoot))
   212  
   213  	slot := types.Slot(10)
   214  	loadedState, err := service.StateBySlot(ctx, slot)
   215  	require.NoError(t, err)
   216  	assert.Equal(t, slot, loadedState.Slot(), "Did not correctly load state")
   217  }
   218  
   219  func TestLoadeStateByRoot_Cached(t *testing.T) {
   220  	ctx := context.Background()
   221  	beaconDB := testDB.SetupDB(t)
   222  	service := New(beaconDB)
   223  
   224  	beaconState, _ := testutil.DeterministicGenesisState(t, 32)
   225  	r := [32]byte{'A'}
   226  	service.hotStateCache.put(r, beaconState)
   227  
   228  	// This tests where hot state was already cached.
   229  	loadedState, err := service.loadStateByRoot(ctx, r)
   230  	require.NoError(t, err)
   231  	require.DeepSSZEqual(t, loadedState.InnerStateUnsafe(), beaconState.InnerStateUnsafe())
   232  }
   233  
   234  func TestLoadeStateByRoot_FinalizedState(t *testing.T) {
   235  	ctx := context.Background()
   236  	beaconDB := testDB.SetupDB(t)
   237  	service := New(beaconDB)
   238  
   239  	beaconState, _ := testutil.DeterministicGenesisState(t, 32)
   240  	genesisStateRoot, err := beaconState.HashTreeRoot(ctx)
   241  	require.NoError(t, err)
   242  	genesis := blocks.NewGenesisBlock(genesisStateRoot[:])
   243  	assert.NoError(t, beaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(genesis)))
   244  	gRoot, err := genesis.Block.HashTreeRoot()
   245  	require.NoError(t, err)
   246  	require.NoError(t, service.beaconDB.SaveStateSummary(ctx, &pb.StateSummary{Slot: 0, Root: gRoot[:]}))
   247  
   248  	service.finalizedInfo.state = beaconState
   249  	service.finalizedInfo.slot = beaconState.Slot()
   250  	service.finalizedInfo.root = gRoot
   251  
   252  	// This tests where hot state was already cached.
   253  	loadedState, err := service.loadStateByRoot(ctx, gRoot)
   254  	require.NoError(t, err)
   255  	require.DeepSSZEqual(t, loadedState.InnerStateUnsafe(), beaconState.InnerStateUnsafe())
   256  }
   257  
   258  func TestLoadeStateByRoot_EpochBoundaryStateCanProcess(t *testing.T) {
   259  	ctx := context.Background()
   260  	beaconDB := testDB.SetupDB(t)
   261  	service := New(beaconDB)
   262  
   263  	beaconState, _ := testutil.DeterministicGenesisState(t, 32)
   264  	gBlk := testutil.NewBeaconBlock()
   265  	gBlkRoot, err := gBlk.Block.HashTreeRoot()
   266  	require.NoError(t, err)
   267  	require.NoError(t, service.epochBoundaryStateCache.put(gBlkRoot, beaconState))
   268  
   269  	blk := testutil.NewBeaconBlock()
   270  	blk.Block.Slot = 11
   271  	blk.Block.ProposerIndex = 8
   272  	blk.Block.ParentRoot = gBlkRoot[:]
   273  	require.NoError(t, service.beaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(blk)))
   274  	blkRoot, err := blk.Block.HashTreeRoot()
   275  	require.NoError(t, err)
   276  	require.NoError(t, service.beaconDB.SaveStateSummary(ctx, &pb.StateSummary{Slot: 10, Root: blkRoot[:]}))
   277  
   278  	// This tests where hot state was not cached and needs processing.
   279  	loadedState, err := service.loadStateByRoot(ctx, blkRoot)
   280  	require.NoError(t, err)
   281  	assert.Equal(t, types.Slot(10), loadedState.Slot(), "Did not correctly load state")
   282  }
   283  
   284  func TestLoadeStateByRoot_FromDBBoundaryCase(t *testing.T) {
   285  	ctx := context.Background()
   286  	beaconDB := testDB.SetupDB(t)
   287  	service := New(beaconDB)
   288  
   289  	beaconState, _ := testutil.DeterministicGenesisState(t, 32)
   290  	gBlk := testutil.NewBeaconBlock()
   291  	gBlkRoot, err := gBlk.Block.HashTreeRoot()
   292  	require.NoError(t, err)
   293  	require.NoError(t, service.epochBoundaryStateCache.put(gBlkRoot, beaconState))
   294  
   295  	blk := testutil.NewBeaconBlock()
   296  	blk.Block.Slot = 11
   297  	blk.Block.ProposerIndex = 8
   298  	blk.Block.ParentRoot = gBlkRoot[:]
   299  	require.NoError(t, service.beaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(blk)))
   300  	blkRoot, err := blk.Block.HashTreeRoot()
   301  	require.NoError(t, err)
   302  	require.NoError(t, service.beaconDB.SaveStateSummary(ctx, &pb.StateSummary{Slot: 10, Root: blkRoot[:]}))
   303  
   304  	// This tests where hot state was not cached and needs processing.
   305  	loadedState, err := service.loadStateByRoot(ctx, blkRoot)
   306  	require.NoError(t, err)
   307  	assert.Equal(t, types.Slot(10), loadedState.Slot(), "Did not correctly load state")
   308  }
   309  
   310  func TestLoadeStateBySlot_CanAdvanceSlotUsingDB(t *testing.T) {
   311  	ctx := context.Background()
   312  	beaconDB := testDB.SetupDB(t)
   313  	service := New(beaconDB)
   314  	beaconState, _ := testutil.DeterministicGenesisState(t, 32)
   315  	b := testutil.NewBeaconBlock()
   316  	require.NoError(t, service.beaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(b)))
   317  	gRoot, err := b.Block.HashTreeRoot()
   318  	require.NoError(t, err)
   319  	require.NoError(t, service.beaconDB.SaveGenesisBlockRoot(ctx, gRoot))
   320  	require.NoError(t, service.beaconDB.SaveState(ctx, beaconState, gRoot))
   321  
   322  	slot := types.Slot(10)
   323  	loadedState, err := service.loadStateBySlot(ctx, slot)
   324  	require.NoError(t, err)
   325  	assert.Equal(t, slot, loadedState.Slot(), "Did not correctly load state")
   326  }
   327  
   328  func TestLoadeStateBySlot_CanReplayBlock(t *testing.T) {
   329  	ctx := context.Background()
   330  	beaconDB := testDB.SetupDB(t)
   331  	service := New(beaconDB)
   332  	genesis, keys := testutil.DeterministicGenesisState(t, 64)
   333  	genesisBlockRoot := bytesutil.ToBytes32(nil)
   334  	require.NoError(t, beaconDB.SaveState(ctx, genesis, genesisBlockRoot))
   335  	stateRoot, err := genesis.HashTreeRoot(ctx)
   336  	require.NoError(t, err)
   337  	genesisBlk := blocks.NewGenesisBlock(stateRoot[:])
   338  	require.NoError(t, beaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(genesisBlk)))
   339  	genesisBlkRoot, err := genesisBlk.Block.HashTreeRoot()
   340  	require.NoError(t, err)
   341  	require.NoError(t, beaconDB.SaveGenesisBlockRoot(ctx, genesisBlkRoot))
   342  
   343  	b1, err := testutil.GenerateFullBlock(genesis, keys, testutil.DefaultBlockGenConfig(), 1)
   344  	assert.NoError(t, err)
   345  	require.NoError(t, beaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(b1)))
   346  	r1, err := b1.Block.HashTreeRoot()
   347  	require.NoError(t, err)
   348  	require.NoError(t, service.beaconDB.SaveStateSummary(ctx, &pb.StateSummary{Slot: 1, Root: r1[:]}))
   349  	service.hotStateCache.put(bytesutil.ToBytes32(b1.Block.ParentRoot), genesis)
   350  
   351  	loadedState, err := service.loadStateBySlot(ctx, 2)
   352  	require.NoError(t, err)
   353  	assert.Equal(t, types.Slot(2), loadedState.Slot(), "Did not correctly load state")
   354  }
   355  
   356  func TestLastAncestorState_CanGetUsingDB(t *testing.T) {
   357  	ctx := context.Background()
   358  	beaconDB := testDB.SetupDB(t)
   359  	service := New(beaconDB)
   360  
   361  	b0 := testutil.NewBeaconBlock()
   362  	b0.Block.ParentRoot = bytesutil.PadTo([]byte{'a'}, 32)
   363  	r0, err := b0.Block.HashTreeRoot()
   364  	require.NoError(t, err)
   365  	b1 := testutil.NewBeaconBlock()
   366  	b1.Block.Slot = 1
   367  	b1.Block.ParentRoot = bytesutil.PadTo(r0[:], 32)
   368  	r1, err := b1.Block.HashTreeRoot()
   369  	require.NoError(t, err)
   370  	b2 := testutil.NewBeaconBlock()
   371  	b2.Block.Slot = 2
   372  	b2.Block.ParentRoot = bytesutil.PadTo(r1[:], 32)
   373  	r2, err := b2.Block.HashTreeRoot()
   374  	require.NoError(t, err)
   375  	b3 := testutil.NewBeaconBlock()
   376  	b3.Block.Slot = 3
   377  	b3.Block.ParentRoot = bytesutil.PadTo(r2[:], 32)
   378  	r3, err := b3.Block.HashTreeRoot()
   379  	require.NoError(t, err)
   380  
   381  	b1State, err := testutil.NewBeaconState()
   382  	require.NoError(t, err)
   383  	require.NoError(t, b1State.SetSlot(1))
   384  
   385  	require.NoError(t, service.beaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(b0)))
   386  	require.NoError(t, service.beaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(b1)))
   387  	require.NoError(t, service.beaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(b2)))
   388  	require.NoError(t, service.beaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(b3)))
   389  	require.NoError(t, service.beaconDB.SaveState(ctx, b1State, r1))
   390  
   391  	lastState, err := service.lastAncestorState(ctx, r3)
   392  	require.NoError(t, err)
   393  	assert.Equal(t, b1State.Slot(), lastState.Slot(), "Did not get wanted state")
   394  }
   395  
   396  func TestLastAncestorState_CanGetUsingCache(t *testing.T) {
   397  	ctx := context.Background()
   398  	beaconDB := testDB.SetupDB(t)
   399  	service := New(beaconDB)
   400  
   401  	b0 := testutil.NewBeaconBlock()
   402  	b0.Block.ParentRoot = bytesutil.PadTo([]byte{'a'}, 32)
   403  	r0, err := b0.Block.HashTreeRoot()
   404  	require.NoError(t, err)
   405  	b1 := testutil.NewBeaconBlock()
   406  	b1.Block.Slot = 1
   407  	b1.Block.ParentRoot = bytesutil.PadTo(r0[:], 32)
   408  	r1, err := b1.Block.HashTreeRoot()
   409  	require.NoError(t, err)
   410  	b2 := testutil.NewBeaconBlock()
   411  	b2.Block.Slot = 2
   412  	b2.Block.ParentRoot = bytesutil.PadTo(r1[:], 32)
   413  	r2, err := b2.Block.HashTreeRoot()
   414  	require.NoError(t, err)
   415  	b3 := testutil.NewBeaconBlock()
   416  	b3.Block.Slot = 3
   417  	b3.Block.ParentRoot = bytesutil.PadTo(r2[:], 32)
   418  	r3, err := b3.Block.HashTreeRoot()
   419  	require.NoError(t, err)
   420  
   421  	b1State, err := testutil.NewBeaconState()
   422  	require.NoError(t, err)
   423  	require.NoError(t, b1State.SetSlot(1))
   424  
   425  	require.NoError(t, service.beaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(b0)))
   426  	require.NoError(t, service.beaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(b1)))
   427  	require.NoError(t, service.beaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(b2)))
   428  	require.NoError(t, service.beaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(b3)))
   429  	service.hotStateCache.put(r1, b1State)
   430  
   431  	lastState, err := service.lastAncestorState(ctx, r3)
   432  	require.NoError(t, err)
   433  	assert.Equal(t, b1State.Slot(), lastState.Slot(), "Did not get wanted state")
   434  }
   435  
   436  func TestState_HasState(t *testing.T) {
   437  	ctx := context.Background()
   438  	beaconDB := testDB.SetupDB(t)
   439  	service := New(beaconDB)
   440  	s, err := testutil.NewBeaconState()
   441  	require.NoError(t, err)
   442  	rHit1 := [32]byte{1}
   443  	rHit2 := [32]byte{2}
   444  	rMiss := [32]byte{3}
   445  	service.hotStateCache.put(rHit1, s)
   446  	require.NoError(t, service.epochBoundaryStateCache.put(rHit2, s))
   447  
   448  	b := testutil.NewBeaconBlock()
   449  	rHit3, err := b.Block.HashTreeRoot()
   450  	require.NoError(t, err)
   451  	require.NoError(t, service.beaconDB.SaveState(ctx, s, rHit3))
   452  	tt := []struct {
   453  		root [32]byte
   454  		want bool
   455  	}{
   456  		{rHit1, true},
   457  		{rHit2, true},
   458  		{rMiss, false},
   459  		{rHit3, true},
   460  	}
   461  	for _, tc := range tt {
   462  		got, err := service.HasState(ctx, tc.root)
   463  		require.NoError(t, err)
   464  		require.Equal(t, tc.want, got)
   465  	}
   466  }
   467  
   468  func TestState_HasStateInCache(t *testing.T) {
   469  	ctx := context.Background()
   470  	beaconDB := testDB.SetupDB(t)
   471  	service := New(beaconDB)
   472  	s, err := testutil.NewBeaconState()
   473  	require.NoError(t, err)
   474  	rHit1 := [32]byte{1}
   475  	rHit2 := [32]byte{2}
   476  	rMiss := [32]byte{3}
   477  	service.hotStateCache.put(rHit1, s)
   478  	require.NoError(t, service.epochBoundaryStateCache.put(rHit2, s))
   479  
   480  	tt := []struct {
   481  		root [32]byte
   482  		want bool
   483  	}{
   484  		{rHit1, true},
   485  		{rHit2, true},
   486  		{rMiss, false},
   487  	}
   488  	for _, tc := range tt {
   489  		got, err := service.HasStateInCache(ctx, tc.root)
   490  		require.NoError(t, err)
   491  		require.Equal(t, tc.want, got)
   492  	}
   493  }