private BlockSimulationResult createFinalBlock(
      final BlockHeader blockHeader,
      final BlockStateCallSimulationResult blockStateCallSimulationResult,
      final BlockOverrides blockOverrides,
      final MutableWorldState ws,
      final Optional<List<Request>> maybeRequests) {

    List<Transaction> transactions = blockStateCallSimulationResult.getTransactions();
    List<TransactionReceipt> receipts = blockStateCallSimulationResult.getReceipts();

    BlockHeader finalBlockHeader =
        BlockHeaderBuilder.createDefault()
            .populateFrom(blockHeader)
            .ommersHash(BodyValidation.ommersHash(List.of()))
            .stateRoot(blockOverrides.getStateRoot().orElseGet(ws::frontierRootHash))
            .transactionsRoot(BodyValidation.transactionsRoot(transactions))
            .receiptsRoot(BodyValidation.receiptsRoot(receipts))
            .logsBloom(BodyValidation.logsBloom(receipts))
            .gasUsed(blockStateCallSimulationResult.getCumulativeGasUsed())
            .withdrawalsRoot(BodyValidation.withdrawalsRoot(List.of()))
            .requestsHash(maybeRequests.map(BodyValidation::requestsHash).orElse(null))
            .extraData(blockOverrides.getExtraData().orElse(Bytes.EMPTY))
            .blockHeaderFunctions(new BlockStateCallBlockHeaderFunctions(blockOverrides))
            .buildBlockHeader();

    Block block =
        new Block(finalBlockHeader, new BlockBody(transactions, List.of(), Optional.of(List.of())));

    return new BlockSimulationResult(block, 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