|
|
|
@ -16,7 +16,9 @@ package org.hyperledger.besu.ethereum.eth.sync.fastsync; |
|
|
|
|
|
|
|
|
|
import static java.util.concurrent.CompletableFuture.completedFuture; |
|
|
|
|
import static org.assertj.core.api.Assertions.assertThat; |
|
|
|
|
import static org.assertj.core.api.Assertions.catchThrowable; |
|
|
|
|
import static org.mockito.ArgumentMatchers.any; |
|
|
|
|
import static org.mockito.Mockito.doAnswer; |
|
|
|
|
import static org.mockito.Mockito.mock; |
|
|
|
|
import static org.mockito.Mockito.times; |
|
|
|
|
import static org.mockito.Mockito.verify; |
|
|
|
@ -35,6 +37,8 @@ import org.hyperledger.besu.services.tasks.TaskCollection; |
|
|
|
|
import java.nio.file.Path; |
|
|
|
|
import java.util.concurrent.CancellationException; |
|
|
|
|
import java.util.concurrent.CompletableFuture; |
|
|
|
|
import java.util.concurrent.Executors; |
|
|
|
|
import java.util.concurrent.TimeUnit; |
|
|
|
|
import java.util.function.Supplier; |
|
|
|
|
|
|
|
|
|
import org.assertj.core.api.Assertions; |
|
|
|
@ -228,6 +232,41 @@ public class FastSyncDownloaderTest { |
|
|
|
|
assertThat(worldStateFuture).isCancelled(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
|
public void shouldAbortIfStopped() { |
|
|
|
|
final FastSyncState selectPivotBlockState = new FastSyncState(50); |
|
|
|
|
final BlockHeader pivotBlockHeader = new BlockHeaderTestFixture().number(50).buildHeader(); |
|
|
|
|
final FastSyncState downloadPivotBlockHeaderState = new FastSyncState(pivotBlockHeader); |
|
|
|
|
when(fastSyncActions.waitForSuitablePeers(FastSyncState.EMPTY_SYNC_STATE)).thenReturn(COMPLETE); |
|
|
|
|
when(fastSyncActions.selectPivotBlock(FastSyncState.EMPTY_SYNC_STATE)) |
|
|
|
|
.thenReturn(completedFuture(selectPivotBlockState)); |
|
|
|
|
doAnswer( |
|
|
|
|
invocation -> { |
|
|
|
|
CompletableFuture<FastSyncState> future = new CompletableFuture<>(); |
|
|
|
|
Executors.newSingleThreadScheduledExecutor() |
|
|
|
|
.schedule( |
|
|
|
|
() -> future.complete(downloadPivotBlockHeaderState), |
|
|
|
|
500, |
|
|
|
|
TimeUnit.MILLISECONDS); |
|
|
|
|
return future; |
|
|
|
|
}) |
|
|
|
|
.when(fastSyncActions) |
|
|
|
|
.downloadPivotBlockHeader(selectPivotBlockState); |
|
|
|
|
|
|
|
|
|
final CompletableFuture<FastSyncState> result = downloader.start(); |
|
|
|
|
downloader.stop(); |
|
|
|
|
|
|
|
|
|
Throwable thrown = catchThrowable(() -> result.get()); |
|
|
|
|
assertThat(thrown).hasCauseExactlyInstanceOf(CancellationException.class); |
|
|
|
|
|
|
|
|
|
verify(fastSyncActions).waitForSuitablePeers(FastSyncState.EMPTY_SYNC_STATE); |
|
|
|
|
verify(fastSyncActions).selectPivotBlock(FastSyncState.EMPTY_SYNC_STATE); |
|
|
|
|
verify(fastSyncActions).downloadPivotBlockHeader(selectPivotBlockState); |
|
|
|
|
verify(storage).storeState(downloadPivotBlockHeaderState); |
|
|
|
|
verify(worldStateDownloader).cancel(); |
|
|
|
|
verifyNoMoreInteractions(fastSyncActions, worldStateDownloader, storage); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
|
public void shouldNotConsiderFastSyncCompleteIfOnlyWorldStateDownloadIsComplete() { |
|
|
|
|
final CompletableFuture<Void> chainFuture = new CompletableFuture<>(); |
|
|
|
|