### Question:
FinalizedStateCache { public Optional<BeaconState> getFinalizedState(final UInt64 slot) { try { return Optional.of(stateCache.getUnchecked(slot)); } catch (final UncheckedExecutionException e) { if (Throwables.getRootCause(e) instanceof StateUnavailableException) { return Optional.empty(); } throw new RuntimeException("Error while regenerating state", e); } } FinalizedStateCache(
      final Database database, final int maximumCacheSize, final boolean useSoftReferences); Optional<BeaconState> getFinalizedState(final UInt64 slot);  }### Answer:
@Test void shouldUseCachedStateWhenAvailable() throws Exception { final BeaconState state = chainBuilder.generateBlockAtSlot(ONE).getState(); when(database.getLatestAvailableFinalizedState(state.getSlot())).thenReturn(Optional.of(state)); final Optional<BeaconState> initialResult = cache.getFinalizedState(state.getSlot()); assertThat(initialResult).contains(state); assertThat(cache.getFinalizedState(state.getSlot())).contains(state); verify(database, times(1)).getLatestAvailableFinalizedState(state.getSlot()); verifyNoMoreInteractions(database); }
@Test void shouldRegenerateFromMoreRecentCachedState() throws Exception { final UInt64 databaseSlot = UInt64.valueOf(1); final UInt64 cachedSlot = UInt64.valueOf(2); final UInt64 requestedSlot = UInt64.valueOf(3); chainBuilder.generateBlocksUpToSlot(requestedSlot); when(database.getLatestAvailableFinalizedState(any())) .thenReturn(Optional.of(chainBuilder.getStateAtSlot(databaseSlot))); allowStreamingBlocks(); assertThat(cache.getFinalizedState(cachedSlot)) .contains(chainBuilder.getStateAtSlot(cachedSlot)); verify(database).streamFinalizedBlocks(databaseSlot.plus(ONE), cachedSlot); assertThat(cache.getFinalizedState(requestedSlot)) .contains(chainBuilder.getStateAtSlot(requestedSlot)); verify(database).streamFinalizedBlocks(cachedSlot.plus(ONE), requestedSlot); }
@Test void shouldLimitNumberOfCachedStates() throws Exception { chainBuilder.generateBlocksUpToSlot(MAXIMUM_CACHE_SIZE + 1); when(database.getLatestAvailableFinalizedState(any())) .thenReturn(Optional.of(chainBuilder.getGenesis().getState())); allowStreamingBlocks(); for (int i = 1; i <= MAXIMUM_CACHE_SIZE; i++) { cache.getFinalizedState(UInt64.valueOf(i)); } cache.getFinalizedState(UInt64.valueOf(MAXIMUM_CACHE_SIZE + 1)); cache.getFinalizedState(ONE); verify(database, times(2)).streamFinalizedBlocks(ONE, ONE); }
@Test void shouldReturnEmptyWhenStateIsNotAvailable() { when(database.getLatestAvailableFinalizedState(any())).thenReturn(Optional.empty()); assertThat(cache.getFinalizedState(ONE)).isEmpty(); }