@Test void shouldSearchCommonAncestorWithSufficientRemoteData() throws ExecutionException, InterruptedException { final UInt64 firstNonFinalSlot = dataStructureUtil.randomUInt64(); final UInt64 currentLocalHead = firstNonFinalSlot.plus(CommonAncestor.OPTIMISTIC_HISTORY_LENGTH.times(10)); final UInt64 currentRemoteHead = firstNonFinalSlot.plus(CommonAncestor.OPTIMISTIC_HISTORY_LENGTH.times(9)); final CommonAncestor commonAncestor = new CommonAncestor(storageClient); final UInt64 syncStartSlot = currentRemoteHead.minus(CommonAncestor.OPTIMISTIC_HISTORY_LENGTH); final SafeFuture<Void> requestFuture1 = new SafeFuture<>(); when(peer.requestBlocksByRange( eq(syncStartSlot), eq(CommonAncestor.BLOCK_COUNT), eq(CommonAncestor.SAMPLE_RATE), any())) .thenReturn(requestFuture1); final PeerStatus status = withPeerHeadSlot( currentRemoteHead, compute_epoch_at_slot(currentRemoteHead), dataStructureUtil.randomBytes32()); when(storageClient.getHeadSlot()).thenReturn(currentLocalHead); when(storageClient.containsBlock(any())).thenReturn(true); SafeFuture<UInt64> futureSlot = commonAncestor.getCommonAncestor(peer, status, firstNonFinalSlot); verify(peer) .requestBlocksByRange( eq(syncStartSlot), eq(CommonAncestor.BLOCK_COUNT), eq(CommonAncestor.SAMPLE_RATE), responseListenerArgumentCaptor.capture()); assertThat(futureSlot.isDone()).isFalse(); final ResponseStreamListener<SignedBeaconBlock> responseListener = responseListenerArgumentCaptor.getValue(); respondWithBlocksAtSlots( responseListener, currentLocalHead.minus(2850), currentLocalHead.minus(2250)); requestFuture1.complete(null); assertThat(futureSlot.get()).isEqualTo(currentLocalHead.minus(2250)); }
public SafeFuture<UInt64> getCommonAncestor( final Eth2Peer peer, final PeerStatus status, final UInt64 firstNonFinalSlot) { final UInt64 lowestHeadSlot = storageClient.getHeadSlot().min(status.getHeadSlot()); if (lowestHeadSlot.isLessThan(firstNonFinalSlot.plus(OPTIMISTIC_HISTORY_LENGTH))) { return SafeFuture.completedFuture(firstNonFinalSlot); } final UInt64 localNonFinalisedSlotCount = lowestHeadSlot.minus(firstNonFinalSlot); final UInt64 firstRequestedSlot = lowestHeadSlot.minus(OPTIMISTIC_HISTORY_LENGTH); final UInt64 lastSlot = firstRequestedSlot.plus(MAX_BLOCK_RANGE); LOG.debug( "Local head slot {}. Have {} non finalized slots, " + "will sample ahead every {} slots from {} to {}. Peer head is {}", storageClient.getHeadSlot(), localNonFinalisedSlotCount, SAMPLE_RATE, firstRequestedSlot, lastSlot, status.getHeadSlot()); final BestBlockListener blockListener = new BestBlockListener(storageClient, firstNonFinalSlot); final PeerSyncBlockRequest request = new PeerSyncBlockRequest(SafeFuture.COMPLETE, lastSlot, blockListener); return peer.requestBlocksByRange(firstRequestedSlot, BLOCK_COUNT, SAMPLE_RATE, request) .thenApply(__ -> blockListener.getBestSlot()); }
CommonAncestor { public SafeFuture<UInt64> getCommonAncestor( final Eth2Peer peer, final PeerStatus status, final UInt64 firstNonFinalSlot) { final UInt64 lowestHeadSlot = storageClient.getHeadSlot().min(status.getHeadSlot()); if (lowestHeadSlot.isLessThan(firstNonFinalSlot.plus(OPTIMISTIC_HISTORY_LENGTH))) { return SafeFuture.completedFuture(firstNonFinalSlot); } final UInt64 localNonFinalisedSlotCount = lowestHeadSlot.minus(firstNonFinalSlot); final UInt64 firstRequestedSlot = lowestHeadSlot.minus(OPTIMISTIC_HISTORY_LENGTH); final UInt64 lastSlot = firstRequestedSlot.plus(MAX_BLOCK_RANGE); LOG.debug( "Local head slot {}. Have {} non finalized slots, " + "will sample ahead every {} slots from {} to {}. Peer head is {}", storageClient.getHeadSlot(), localNonFinalisedSlotCount, SAMPLE_RATE, firstRequestedSlot, lastSlot, status.getHeadSlot()); final BestBlockListener blockListener = new BestBlockListener(storageClient, firstNonFinalSlot); final PeerSyncBlockRequest request = new PeerSyncBlockRequest(SafeFuture.COMPLETE, lastSlot, blockListener); return peer.requestBlocksByRange(firstRequestedSlot, BLOCK_COUNT, SAMPLE_RATE, request) .thenApply(__ -> blockListener.getBestSlot()); } }
CommonAncestor { public SafeFuture<UInt64> getCommonAncestor( final Eth2Peer peer, final PeerStatus status, final UInt64 firstNonFinalSlot) { final UInt64 lowestHeadSlot = storageClient.getHeadSlot().min(status.getHeadSlot()); if (lowestHeadSlot.isLessThan(firstNonFinalSlot.plus(OPTIMISTIC_HISTORY_LENGTH))) { return SafeFuture.completedFuture(firstNonFinalSlot); } final UInt64 localNonFinalisedSlotCount = lowestHeadSlot.minus(firstNonFinalSlot); final UInt64 firstRequestedSlot = lowestHeadSlot.minus(OPTIMISTIC_HISTORY_LENGTH); final UInt64 lastSlot = firstRequestedSlot.plus(MAX_BLOCK_RANGE); LOG.debug( "Local head slot {}. Have {} non finalized slots, " + "will sample ahead every {} slots from {} to {}. Peer head is {}", storageClient.getHeadSlot(), localNonFinalisedSlotCount, SAMPLE_RATE, firstRequestedSlot, lastSlot, status.getHeadSlot()); final BestBlockListener blockListener = new BestBlockListener(storageClient, firstNonFinalSlot); final PeerSyncBlockRequest request = new PeerSyncBlockRequest(SafeFuture.COMPLETE, lastSlot, blockListener); return peer.requestBlocksByRange(firstRequestedSlot, BLOCK_COUNT, SAMPLE_RATE, request) .thenApply(__ -> blockListener.getBestSlot()); } CommonAncestor(final RecentChainData storageClient); }
CommonAncestor { public SafeFuture<UInt64> getCommonAncestor( final Eth2Peer peer, final PeerStatus status, final UInt64 firstNonFinalSlot) { final UInt64 lowestHeadSlot = storageClient.getHeadSlot().min(status.getHeadSlot()); if (lowestHeadSlot.isLessThan(firstNonFinalSlot.plus(OPTIMISTIC_HISTORY_LENGTH))) { return SafeFuture.completedFuture(firstNonFinalSlot); } final UInt64 localNonFinalisedSlotCount = lowestHeadSlot.minus(firstNonFinalSlot); final UInt64 firstRequestedSlot = lowestHeadSlot.minus(OPTIMISTIC_HISTORY_LENGTH); final UInt64 lastSlot = firstRequestedSlot.plus(MAX_BLOCK_RANGE); LOG.debug( "Local head slot {}. Have {} non finalized slots, " + "will sample ahead every {} slots from {} to {}. Peer head is {}", storageClient.getHeadSlot(), localNonFinalisedSlotCount, SAMPLE_RATE, firstRequestedSlot, lastSlot, status.getHeadSlot()); final BestBlockListener blockListener = new BestBlockListener(storageClient, firstNonFinalSlot); final PeerSyncBlockRequest request = new PeerSyncBlockRequest(SafeFuture.COMPLETE, lastSlot, blockListener); return peer.requestBlocksByRange(firstRequestedSlot, BLOCK_COUNT, SAMPLE_RATE, request) .thenApply(__ -> blockListener.getBestSlot()); } CommonAncestor(final RecentChainData storageClient); SafeFuture<UInt64> getCommonAncestor(
      final Eth2Peer peer, final PeerStatus status, final UInt64 firstNonFinalSlot); }
