private CompletableFuture<Block> getBlockFromPeers(
      final Optional<EthPeer> preferredPeer,
      final long blockNumber,
      final Optional<Hash> maybeBlockHash) {
    return repeatableGetBlockFromPeer(preferredPeer, blockNumber, maybeBlockHash)
        .whenComplete(
            (block, throwable) -> {
              if (block != null) {
                LOG.atDebug()
                    .setMessage("Successfully retrieved block {}")
                    .addArgument(block::toLogString)
                    .log();
                processingBlocksManager.registerReceivedBlock(block);
              } else {
                if (throwable != null) {
                  LOG.warn(
                      "Failed to retrieve block "
                          + logBlockNumberMaybeHash(blockNumber, maybeBlockHash),
                      throwable);
                } else {
                  // this could happen if we give up at some point since we find that it make no
                  // sense to retry
                  LOG.atDebug()
                      .setMessage("Block {} not retrieved")
                      .addArgument(() -> logBlockNumberMaybeHash(blockNumber, maybeBlockHash))
                      .log();
                }
                processingBlocksManager.registerFailedGetBlock(blockNumber, maybeBlockHash);
              }
            });
  }
Process pending Children if any

@param block the block to process the children
@return true if block has any pending child
ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/BlockPropagationManager.java