public static List<BlockStateCall> fillBlockStateCalls(
      final List<? extends BlockStateCall> blockStateCalls, final BlockHeader header) {
    long lastPresentBlockNumber = findLastBlockNumber(blockStateCalls);
    if (lastPresentBlockNumber > header.getNumber() + MAX_BLOCK_CALL_SIZE) {
      throw new IllegalArgumentException(
          String.format(
              "Block number %d exceeds the limit of %d (header: %d + MAX_BLOCK_CALL_SIZE: %d)",
              lastPresentBlockNumber,
              header.getNumber() + MAX_BLOCK_CALL_SIZE,
              header.getNumber(),
              MAX_BLOCK_CALL_SIZE));
    }
    List<BlockStateCall> filledCalls = new ArrayList<>();
    long currentBlock = header.getNumber();
    long currentTimestamp = header.getTimestamp();
    for (BlockStateCall blockStateCall : blockStateCalls) {
      long nextBlockNumber =
          blockStateCall.getBlockOverrides().getBlockNumber().orElse(currentBlock + 1);
      List<BlockStateCall> intermediateBlocks =
          new ArrayList<>(
              generateIntermediateBlocks(nextBlockNumber, currentBlock, currentTimestamp));
      // Add intermediate blocks
      for (BlockStateCall intermediateBlock : intermediateBlocks) {
        add(filledCalls, intermediateBlock, currentBlock, currentTimestamp);
        currentBlock = intermediateBlock.getBlockOverrides().getBlockNumber().orElseThrow();
        currentTimestamp = intermediateBlock.getBlockOverrides().getTimestamp().orElseThrow();
      }
      // set the block number and timestamp if they are not set
      if (blockStateCall.getBlockOverrides().getBlockNumber().isEmpty()) {
        blockStateCall.getBlockOverrides().setBlockNumber(currentBlock + 1);
      }
      if (blockStateCall.getBlockOverrides().getTimestamp().isEmpty()) {
        blockStateCall.getBlockOverrides().setTimestamp(currentTimestamp + TIMESTAMP_INCREMENT);
      }
      // Add the current block
      add(filledCalls, blockStateCall, currentBlock, currentTimestamp);
      currentBlock = blockStateCall.getBlockOverrides().getBlockNumber().orElseThrow();
      currentTimestamp = blockStateCall.getBlockOverrides().getTimestamp().orElseThrow();
    }
    return filledCalls;
  }
Normalizes a list of BlockStateCalls by filling gaps and setting the correct block number and
timestamp.

@param blockStateCalls the list of BlockStateCalls to normalize
@param header the initial block header
@return a normalized list of BlockStateCalls
ethereum/core/src/main/java/org/hyperledger/besu/ethereum/transaction/BlockStateCalls.java