CommonAncestor { public SafeFuture<UInt64> getCommonAncestor( final Eth2Peer peer, final PeerStatus status, final UInt64 firstNonFinalSlot) { final UInt64 lowestHeadSlot = storageClient.getHeadSlot().min(status.getHeadSlot()); if (lowestHeadSlot.isLessThan(firstNonFinalSlot.plus(OPTIMISTIC_HISTORY_LENGTH))) { return SafeFuture.completedFuture(firstNonFinalSlot); } final UInt64 localNonFinalisedSlotCount = lowestHeadSlot.minus(firstNonFinalSlot); final UInt64 firstRequestedSlot = lowestHeadSlot.minus(OPTIMISTIC_HISTORY_LENGTH); final UInt64 lastSlot = firstRequestedSlot.plus(MAX_BLOCK_RANGE); LOG.debug( "Local head slot {}. Have {} non finalized slots, " + "will sample ahead every {} slots from {} to {}. Peer head is {}", storageClient.getHeadSlot(), localNonFinalisedSlotCount, SAMPLE_RATE, firstRequestedSlot, lastSlot, status.getHeadSlot()); final BestBlockListener blockListener = new BestBlockListener(storageClient, firstNonFinalSlot); final PeerSyncBlockRequest request = new PeerSyncBlockRequest(SafeFuture.COMPLETE, lastSlot, blockListener); return peer.requestBlocksByRange(firstRequestedSlot, BLOCK_COUNT, SAMPLE_RATE, request) .thenApply(__ -> blockListener.getBestSlot()); } CommonAncestor(final RecentChainData storageClient); SafeFuture<UInt64> getCommonAncestor(
      final Eth2Peer peer, final PeerStatus status, final UInt64 firstNonFinalSlot);  }