Program: 10958
Project: 10958
Buggy source:
public void verifyDifficultyFromPreviousBlock(Block prev){
  if ((prev.getBlockNo() + 1) % BitherjSettings.BLOCK_DIFFICULTY_INTERVAL != 0) {
    if (this.getBlockBits() != prev.getBlockBits())     throw new VerificationException("String_Node_Str" + prev.getBlockNo() + "String_Node_Str"+ Long.toHexString(this.getBlockBits())+ "String_Node_Str"+ Long.toHexString(prev.getBlockBits()));
    return;
  }
  long now=System.currentTimeMillis();
  Block cursor=get(prev.getBlockHash());
  for (int i=0; i < BitherjSettings.BLOCK_DIFFICULTY_INTERVAL - 1; i++) {
    if (cursor == null) {
      throw new VerificationException("String_Node_Str");
    }
    cursor=get(cursor.getBlockPrev());
  }
  long elapsed=System.currentTimeMillis() - now;
  if (elapsed > 50)   log.info("String_Node_Str",elapsed);
  Block blockIntervalAgo=cursor;
  int timespan=(int)(prev.getBlockTime() - blockIntervalAgo.getBlockTime());
  final int targetTimespan=BitherjSettings.TARGET_TIMESPAN;
  if (timespan < targetTimespan / 4)   timespan=targetTimespan / 4;
  if (timespan > targetTimespan * 4)   timespan=targetTimespan * 4;
  BigInteger newDifficulty=Utils.decodeCompactBits(prev.getBlockBits());
  newDifficulty=newDifficulty.multiply(BigInteger.valueOf(timespan));
  newDifficulty=newDifficulty.divide(BigInteger.valueOf(targetTimespan));
  if (newDifficulty.compareTo(BitherjSettings.proofOfWorkLimit) > 0) {
    newDifficulty=BitherjSettings.proofOfWorkLimit;
  }
  int accuracyBytes=(int)(this.getBlockBits() >>> 24) - 3;
  BigInteger receivedDifficulty=this.getDifficultyTargetAsInteger();
  BigInteger mask=BigInteger.valueOf(0xFFFFFFL).shiftLeft(accuracyBytes * 8);
  newDifficulty=newDifficulty.and(mask);
  if (newDifficulty.compareTo(receivedDifficulty) != 0)   throw new VerificationException("String_Node_Str" + receivedDifficulty.toString(16) + "String_Node_Str"+ newDifficulty.toString(16));
}

Fixed version (ground truth):
public void verifyDifficultyFromPreviousBlock(Block prev,int transitionTime){
  if ((prev.getBlockNo() + 1) % BitherjSettings.BLOCK_DIFFICULTY_INTERVAL != 0) {
    if (this.getBlockBits() != prev.getBlockBits())     throw new VerificationException("String_Node_Str" + prev.getBlockNo() + "String_Node_Str"+ Long.toHexString(this.getBlockBits())+ "String_Node_Str"+ Long.toHexString(prev.getBlockBits()));
    return;
  }
  int timespan=(int)(prev.getBlockTime() - transitionTime);
  final int targetTimespan=BitherjSettings.TARGET_TIMESPAN;
  if (timespan < targetTimespan / 4)   timespan=targetTimespan / 4;
  if (timespan > targetTimespan * 4)   timespan=targetTimespan * 4;
  BigInteger newDifficulty=Utils.decodeCompactBits(prev.getBlockBits());
  newDifficulty=newDifficulty.multiply(BigInteger.valueOf(timespan));
  newDifficulty=newDifficulty.divide(BigInteger.valueOf(targetTimespan));
  if (newDifficulty.compareTo(BitherjSettings.proofOfWorkLimit) > 0) {
    newDifficulty=BitherjSettings.proofOfWorkLimit;
  }
  int accuracyBytes=(int)(this.getBlockBits() >>> 24) - 3;
  BigInteger receivedDifficulty=this.getDifficultyTargetAsInteger();
  BigInteger mask=BigInteger.valueOf(0xFFFFFFL).shiftLeft(accuracyBytes * 8);
  newDifficulty=newDifficulty.and(mask);
  if (newDifficulty.compareTo(receivedDifficulty) != 0)   throw new VerificationException("String_Node_Str" + receivedDifficulty.toString(16) + "String_Node_Str"+ newDifficulty.toString(16));
}