private static void verifyDifficulty( StoredBlock prevBlock, Block added, BigInteger calcDiff, NetworkParameters params) { if (calcDiff.compareTo(params.getMaxTarget()) > 0) { log.info("Difficulty hit proof of work limit: {}", calcDiff.toString(16)); calcDiff = params.getMaxTarget(); } int accuracyBytes = (int) (added.getDifficultyTarget() >>> 24) - 3; final BigInteger receivedDifficulty = added.getDifficultyTargetAsInteger(); // The calculated difficulty is to a higher precision than received, so reduce here. final BigInteger mask = BigInteger.valueOf(0xFFFFFFL).shiftLeft(accuracyBytes * 8); calcDiff = calcDiff.and(mask); if (CoinDefinition.TEST_NETWORK_STANDARD.equals(params.getStandardNetworkId())) { if (calcDiff.compareTo(receivedDifficulty) != 0) { throw new VerificationException( "Network provided difficulty bits do not match what was calculated: " + receivedDifficulty.toString(16) + " vs " + calcDiff.toString(16)); } } else { final int height = prevBlock.getHeight() + 1; if (height <= 68589) { long nBitsNext = added.getDifficultyTarget(); long calcDiffBits = (accuracyBytes + 3) << 24; calcDiffBits |= calcDiff.shiftRight(accuracyBytes * 8).longValue(); final double n1 = CommonUtils.convertBitsToDouble(calcDiffBits); final double n2 = CommonUtils.convertBitsToDouble(nBitsNext); if (Math.abs(n1 - n2) > n1 * 0.2) { throw new VerificationException( "Network provided difficulty bits do not match what was calculated: " + receivedDifficulty.toString(16) + " vs " + calcDiff.toString(16)); } } else { if (calcDiff.compareTo(receivedDifficulty) != 0) { throw new VerificationException( "Network provided difficulty bits do not match what was calculated: " + receivedDifficulty.toString(16) + " vs " + calcDiff.toString(16)); } } } }
@Override public void verifyDifficultyTransitions( StoredBlock prevBlock, Block added, NetworkParameters params) { int diffMode = 1; final int heightInc = prevBlock.getHeight() + 1; if (CoinDefinition.TEST_NETWORK_STANDARD.equals(params.getStandardNetworkId())) { if (heightInc >= 2000) { diffMode = 4; } } else { if (heightInc >= 68589) { diffMode = 4; } else if (heightInc >= 34140) { diffMode = 3; } else if (heightInc >= 15200) { diffMode = 2; } } try { switch (diffMode) { case 4: darkGravityWave3Check( prevBlock, added, linearExtension.getBlockChain().getBlockStore(), params); return; case 1: linearExtension.verifyDifficultyTransitions(prevBlock, added, params); return; case 2: kimotoGravityWellCheck( prevBlock, added, linearExtension.getBlockChain().getBlockStore(), params); return; case 3: darkGravityWaveCheck( prevBlock, added, linearExtension.getBlockChain().getBlockStore(), params); return; default: throw new RuntimeException("Unreachable"); } } catch (BlockStoreException ex) { throw new VerificationException( "Block store exception during difficulty transitions check", ex); } }