protected BlockStateCallSimulationResult processTransactions(
      final BlockHeader blockHeader,
      final BlockStateCall blockStateCall,
      final MutableWorldState ws,
      final ProtocolSpec protocolSpec,
      final boolean shouldValidate,
      final boolean isTraceTransfers,
      final MainnetTransactionProcessor transactionProcessor,
      final BlockHashLookup blockHashLookup,
      final Supplier<SECPSignature> signatureSupplier,
      final long simulationCumulativeGasUsed) {

    TransactionValidationParams transactionValidationParams =
        shouldValidate ? STRICT_VALIDATION_PARAMS : SIMULATION_PARAMS;

    BlockStateCallSimulationResult blockStateCallSimulationResult =
        new BlockStateCallSimulationResult(
            protocolSpec, calculateSimulationGasCap(blockHeader, simulationCumulativeGasUsed));

    MiningBeneficiaryCalculator miningBeneficiaryCalculator =
        blockStateCall
            .getBlockOverrides()
            .getFeeRecipient()
            .<MiningBeneficiaryCalculator>map(feeRecipient -> header -> feeRecipient)
            .orElseGet(protocolSpec::getMiningBeneficiaryCalculator);

    for (CallParameter callParameter : blockStateCall.getCalls()) {

      OperationTracer operationTracer =
          isTraceTransfers ? new EthTransferLogOperationTracer() : OperationTracer.NO_TRACING;

      final WorldUpdater transactionUpdater = ws.updater();
      long gasLimit =
          transactionSimulator.calculateSimulationGasCap(
              blockHeader,
              callParameter.getGas(),
              blockStateCallSimulationResult.getRemainingGas());

      BiFunction<ProtocolSpec, Optional<BlockHeader>, Wei> blobGasPricePerGasSupplier =
          getBlobGasPricePerGasSupplier(
              blockStateCall.getBlockOverrides(), transactionValidationParams);

      final Optional<TransactionSimulatorResult> transactionSimulatorResult =
          transactionSimulator.processWithWorldUpdater(
              callParameter,
              Optional.empty(), // We have already applied state overrides on block level
              transactionValidationParams,
              operationTracer,
              blockHeader,
              transactionUpdater,
              miningBeneficiaryCalculator.calculateBeneficiary(blockHeader),
              gasLimit,
              transactionProcessor,
              blobGasPricePerGasSupplier,
              blockHashLookup,
              signatureSupplier);

      TransactionSimulatorResult transactionSimulationResult =
          transactionSimulatorResult.orElseThrow(
              () -> new BlockStateCallException("Transaction simulator result is empty"));

      if (transactionSimulationResult.isInvalid()) {
        throw new BlockStateCallException(
            "Transaction simulator result is invalid", transactionSimulationResult);
      }
      transactionUpdater.commit();
      blockStateCallSimulationResult.add(transactionSimulationResult, ws, operationTracer);
    }
    return blockStateCallSimulationResult;
  }
Processes a single BlockStateCall, simulating the block execution.

@param baseBlockHeader The block header for the simulation.
@param blockStateCall The BlockStateCall to process.
@param ws The MutableWorldState to use for the simulation.
@return A BlockSimulationResult from processing the BlockStateCall.
ethereum/core/src/main/java/org/hyperledger/besu/ethereum/transaction/BlockSimulator.java