Program: 34985
Project: 34985
Buggy source:
/** 
 * 计算账户的余额，这个方法应该和获取余额方法互斥，避免并发导致数据不准确
 * @param address
 * @return
 * @throws NulsException
 */
public Balance calBalanceByAddress(byte[] address) throws NulsException {
  lock.lock();
  try {
    if (accountService.getAccount(address).isFailed()) {
      return null;
    }
    List<Coin> coinList=getCoinListByAddress(address);
    Collections.sort(coinList,CoinComparator.getInstance());
    BalanceCacheEntity balanceCacheEntity=new BalanceCacheEntity();
    Na usable=Na.ZERO;
    Na locked=Na.ZERO;
    for (    Coin coin : coinList) {
      if (coin.usable()) {
        usable=usable.add(coin.getNa());
      }
 else {
        locked=locked.add(coin.getNa());
        long lockTime=coin.getLockTime();
        if (lockTime <= 0L) {
          continue;
        }
        if (balanceCacheEntity.getLowestLockHeigh() == 0L || (lockTime < NulsConstant.BlOCKHEIGHT_TIME_DIVIDE && lockTime < balanceCacheEntity.getLowestLockHeigh())) {
          balanceCacheEntity.setLowestLockHeigh(lockTime);
          continue;
        }
        if (balanceCacheEntity.getEarlistLockTime() == 0L || (lockTime > NulsConstant.BlOCKHEIGHT_TIME_DIVIDE && lockTime < balanceCacheEntity.getEarlistLockTime())) {
          balanceCacheEntity.setEarlistLockTime(lockTime);
          continue;
        }
      }
    }
    Balance balance=new Balance();
    balance.setUsable(usable);
    balance.setLocked(locked);
    balance.setBalance(usable.add(locked));
    balanceCacheEntity.setBalance(balance);
    balanceMap.put(Base58.encode(address),balanceCacheEntity);
    return balance;
  }
  finally {
    lock.unlock();
  }
}

Fixed version (ground truth):
/** 
 * 计算账户的余额，这个方法应该和获取余额方法互斥，避免并发导致数据不准确
 */
public Balance calBalanceByAddress(byte[] address) throws NulsException {
  lock.lock();
  try {
    if (accountService.getAccount(address).isFailed()) {
      return null;
    }
    List<Coin> coinList=getCoinListByAddress(address);
    Collections.sort(coinList,CoinComparator.getInstance());
    BalanceCacheEntity balanceCacheEntity=new BalanceCacheEntity();
    Na usable=Na.ZERO;
    Na locked=Na.ZERO;
    for (    Coin coin : coinList) {
      if (coin.usable()) {
        usable=usable.add(coin.getNa());
      }
 else {
        locked=locked.add(coin.getNa());
        long lockTime=coin.getLockTime();
        if (lockTime <= 0L) {
          continue;
        }
        if (balanceCacheEntity.getLowestLockHeigh() == 0L || (lockTime < NulsConstant.BlOCKHEIGHT_TIME_DIVIDE && lockTime < balanceCacheEntity.getLowestLockHeigh())) {
          balanceCacheEntity.setLowestLockHeigh(lockTime);
          continue;
        }
        if (balanceCacheEntity.getEarlistLockTime() == 0L || (lockTime > NulsConstant.BlOCKHEIGHT_TIME_DIVIDE && lockTime < balanceCacheEntity.getEarlistLockTime())) {
          balanceCacheEntity.setEarlistLockTime(lockTime);
          continue;
        }
      }
    }
    Balance balance=new Balance();
    balance.setUsable(usable);
    balance.setLocked(locked);
    balance.setBalance(usable.add(locked));
    balanceCacheEntity.setBalance(balance);
    balanceMap.put(Base58.encode(address),balanceCacheEntity);
    return balance;
  }
  finally {
    lock.unlock();
  }
}