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 }