mirror of
https://github.com/Qortal/altcoinj.git
synced 2025-01-30 23:02:15 +00:00
Modified Dogecoin difficulty calculations to use next expected target to determine precision.
This commit is contained in:
parent
95db3b960e
commit
355ea2d50e
@ -211,7 +211,8 @@ public abstract class AbstractDogecoinParams extends NetworkParameters implement
|
|||||||
|
|
||||||
Block blockIntervalAgo = cursor.getHeader();
|
Block blockIntervalAgo = cursor.getHeader();
|
||||||
long receivedTargetCompact = nextBlock.getDifficultyTarget();
|
long receivedTargetCompact = nextBlock.getDifficultyTarget();
|
||||||
long newTargetCompact = this.getNewDifficultyTarget(previousHeight, prev, blockIntervalAgo);
|
long newTargetCompact = this.getNewDifficultyTarget(previousHeight, prev,
|
||||||
|
nextBlock, blockIntervalAgo);
|
||||||
|
|
||||||
if (newTargetCompact != receivedTargetCompact)
|
if (newTargetCompact != receivedTargetCompact)
|
||||||
throw new VerificationException("Network provided difficulty bits do not match what was calculated: " +
|
throw new VerificationException("Network provided difficulty bits do not match what was calculated: " +
|
||||||
@ -220,14 +221,17 @@ public abstract class AbstractDogecoinParams extends NetworkParameters implement
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
* @param previousHeight height of the block immediately before the retarget.
|
||||||
* @param prev the block immediately before the retarget block.
|
* @param prev the block immediately before the retarget block.
|
||||||
|
* @param nextBlock the block the retarget happens at.
|
||||||
* @param blockIntervalAgo The last retarget block.
|
* @param blockIntervalAgo The last retarget block.
|
||||||
* @return New difficulty target as compact bytes.
|
* @return New difficulty target as compact bytes.
|
||||||
*/
|
*/
|
||||||
public long getNewDifficultyTarget(int previousHeight, final Block prev,
|
public long getNewDifficultyTarget(int previousHeight, final Block prev, final Block nextBlock,
|
||||||
final Block blockIntervalAgo) {
|
final Block blockIntervalAgo) {
|
||||||
return this.getNewDifficultyTarget(previousHeight, prev.getTimeSeconds(),
|
return this.getNewDifficultyTarget(previousHeight, prev.getTimeSeconds(),
|
||||||
blockIntervalAgo.getDifficultyTarget(), blockIntervalAgo.getTimeSeconds());
|
prev.getDifficultyTarget(), blockIntervalAgo.getTimeSeconds(),
|
||||||
|
nextBlock.getDifficultyTarget());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -236,10 +240,13 @@ public abstract class AbstractDogecoinParams extends NetworkParameters implement
|
|||||||
* @param previousBlockTime Time of the block immediately previous to the one we're calculating difficulty of.
|
* @param previousBlockTime Time of the block immediately previous to the one we're calculating difficulty of.
|
||||||
* @param lastDifficultyTarget Compact difficulty target of the last retarget block.
|
* @param lastDifficultyTarget Compact difficulty target of the last retarget block.
|
||||||
* @param lastRetargetTime Time of the last difficulty retarget.
|
* @param lastRetargetTime Time of the last difficulty retarget.
|
||||||
|
* @param nextDifficultyTarget The expected difficulty target of the next
|
||||||
|
* block, used for determining precision of the result.
|
||||||
* @return New difficulty target as compact bytes.
|
* @return New difficulty target as compact bytes.
|
||||||
*/
|
*/
|
||||||
public long getNewDifficultyTarget(int previousHeight, long previousBlockTime,
|
protected long getNewDifficultyTarget(int previousHeight, long previousBlockTime,
|
||||||
final long lastDifficultyTarget, final long lastRetargetTime) {
|
final long lastDifficultyTarget, final long lastRetargetTime,
|
||||||
|
final long nextDifficultyTarget) {
|
||||||
final int height = previousHeight + 1;
|
final int height = previousHeight + 1;
|
||||||
final boolean digishieldAlgorithm = height >= this.getDigishieldBlockHeight();
|
final boolean digishieldAlgorithm = height >= this.getDigishieldBlockHeight();
|
||||||
final int retargetTimespan = digishieldAlgorithm
|
final int retargetTimespan = digishieldAlgorithm
|
||||||
@ -287,7 +294,7 @@ public abstract class AbstractDogecoinParams extends NetworkParameters implement
|
|||||||
newTarget = this.getMaxTarget();
|
newTarget = this.getMaxTarget();
|
||||||
}
|
}
|
||||||
|
|
||||||
int accuracyBytes = (int) (lastDifficultyTarget >>> 24) - 3;
|
int accuracyBytes = (int) (nextDifficultyTarget >>> 24) - 3;
|
||||||
|
|
||||||
// The calculated difficulty is to a higher precision than received, so reduce here.
|
// The calculated difficulty is to a higher precision than received, so reduce here.
|
||||||
BigInteger mask = BigInteger.valueOf(0xFFFFFFL).shiftLeft(accuracyBytes * 8);
|
BigInteger mask = BigInteger.valueOf(0xFFFFFFL).shiftLeft(accuracyBytes * 8);
|
||||||
|
@ -18,6 +18,7 @@ package org.libdohj.params;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import org.bitcoinj.core.AltcoinBlock;
|
import org.bitcoinj.core.AltcoinBlock;
|
||||||
import org.bitcoinj.core.Context;
|
import org.bitcoinj.core.Context;
|
||||||
|
import org.bitcoinj.core.Sha256Hash;
|
||||||
import org.bitcoinj.core.Util;
|
import org.bitcoinj.core.Util;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
@ -42,14 +43,20 @@ public class AbstractDogecoinParamsTest {
|
|||||||
long previousBlockTime = 1386475638; // Block 239
|
long previousBlockTime = 1386475638; // Block 239
|
||||||
long lastRetargetDifficulty = 0x1e0ffff0;
|
long lastRetargetDifficulty = 0x1e0ffff0;
|
||||||
long lastRetargetTime = 1386474927; // Block 1
|
long lastRetargetTime = 1386474927; // Block 1
|
||||||
long newDifficulty = params.getNewDifficultyTarget(previousHeight, previousBlockTime, lastRetargetDifficulty, lastRetargetTime);
|
long nextDifficulty = 0x1e00ffff;
|
||||||
|
long newDifficulty =
|
||||||
|
params.getNewDifficultyTarget(previousHeight, previousBlockTime,
|
||||||
|
lastRetargetDifficulty, lastRetargetTime, nextDifficulty);
|
||||||
assertEquals(0x1e00ffff, newDifficulty);
|
assertEquals(0x1e00ffff, newDifficulty);
|
||||||
|
|
||||||
previousHeight = 9599;
|
previousHeight = 9599;
|
||||||
previousBlockTime = 1386954113;
|
previousBlockTime = 1386954113;
|
||||||
lastRetargetDifficulty = 0x1c1a1206;
|
lastRetargetDifficulty = 0x1c1a1206;
|
||||||
lastRetargetTime = 1386942008; // Block 9359
|
lastRetargetTime = 1386942008; // Block 9359
|
||||||
newDifficulty = params.getNewDifficultyTarget(previousHeight, previousBlockTime, lastRetargetDifficulty, lastRetargetTime);
|
nextDifficulty = 0x1c15ea59;
|
||||||
|
newDifficulty =
|
||||||
|
params.getNewDifficultyTarget(previousHeight, previousBlockTime,
|
||||||
|
lastRetargetDifficulty, lastRetargetTime, nextDifficulty);
|
||||||
assertEquals(0x1c15ea59, newDifficulty);
|
assertEquals(0x1c15ea59, newDifficulty);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,51 +66,73 @@ public class AbstractDogecoinParamsTest {
|
|||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void shouldConstrainActualTime() {
|
public void shouldConstrainActualTime() {
|
||||||
int previousHeight = 719;
|
final int previousHeight = 719;
|
||||||
long previousBlockTime = 1386476362; // Block 719
|
final long previousBlockTime = 1386476362; // Block 719
|
||||||
long lastRetargetDifficulty = 0x1e00ffff;
|
final long lastRetargetDifficulty = 0x1e00ffff;
|
||||||
long lastRetargetTime = 1386475840; // Block 439
|
final long lastRetargetTime = 1386475840; // Block 479
|
||||||
long newDifficulty = params.getNewDifficultyTarget(previousHeight, previousBlockTime, lastRetargetDifficulty, lastRetargetTime);
|
final long nextDifficulty = 0x1d0ffff0; // Block 720
|
||||||
|
final long newDifficulty =
|
||||||
|
params.getNewDifficultyTarget(previousHeight, previousBlockTime,
|
||||||
|
lastRetargetDifficulty, lastRetargetTime, nextDifficulty);
|
||||||
assertEquals(0x1d0ffff0, newDifficulty);
|
assertEquals(0x1d0ffff0, newDifficulty);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void shouldCalculateDigishieldDifficulty() {
|
public void shouldCalculateDigishieldDifficulty() {
|
||||||
int previousHeight = 145000;
|
final int previousHeight = 145000;
|
||||||
long previousBlockTime = 1395094679;
|
final long previousBlockTime = 1395094679;
|
||||||
long lastRetargetDifficulty = 0x1b499dfd;
|
final long lastRetargetDifficulty = 0x1b499dfd;
|
||||||
long lastRetargetTime = 1395094427;
|
final long lastRetargetTime = 1395094427;
|
||||||
long newDifficulty = params.getNewDifficultyTarget(previousHeight, previousBlockTime, lastRetargetDifficulty, lastRetargetTime);
|
final long nextDifficulty = 0x1b671062;
|
||||||
|
final long newDifficulty =
|
||||||
|
params.getNewDifficultyTarget(previousHeight, previousBlockTime,
|
||||||
|
lastRetargetDifficulty, lastRetargetTime, nextDifficulty);
|
||||||
assertEquals(0x1b671062, newDifficulty);
|
assertEquals(0x1b671062, newDifficulty);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void shouldCalculateDigishieldDifficultyRounding() {
|
public void shouldCalculateDigishieldDifficultyRounding() {
|
||||||
// Test case for correct rounding of modulated time
|
// Test case for correct rounding of modulated time
|
||||||
int previousHeight = 145001;
|
final int previousHeight = 145001;
|
||||||
long previousBlockTime = 1395094727;
|
final long previousBlockTime = 1395094727;
|
||||||
long lastRetargetDifficulty = 0x1b671062;
|
final long lastRetargetDifficulty = 0x1b671062;
|
||||||
long lastRetargetTime = 1395094679;
|
final long lastRetargetTime = 1395094679;
|
||||||
long newDifficulty = params.getNewDifficultyTarget(previousHeight, previousBlockTime, lastRetargetDifficulty, lastRetargetTime);
|
final long nextDifficulty = 0x1b6558a4;
|
||||||
|
final long newDifficulty =
|
||||||
|
params.getNewDifficultyTarget(previousHeight, previousBlockTime,
|
||||||
|
lastRetargetDifficulty, lastRetargetTime, nextDifficulty);
|
||||||
assertEquals(0x1b6558a4, newDifficulty);
|
assertEquals(0x1b6558a4, newDifficulty);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void shouldCalculateRetarget() throws IOException {
|
public void shouldCalculateRetarget() throws IOException {
|
||||||
// Do a more in-depth test for the first retarget
|
// Do a more in-depth test for the first retarget
|
||||||
byte[] payload = Util.getBytes(getClass().getResourceAsStream("dogecoin_block239.bin"));
|
byte[] payload;
|
||||||
AltcoinSerializer serializer = (AltcoinSerializer)params.getDefaultSerializer();
|
AltcoinSerializer serializer = (AltcoinSerializer)params.getDefaultSerializer();
|
||||||
final AltcoinBlock block239 = (AltcoinBlock)serializer.makeBlock(payload);
|
final AltcoinBlock block239;
|
||||||
final AltcoinBlock block479;
|
final AltcoinBlock block479;
|
||||||
|
final AltcoinBlock block480;
|
||||||
final AltcoinBlock block719;
|
final AltcoinBlock block719;
|
||||||
|
final AltcoinBlock block720;
|
||||||
|
|
||||||
|
payload = Util.getBytes(getClass().getResourceAsStream("dogecoin_block239.bin"));
|
||||||
|
block239 = (AltcoinBlock)serializer.makeBlock(payload);
|
||||||
payload = Util.getBytes(getClass().getResourceAsStream("dogecoin_block479.bin"));
|
payload = Util.getBytes(getClass().getResourceAsStream("dogecoin_block479.bin"));
|
||||||
block479 = (AltcoinBlock)serializer.makeBlock(payload);
|
block479 = (AltcoinBlock)serializer.makeBlock(payload);
|
||||||
|
payload = Util.getBytes(getClass().getResourceAsStream("dogecoin_block480.bin"));
|
||||||
|
block480 = (AltcoinBlock)serializer.makeBlock(payload);
|
||||||
payload = Util.getBytes(getClass().getResourceAsStream("dogecoin_block719.bin"));
|
payload = Util.getBytes(getClass().getResourceAsStream("dogecoin_block719.bin"));
|
||||||
block719 = (AltcoinBlock)serializer.makeBlock(payload);
|
block719 = (AltcoinBlock)serializer.makeBlock(payload);
|
||||||
|
payload = Util.getBytes(getClass().getResourceAsStream("dogecoin_block720.bin"));
|
||||||
|
block720 = (AltcoinBlock)serializer.makeBlock(payload);
|
||||||
|
|
||||||
assertEquals(0x1e00ffff, params.getNewDifficultyTarget(479, block239, block479));
|
assertEquals(Sha256Hash.wrap("f9533416310fc4484cf43405a858b06afc9763ad401d267c1835d77e7d225a4e"), block239.getHash());
|
||||||
assertEquals(0x1d0ffff0, params.getNewDifficultyTarget(719, block479, block719));
|
assertEquals(Sha256Hash.wrap("ed83c923b532835f6597f70def42910aa9e06880e8a19b68f6b4a787f2b4b69f"), block479.getHash());
|
||||||
|
assertEquals(Sha256Hash.wrap("a0e6d1cdef02b394d31628c3281f67e8534bec74fda1a4294b58be80c3fdf3f3"), block480.getHash());
|
||||||
|
assertEquals(Sha256Hash.wrap("82e56e141ccfe019d475382d9a108ef86afeb297d95443dfd7250e57af805696"), block719.getHash());
|
||||||
|
assertEquals(Sha256Hash.wrap("6b34f1a7de1954beb0ddf100bb2b618ff0183b6ae2b4a9376721ef8e04ab3b39"), block720.getHash());
|
||||||
|
|
||||||
|
assertEquals(block480.getDifficultyTarget(), params.getNewDifficultyTarget(479, block479, block480, block239));
|
||||||
|
assertEquals(block720.getDifficultyTarget(), params.getNewDifficultyTarget(719, block719, block720, block479));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
BIN
src/test/resources/org/libdohj/params/dogecoin_block480.bin
Normal file
BIN
src/test/resources/org/libdohj/params/dogecoin_block480.bin
Normal file
Binary file not shown.
BIN
src/test/resources/org/libdohj/params/dogecoin_block720.bin
Normal file
BIN
src/test/resources/org/libdohj/params/dogecoin_block720.bin
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user