public BlockHeader header(final long number, final BlockBody body, final BlockOptions options) {
    final int gasLimit = random.nextInt() & Integer.MAX_VALUE;
    final int gasUsed = Math.max(0, gasLimit - 1);
    final long blockNonce = random.nextLong();
    final BlockHeaderBuilder blockHeaderBuilder =
        BlockHeaderBuilder.create()
            .parentHash(options.getParentHash(hash()))
            .ommersHash(BodyValidation.ommersHash(body.getOmmers()))
            .coinbase(options.getCoinbase(address()))
            .stateRoot(options.getStateRoot(hash()))
            .transactionsRoot(BodyValidation.transactionsRoot(body.getTransactions()))
            .receiptsRoot(options.getReceiptsRoot(hash()))
            .logsBloom(options.getLogsBloom(logsBloom()))
            .difficulty(options.getDifficulty(Difficulty.of(uint256(4))))
            .number(number)
            .gasLimit(gasLimit)
            .gasUsed(options.getGasUsed(gasUsed))
            .timestamp(
                options
                    .getTimestamp()
                    .orElse(Instant.now().truncatedTo(ChronoUnit.SECONDS).getEpochSecond()))
            .extraData(options.getExtraData(bytes32()))
            .mixHash(hash())
            .nonce(blockNonce)
            .withdrawalsRoot(options.getWithdrawalsRoot(null))
            .requestsHash(options.getRequestsHash(null))
            .blockHeaderFunctions(
                options.getBlockHeaderFunctions(new MainnetBlockHeaderFunctions()));
    options.getBaseFee(Optional.of(Wei.of(uint256(2)))).ifPresent(blockHeaderBuilder::baseFee);
    return blockHeaderBuilder.buildBlockHeader();
  }
Generates a sequence of blocks with some accounts and account storage pre-populated with random
data.
ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/BlockDataGenerator.java