private void handleFailedBlockProcessing(
      final Block failedBlock,
      final BlockValidationResult result,
      final boolean shouldRecordBadBlock,
      final ProtocolContext context) {
    if (result.causedBy().isPresent()) {
      // Block processing failed exceptionally, we cannot assume the block was intrinsically invalid
      LOG.info(
          "Failed to process block {}: {}, caused by {}",
          failedBlock.toLogString(),
          result.errorMessage,
          result.causedBy().get());
      LOG.debug("with stack", result.causedBy().get());
    } else {
      if (result.errorMessage.isPresent()) {
        LOG.info("Invalid block {}: {}", failedBlock.toLogString(), result.errorMessage);
      } else {
        LOG.info("Invalid block {}", failedBlock.toLogString());
      }

      if (shouldRecordBadBlock) {
        // Result.errorMessage should not be empty on failure, but add a default to be safe
        String description = result.errorMessage.orElse("Unknown cause");
        final BadBlockCause cause = BadBlockCause.fromValidationFailure(description);
        context.getBadBlockManager().addBadBlock(failedBlock, cause);
      } else {
        LOG.debug("Invalid block {} not added to badBlockManager ", failedBlock.toLogString());
      }
    }
  }
Performs a full validation and processing of a block

@param context the {@link ProtocolContext}
@param block the block being validated and processed
@param headerValidationMode the {@link HeaderValidationMode} used for validating the header
@param ommerValidationMode the {@link HeaderValidationMode} used for validating the ommers
@return an optional containing the {@link BlockProcessingOutputs} with the output of processing
    the block, empty if the block was deemed invalid or couldn't be processed
ethereum/core/src/main/java/org/hyperledger/besu/ethereum/MainnetBlockValidator.java