private Blockchain setupLocalAndRemoteChains(
      final int localBlockCount, final int remoteBlockCount, final int blocksInCommon) {
    checkArgument(localBlockCount >= 1);
    checkArgument(remoteBlockCount >= 1);
    checkArgument(blocksInCommon >= 0);
    checkArgument(blocksInCommon <= Math.min(localBlockCount, remoteBlockCount));

    final Block remoteGenesis =
        (blocksInCommon > 0) ? localGenesisBlock : blockDataGenerator.genesisBlock();
    MutableBlockchain remoteChain = createInMemoryBlockchain(remoteGenesis);

    // Build common chain
    if (blocksInCommon > 1) {
      List<Block> commonBlocks =
          blockDataGenerator.blockSequence(remoteGenesis, blocksInCommon - 1);
      for (Block commonBlock : commonBlocks) {
        List<TransactionReceipt> receipts = blockDataGenerator.receipts(commonBlock);
        localBlockchain.appendBlock(commonBlock, receipts);
        remoteChain.appendBlock(commonBlock, receipts);
      }
    }

    // Build divergent local blocks
    if (localBlockCount > blocksInCommon) {
      Block localChainHead = localBlockchain.getChainHeadBlock();
      final int currentHeight =
          Math.toIntExact(
              localBlockchain.getChainHeadBlockNumber() - BlockHeader.GENESIS_BLOCK_NUMBER + 1);
      List<Block> localBlocks =
          blockDataGenerator.blockSequence(localChainHead, localBlockCount - currentHeight);
      for (Block localBlock : localBlocks) {
        List<TransactionReceipt> receipts = blockDataGenerator.receipts(localBlock);
        localBlockchain.appendBlock(localBlock, receipts);
      }
    }

    // Build divergent remote blocks
    if (remoteBlockCount > blocksInCommon) {
      Block remoteChainHead = remoteChain.getChainHeadBlock();
      final int currentHeight =
          Math.toIntExact(
              remoteChain.getChainHeadBlockNumber() - BlockHeader.GENESIS_BLOCK_NUMBER + 1);
      List<Block> remoteBlocks =
          blockDataGenerator.blockSequence(remoteChainHead, remoteBlockCount - currentHeight);
      for (Block remoteBlock : remoteBlocks) {
        List<TransactionReceipt> receipts = blockDataGenerator.receipts(remoteBlock);
        remoteChain.appendBlock(remoteBlock, receipts);
      }
    }

    return remoteChain;
  }
@param localBlockCount The number of local blocks to create. Highest block will be: {@code
    localBlockHeight} - 1.
@param remoteBlockCount The number of remote blocks to create. Highest block will be: {@code
    remoteBlockCount} - 1.
@param blocksInCommon The number of blocks shared between local and remote. If a common
    ancestor exists, its block number will be: {@code blocksInCommon} - 1
@return the test blockchain
ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/tasks/DetermineCommonAncestorTaskTest.java