protected BlockCreationResult createBlock(
      final Optional<List<Transaction>> maybeTransactions,
      final Optional<List<BlockHeader>> maybeOmmers,
      final Optional<List<Withdrawal>> maybeWithdrawals,
      final Optional<Bytes32> maybePrevRandao,
      final Optional<Bytes32> maybeParentBeaconBlockRoot,
      final long timestamp,
      boolean rewardCoinbase,
      final BlockHeader parentHeader) {

    final var timings = new BlockCreationTiming();

    try (final MutableWorldState disposableWorldState = duplicateWorldStateAtParent(parentHeader)) {
      timings.register("duplicateWorldState");
      final ProtocolSpec newProtocolSpec =
          protocolSchedule.getForNextBlockHeader(parentHeader, timestamp);

      final ProcessableBlockHeader processableBlockHeader =
          createPending(
                  newProtocolSpec,
                  parentHeader,
                  miningConfiguration,
                  timestamp,
                  maybePrevRandao,
                  maybeParentBeaconBlockRoot)
              .buildProcessableBlockHeader();

      final Address miningBeneficiary =
          miningBeneficiaryCalculator.getMiningBeneficiary(timestamp, processableBlockHeader);

      throwIfStopped();

      final List<BlockHeader> ommers = maybeOmmers.orElse(selectOmmers());

      throwIfStopped();

      final var selectorsStateManager = new SelectorsStateManager();
      final var pluginTransactionSelector =
          miningConfiguration
              .getTransactionSelectionService()
              .createPluginTransactionSelector(selectorsStateManager);
      final var operationTracer = pluginTransactionSelector.getOperationTracer();
      operationTracer.traceStartBlock(processableBlockHeader, miningBeneficiary);
      BlockProcessingContext blockProcessingContext =
          new BlockProcessingContext(
              processableBlockHeader,
              disposableWorldState,
              newProtocolSpec,
              newProtocolSpec
                  .getBlockHashProcessor()
                  .createBlockHashLookup(protocolContext.getBlockchain(), processableBlockHeader),
              operationTracer);
      newProtocolSpec.getBlockHashProcessor().process(blockProcessingContext);

      timings.register("preTxsSelection");
      final TransactionSelectionResults transactionResults =
          selectTransactions(
              processableBlockHeader,
              disposableWorldState,
              maybeTransactions,
              miningBeneficiary,
              newProtocolSpec,
              pluginTransactionSelector,
              selectorsStateManager,
              parentHeader);
      transactionResults.logSelectionStats();
      timings.register("txsSelection");
      throwIfStopped();

      final Optional<WithdrawalsProcessor> maybeWithdrawalsProcessor =
          newProtocolSpec.getWithdrawalsProcessor();
      final boolean withdrawalsCanBeProcessed =
          maybeWithdrawalsProcessor.isPresent() && maybeWithdrawals.isPresent();
      if (withdrawalsCanBeProcessed) {
        maybeWithdrawalsProcessor
            .get()
            .processWithdrawals(maybeWithdrawals.get(), disposableWorldState.updater());
      }

      throwIfStopped();

      // EIP-7685: process EL requests
      final Optional<RequestProcessorCoordinator> requestProcessor =
          newProtocolSpec.getRequestProcessorCoordinator();
      RequestProcessingContext requestProcessingContext =
          new RequestProcessingContext(blockProcessingContext, transactionResults.getReceipts());

      Optional<List<Request>> maybeRequests =
          requestProcessor.map(processor -> processor.process(requestProcessingContext));

      throwIfStopped();

      if (rewardCoinbase
          && !rewardBeneficiary(
              disposableWorldState,
              processableBlockHeader,
              ommers,
              miningBeneficiary,
              newProtocolSpec.getBlockReward(),
              newProtocolSpec.isSkipZeroBlockRewards(),
              newProtocolSpec)) {
        LOG.trace("Failed to apply mining reward, exiting.");
        throw new RuntimeException("Failed to apply mining reward.");
      }

      throwIfStopped();

      final GasUsage usage =
          computeExcessBlobGas(transactionResults, newProtocolSpec, parentHeader);

      throwIfStopped();

      BlockHeaderBuilder builder =
          BlockHeaderBuilder.create()
              .populateFrom(processableBlockHeader)
              .ommersHash(BodyValidation.ommersHash(ommers))
              .stateRoot(disposableWorldState.rootHash())
              .transactionsRoot(
                  BodyValidation.transactionsRoot(transactionResults.getSelectedTransactions()))
              .receiptsRoot(BodyValidation.receiptsRoot(transactionResults.getReceipts()))
              .logsBloom(BodyValidation.logsBloom(transactionResults.getReceipts()))
              .gasUsed(transactionResults.getCumulativeGasUsed())
              .extraData(extraDataCalculator.get(parentHeader))
              .withdrawalsRoot(
                  withdrawalsCanBeProcessed
                      ? BodyValidation.withdrawalsRoot(maybeWithdrawals.get())
                      : null)
              .requestsHash(maybeRequests.map(BodyValidation::requestsHash).orElse(null));
      if (usage != null) {
        builder.blobGasUsed(usage.used.toLong()).excessBlobGas(usage.excessBlobGas);
      }

      final SealableBlockHeader sealableBlockHeader = builder.buildSealableBlockHeader();

      final BlockHeader blockHeader = createFinalBlockHeader(sealableBlockHeader);

      final Optional<List<Withdrawal>> withdrawals =
          withdrawalsCanBeProcessed ? maybeWithdrawals : Optional.empty();
      final BlockBody blockBody =
          new BlockBody(transactionResults.getSelectedTransactions(), ommers, withdrawals);
      final Block block = new Block(blockHeader, blockBody);

      operationTracer.traceEndBlock(blockHeader, blockBody);
      timings.register("blockAssembled");
      return new BlockCreationResult(block, transactionResults, timings);
    } catch (final SecurityModuleException ex) {
      throw new IllegalStateException("Failed to create block signature", ex);
    } catch (final CancellationException | StorageException ex) {
      throw ex;
    } catch (final Exception ex) {
      throw new IllegalStateException(
          "Block creation failed unexpectedly. Will restart on next block added to chain.", ex);
    }
  }
Create block will create a new block at the head of the blockchain specified in the
protocolContext.

<p>It will select transactions from the PendingTransaction list for inclusion in the Block
body, and will supply an empty Ommers list.

<p>Once transactions have been selected and applied to a disposable/temporary world state, the
block reward is paid to the relevant coinbase, and a sealable header is constructed.

<p>The sealableHeader is then provided to child instances for sealing (i.e. proof of work or
otherwise).

<p>The constructed block is then returned.

@return a block with appropriately selected transactions, seals and ommers.
ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreator.java