private CompletableFuture<BlockHeader> executePivotQuery(final long blockNumber) {
    if (isCancelled.get() || result.isDone()) {
      // Stop loop if this task is done
      return CompletableFuture.failedFuture(new CancellationException());
    }
    final Optional<RetryingGetHeaderFromPeerByNumberTask> query = createPivotQuery(blockNumber);
    final CompletableFuture<BlockHeader> pivotHeaderFuture;
    if (query.isPresent()) {
      final CompletableFuture<BlockHeader> headerQuery = query.get().getHeader();
      pivotHeaderFuture =
          FutureUtils.exceptionallyCompose(headerQuery, (error) -> executePivotQuery(blockNumber));
    } else {
      // We were unable to find a peer to query, wait and try again
      LOG.debug("No peer currently available to query for block {}.", blockNumber);
      pivotHeaderFuture =
          ethContext
              .getScheduler()
              .scheduleFutureTask(
                  () ->
                      ethContext
                          .getEthPeers()
                          .waitForPeer(
                              (peer) -> !pivotBlockQueriesByPeerId.containsKey(peer.nodeId()))
                          // Ignore result, ensure even a timeout will result in calling
                          // executePivotQuery
                          .handle((r, e) -> null)
                          .thenCompose(res -> executePivotQuery(blockNumber)),
                  Duration.ofSeconds(5));
    }

    return pivotHeaderFuture;
  }
This task will query {@code numberOfPeersToQuery} peers for a particular block number. If any
peers disagree on the block at this number, the task fails with a {@code
ContestedPivotBlockException}. The task will succeed only if {@code numberOfPeersToQuery}
distinct peers all return matching block headers for the specified block number.
ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/PivotBlockConfirmer.java