private static void darkGravityWave3Check( StoredBlock prevBlock, Block added, BlockStore store, NetworkParameters params) { StoredBlock blockReading = prevBlock; long actualTimespan = 0; long lastBlockTime = 0; long pastBlocksMin = 24; long pastBlocksMax = 24; long countBlocks = 0; BigInteger pastDifficultyAverage = BigInteger.ZERO; BigInteger pastDifficultyAveragePrev = BigInteger.ZERO; if (prevBlock == null || prevBlock.getHeight() == 0 || prevBlock.getHeight() < pastBlocksMin) { verifyDifficulty(prevBlock, added, params.getMaxTarget(), params); return; } for (int i = 1; blockReading.getHeight() > 0; i++) { if (i > pastBlocksMax) { break; } countBlocks++; if (countBlocks <= pastBlocksMin) { if (countBlocks == 1) { pastDifficultyAverage = blockReading.getHeader().getDifficultyTargetAsInteger(); } else { pastDifficultyAverage = pastDifficultyAveragePrev .multiply(BigInteger.valueOf(countBlocks)) .add(blockReading.getHeader().getDifficultyTargetAsInteger()) .divide(BigInteger.valueOf(countBlocks + 1)); } pastDifficultyAveragePrev = pastDifficultyAverage; } if (lastBlockTime > 0) { actualTimespan += (lastBlockTime - blockReading.getHeader().getTimeSeconds()); } lastBlockTime = blockReading.getHeader().getTimeSeconds(); try { blockReading = store.get(blockReading.getHeader().getPrevBlockHash()); if (blockReading == null) { return; } } catch (BlockStoreException ex) { log.warn("Dark gravity wave 3 descended to start of the chain"); return; } } BigInteger bnNew = pastDifficultyAverage; long targetTimespan = countBlocks * params.getTargetSpacing(prevBlock.getHeader(), prevBlock.getHeight()); if (actualTimespan < targetTimespan / 3) { actualTimespan = targetTimespan / 3; } if (actualTimespan > targetTimespan * 3) { actualTimespan = targetTimespan * 3; } // Retarget bnNew = bnNew.multiply(BigInteger.valueOf(actualTimespan)); bnNew = bnNew.divide(BigInteger.valueOf(targetTimespan)); verifyDifficulty(prevBlock, added, bnNew, params); }
private static void darkGravityWaveCheck( StoredBlock prevBlock, Block added, BlockStore store, NetworkParameters params) { StoredBlock blockReading = prevBlock; long blockTimeAverage = 0; long blockTimeAveragePrev = 0; long blockTimeCount = 0; long blockTimeSum2 = 0; long blockTimeCount2 = 0; long lastBlockTime = 0; long pastBlocksMin = 14; long pastBlocksMax = 140; long countBlocks = 0; BigInteger pastDifficultyAverage = BigInteger.valueOf(0); BigInteger pastDifficultyAveragePrev = BigInteger.valueOf(0); if (prevBlock == null || prevBlock.getHeight() == 0 || prevBlock.getHeight() < pastBlocksMin) { verifyDifficulty(prevBlock, added, params.getMaxTarget(), params); return; } for (int i = 1; blockReading.getHeight() > 0; i++) { if (i > pastBlocksMax) { break; } countBlocks++; if (countBlocks <= pastBlocksMin) { if (countBlocks == 1) { pastDifficultyAverage = blockReading.getHeader().getDifficultyTargetAsInteger(); } else { pastDifficultyAverage = blockReading .getHeader() .getDifficultyTargetAsInteger() .subtract(pastDifficultyAveragePrev) .divide(BigInteger.valueOf(countBlocks)) .add(pastDifficultyAveragePrev); } pastDifficultyAveragePrev = pastDifficultyAverage; } if (lastBlockTime > 0) { long diff = lastBlockTime - blockReading.getHeader().getTimeSeconds(); if (blockTimeCount <= pastBlocksMin) { blockTimeCount++; if (blockTimeCount == 1) { blockTimeAverage = diff; } else { blockTimeAverage = (diff - blockTimeAveragePrev) / blockTimeCount + blockTimeAveragePrev; } blockTimeAveragePrev = blockTimeAverage; } blockTimeCount2++; blockTimeSum2 += diff; } lastBlockTime = blockReading.getHeader().getTimeSeconds(); try { blockReading = store.get(blockReading.getHeader().getPrevBlockHash()); if (blockReading == null) { return; } } catch (BlockStoreException ex) { log.warn("Dark gravity wave 3 descended to start of the chain"); return; } } BigInteger bnNew = pastDifficultyAverage; if (blockTimeCount != 0 && blockTimeCount2 != 0) { double smartAverage = ((double) blockTimeAverage) * 0.7 + ((double) blockTimeSum2 / (double) blockTimeCount2) * 0.3; if (smartAverage < 1) smartAverage = 1; final int targetSpacing = params.getTargetSpacing(prevBlock.getHeader(), prevBlock.getHeight()); final double shift = targetSpacing / smartAverage; final double dCountBlocks = (double) countBlocks; double actualTimespan = dCountBlocks * ((double) targetSpacing) / shift; double targetTimespan = dCountBlocks * targetSpacing; if (actualTimespan < targetTimespan / 3) actualTimespan = targetTimespan / 3; if (actualTimespan > targetTimespan * 3) actualTimespan = targetTimespan * 3; // Retarget bnNew = bnNew.multiply(BigInteger.valueOf((long) actualTimespan)); bnNew = bnNew.divide(BigInteger.valueOf((long) targetTimespan)); } verifyDifficulty(prevBlock, added, bnNew, params); }