@Override
 public BlockchainImpl getBlockchain() {
   if (blockchain == null) {
     blockchain = createBlockchain(genesis);
     blockchain.setMinerCoinbase(coinbase);
   }
   return blockchain;
 }
  private BlockchainImpl createBlockchain(Genesis genesis) {
    IndexedBlockStore blockStore = new IndexedBlockStore();
    blockStore.init(new HashMapDB(), new HashMapDB());

    Repository repository = new RepositoryImpl(new HashMapDB(), new HashMapDB());

    ProgramInvokeFactoryImpl programInvokeFactory = new ProgramInvokeFactoryImpl();
    EthereumListenerAdapter listener = new EthereumListenerAdapter();

    BlockchainImpl blockchain = new BlockchainImpl(blockStore, repository);
    blockchain.setParentHeaderValidator(new DependentBlockHeaderRuleAdapter());
    blockchain.setProgramInvokeFactory(programInvokeFactory);
    programInvokeFactory.setBlockchain(blockchain);

    blockchain.byTest = true;

    PendingStateImpl pendingState = new PendingStateImpl(listener, blockchain);

    pendingState.init();

    pendingState.setBlockchain(blockchain);
    blockchain.setPendingState(pendingState);

    Repository track = repository.startTracking();
    for (ByteArrayWrapper key : genesis.getPremine().keySet()) {
      track.createAccount(key.getData());
      track.addBalance(key.getData(), genesis.getPremine().get(key).getBalance());
    }
    for (Pair<byte[], BigInteger> acc : initialBallances) {
      track.createAccount(acc.getLeft());
      track.addBalance(acc.getLeft(), acc.getRight());
    }

    track.commit();

    blockStore.saveBlock(genesis, genesis.getCumulativeDifficulty(), true);

    blockchain.setBestBlock(genesis);
    blockchain.setTotalDifficulty(genesis.getCumulativeDifficulty());

    return blockchain;
  }
/**
 * Economic Clustering concept (EC) solves the most critical flaw of "classical" Proof-of-Stake -
 * the problem called "Nothing-at-Stake".
 *
 * <p>I ought to respect BCNext's wish and say that this concept is inspired by Economic Majority
 * idea of Meni Rosenfeld (http://en.wikipedia.org/wiki/User:Meni_Rosenfeld).
 *
 * <p>EC is a vital part of Transparent Forging. Words "Mining in Nxt relies on cooperation of
 * people and even forces it" (https://bitcointalk.org/index.php?topic=553205.0) were said about EC.
 *
 * <p>Keep in mind that this concept has not been peer reviewed. You are very welcome to do it...
 *
 * <p>Come-from-Beyond (21.05.2014)
 */
public final class EconomicClustering {

  private static final Blockchain blockchain = BlockchainImpl.getInstance();

  public static Block getECBlock(int timestamp) {
    Block block = blockchain.getLastBlock();
    if (timestamp < block.getTimestamp() - 15) {
      throw new IllegalArgumentException(
          "Timestamp cannot be more than 15 s earlier than last block timestamp: "
              + block.getTimestamp());
    }
    int distance = 0;
    while (block.getTimestamp() > timestamp - Constants.EC_RULE_TERMINATOR
        && distance < Constants.EC_BLOCK_DISTANCE_LIMIT) {
      block = blockchain.getBlock(block.getPreviousBlockId());
      distance += 1;
    }
    return block;
  }

  public static boolean verifyFork(Transaction transaction) {
    if (blockchain.getHeight() < Constants.DIGITAL_GOODS_STORE_BLOCK) {
      return true;
    }
    if (transaction.getReferencedTransactionFullHash() != null) {
      return true;
    }
    if (blockchain.getHeight() < Constants.EC_CHANGE_BLOCK_1) {
      if (blockchain.getHeight() - transaction.getECBlockHeight()
          > Constants.EC_BLOCK_DISTANCE_LIMIT) {
        return false;
      }
    }
    Block ecBlock = blockchain.getBlock(transaction.getECBlockId());
    return ecBlock != null && ecBlock.getHeight() == transaction.getECBlockHeight();
  }
}