use of org.hyperledger.besu.ethereum.eth.sync.worldstate.StalledDownloadException in project besu by hyperledger.
the class FastSyncDownloaderTest method shouldResetFastSyncStateAndRestartProcessIfWorldStateIsUnavailable.
@SuppressWarnings("unchecked")
@Test
public void shouldResetFastSyncStateAndRestartProcessIfWorldStateIsUnavailable() {
final CompletableFuture<Void> firstWorldStateFuture = new CompletableFuture<>();
final CompletableFuture<Void> secondWorldStateFuture = new CompletableFuture<>();
final CompletableFuture<Void> chainFuture = new CompletableFuture<>();
final ChainDownloader secondChainDownloader = mock(ChainDownloader.class);
final FastSyncState selectPivotBlockState = new FastSyncState(50);
final FastSyncState secondSelectPivotBlockState = new FastSyncState(90);
final BlockHeader pivotBlockHeader = new BlockHeaderTestFixture().number(50).buildHeader();
final BlockHeader secondPivotBlockHeader = new BlockHeaderTestFixture().number(90).buildHeader();
final FastSyncState downloadPivotBlockHeaderState = new FastSyncState(pivotBlockHeader);
final FastSyncState secondDownloadPivotBlockHeaderState = new FastSyncState(secondPivotBlockHeader);
// First attempt
when(fastSyncActions.waitForSuitablePeers(FastSyncState.EMPTY_SYNC_STATE)).thenReturn(COMPLETE);
when(fastSyncActions.selectPivotBlock(FastSyncState.EMPTY_SYNC_STATE)).thenReturn(completedFuture(selectPivotBlockState), completedFuture(secondSelectPivotBlockState));
when(fastSyncActions.downloadPivotBlockHeader(selectPivotBlockState)).thenReturn(completedFuture(downloadPivotBlockHeaderState));
when(fastSyncActions.createChainDownloader(downloadPivotBlockHeaderState)).thenReturn(chainDownloader);
when(chainDownloader.start()).thenReturn(chainFuture);
when(worldStateDownloader.run(any(FastSyncActions.class), eq(new FastSyncState(pivotBlockHeader)))).thenReturn(firstWorldStateFuture);
// Second attempt with new pivot block
when(fastSyncActions.downloadPivotBlockHeader(secondSelectPivotBlockState)).thenReturn(completedFuture(secondDownloadPivotBlockHeaderState));
when(fastSyncActions.createChainDownloader(secondDownloadPivotBlockHeaderState)).thenReturn(secondChainDownloader);
when(secondChainDownloader.start()).thenReturn(completedFuture(null));
when(worldStateDownloader.run(any(FastSyncActions.class), eq(new FastSyncState(secondPivotBlockHeader)))).thenReturn(secondWorldStateFuture);
final CompletableFuture<FastSyncState> result = downloader.start();
verify(fastSyncActions).waitForSuitablePeers(FastSyncState.EMPTY_SYNC_STATE);
verify(fastSyncActions).selectPivotBlock(FastSyncState.EMPTY_SYNC_STATE);
verify(fastSyncActions).downloadPivotBlockHeader(selectPivotBlockState);
verify(storage).storeState(downloadPivotBlockHeaderState);
verify(fastSyncActions).createChainDownloader(downloadPivotBlockHeaderState);
verify(worldStateDownloader).run(any(FastSyncActions.class), eq(new FastSyncState(pivotBlockHeader)));
verifyNoMoreInteractions(fastSyncActions, worldStateDownloader, storage);
assertThat(result).isNotDone();
firstWorldStateFuture.completeExceptionally(new StalledDownloadException("test"));
assertThat(result).isNotDone();
verify(chainDownloader).cancel();
// A real chain downloader would cause the chainFuture to complete when cancel is called.
chainFuture.completeExceptionally(new CancellationException());
verify(fastSyncActions, times(2)).waitForSuitablePeers(FastSyncState.EMPTY_SYNC_STATE);
verify(fastSyncActions, times(2)).selectPivotBlock(FastSyncState.EMPTY_SYNC_STATE);
verify(fastSyncActions).downloadPivotBlockHeader(secondSelectPivotBlockState);
verify(storage).storeState(secondDownloadPivotBlockHeaderState);
verify(fastSyncActions).createChainDownloader(secondDownloadPivotBlockHeaderState);
verify(worldStateDownloader).run(any(FastSyncActions.class), eq(new FastSyncState(secondPivotBlockHeader)));
verifyNoMoreInteractions(fastSyncActions, worldStateDownloader, storage);
secondWorldStateFuture.complete(null);
assertThat(result).isCompletedWithValue(secondDownloadPivotBlockHeaderState);
}
Aggregations