private CompletableFuture<?> markBadBlock(final BlockHeader badHeader, final EthPeer badPeer) {
    // even though the header is known bad we are downloading the block body for the debug_badBlocks
    // RPC
    final BadBlockManager badBlockManager = protocolContext.getBadBlockManager();
    CompletableFuture<Block> blockFuture;
    if (synchronizerConfiguration.isPeerTaskSystemEnabled()) {
      blockFuture =
          ethContext
              .getScheduler()
              .scheduleServiceTask(
                  () -> {
                    GetBodiesFromPeerTask task =
                        new GetBodiesFromPeerTask(List.of(badHeader), protocolSchedule);
                    PeerTaskExecutorResult<List<Block>> taskResult =
                        ethContext.getPeerTaskExecutor().executeAgainstPeer(task, badPeer);
                    if (taskResult.responseCode() == PeerTaskExecutorResponseCode.SUCCESS) {
                      return CompletableFuture.completedFuture(
                          taskResult.result().map(List::getFirst).orElse(null));
                    } else {
                      return CompletableFuture.failedFuture(new RuntimeException());
                    }
                  });
    } else {
      blockFuture =
          org.hyperledger.besu.ethereum.eth.manager.task.GetBodiesFromPeerTask.forHeaders(
                  protocolSchedule, ethContext, List.of(badHeader), metricsSystem)
              .assignPeer(badPeer)
              .run()
              .thenApply((blockPeerTaskResult) -> blockPeerTaskResult.getResult().getFirst());
    }
    return blockFuture.whenComplete(
        (blockResult, error) -> {
          final HeaderValidationMode validationMode =
              validationPolicy.getValidationModeForNextBlock();
          final String description = String.format("Failed header validation (%s)", validationMode);
          final BadBlockCause cause = BadBlockCause.fromValidationFailure(description);
          if (blockResult != null) {
            badBlockManager.addBadBlock(blockResult, cause);
          } else {
            badBlockManager.addBadHeader(badHeader, cause);
          }
        });
  }
Retrieves a sequence of headers, sending out requests repeatedly until all headers are fulfilled.
Validates headers as they are received.
ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/tasks/DownloadHeaderSequenceTask.java