Add support for all 3 difficulty calculation algorithms

This commit is contained in:
Sky Young 2018-05-21 13:08:47 -07:00
parent d2d2400a8e
commit f6aaf70c3d
2 changed files with 126 additions and 15 deletions

View File

@ -395,6 +395,8 @@ Chain.prototype.verify = async function verify(block, prev, flags) {
// Ensure the POW is what we expect.
const bits = await this.getTarget(block.time, prev);
// console.log(block.bits, bits);
if (block.bits !== bits) {
throw new VerifyError(block,
'invalid',
@ -2278,15 +2280,41 @@ Chain.prototype.getTarget = async function getTarget(time, prev) {
return pow.bits;
}
let retargetInterval, targetSpacing, averagingInterval;
if (prev.height < pow.blockHeight_version2){
retargetInterval = pow.retargetInterval_version1;
targetSpacing = pow.targetSpacing_version1;
averagingInterval = pow.averagingInterval_version1;
} else if (prev.height >= pow.blockHeight_version2 && prev.height < pow.blockHeight_version3){
retargetInterval = pow.retargetInterval_version2;
targetSpacing = pow.targetSpacing_version2;
averagingInterval = pow.averagingInterval_version2;
} else if (prev.height >= pow.blockHeight_version3) {
retargetInterval = pow.retargetInterval_version3;
targetSpacing = pow.targetSpacing_version3;
averagingInterval = pow.averagingInterval_version3;
}
// Do not retarget
if ((prev.height + 1) % pow.retargetInterval !== 0) {
if ((prev.height + 1) % retargetInterval !== 0) {
if (pow.targetReset) {
// Special behavior for testnet:
if (time > prev.time + pow.targetSpacing * 2)
return pow.bits;
// console.log("Time: " + time)
// console.log("Prev Time: " + prev.time)
// console.log("Target Spacing*2: " + (targetSpacing * 2))
// console.log("prev+targ: " + (prev.time + targetSpacing * 2))
if (time > prev.time + targetSpacing * 2)
return prev.bits;
while (prev.height !== 0
&& prev.height % pow.retargetInterval !== 0
&& prev.height % retargetInterval !== 0
&& prev.bits === pow.bits) {
const cache = this.getPrevCache(prev);
@ -2302,11 +2330,11 @@ Chain.prototype.getTarget = async function getTarget(time, prev) {
}
// Back 6 block
var back = pow.averagingInterval - 1;
var back = averagingInterval - 1;
if (prev.height + 1 !== pow.averagingInterval)
back = pow.averagingInterval;
if (prev.height + 1 !== averagingInterval)
back = averagingInterval;
let first = prev;
@ -2330,38 +2358,77 @@ Chain.prototype.getTarget = async function getTarget(time, prev) {
Chain.prototype.retarget = function retarget(prev, first) {
const pow = this.network.pow;
const targetTimespan = pow.targetTimespan;
const averagingIntervalTimespan = pow.averagingIntervalTimespan;
const targetSpacing = pow.targetSpacing;
const adjustUp = pow.adjustUp;
const adjustDown = pow.adjustDown;
let height = prev.height;
let targetTimespan, averagingIntervalTimespan, targetSpacing, adjustUp, adjustDown;
if (height < pow.blockHeight_version2){
targetTimespan = pow.targetTimespan_version1;
averagingIntervalTimespan = pow.averagingIntervalTimespan_version1;
targetSpacing = pow.targetSpacing_version1;
adjustUp = pow.adjustUp_version1;
adjustDown = pow.adjustDown_version1;
} else if (height >= pow.blockHeight_version2 && height < pow.blockHeight_version3){
targetTimespan = pow.targetTimespan_version2;
averagingIntervalTimespan = pow.averagingIntervalTimespan_version2;
targetSpacing = pow.targetSpacing_version2;
adjustUp = pow.adjustUp_version2;
adjustDown = pow.adjustDown_version2;
} else if (height >= pow.blockHeight_version3) {
targetTimespan = pow.targetTimespan_version3;
averagingIntervalTimespan = pow.averagingIntervalTimespan_version3;
targetSpacing = pow.targetSpacing_version3;
adjustUp = pow.adjustUp_version3;
adjustDown = pow.adjustDown_version3;
} else {
// Difficulty NOT handled?!?
}
if (pow.noRetargeting)
return prev.bits;
let actualTimespan = prev.time - first.time;
// console.log("Actual Timespan: " + actualTimespan);
let minActualTimespan = Math.floor(averagingIntervalTimespan * (100 - adjustUp) / 100)
let maxActualTimespan = Math.floor(averagingIntervalTimespan * (100 + adjustDown) / 100)
// console.log("minActualTimespan: " + minActualTimespan);
// console.log("maxActualTimespan: " + maxActualTimespan);
if (actualTimespan < minActualTimespan)
actualTimespan = minActualTimespan;
// console.log("New Actual Timespan: " + actualTimespan)
if (actualTimespan > maxActualTimespan)
actualTimespan = maxActualTimespan;
// console.log("New Actual Timespan: " + actualTimespan)
// Retarget
let target = consensus.fromCompact(prev.bits);
// console.log("Target: " + target)
target.imuln(actualTimespan);
// console.log("imuln: " + target)
target.idivn(targetTimespan);
// console.log("idivn: " + target)
if (target.gt(pow.limit))
return pow.bits;
// console.log("gt: " + target)
return consensus.toCompact(target);
};

View File

@ -267,6 +267,30 @@ main.pow = {
adjustDown: 3,
targetTimespan_version1: 60 * 60,
targetSpacing_version1: 40,
retargetInterval_version1: (60 * 60) / 40,
averagingInterval_version1: (60 * 60) / 40,
averagingIntervalTimespan_version1: ((60 * 60) / 40) * 40,
adjustUp_version1: 75,
adjustDown_version1: 300,
blockHeight_version2: 208440,
targetTimespan_version2: 15 * 40,
targetSpacing_version2: 40,
retargetInterval_version2: 15,
averagingInterval_version2: 15,
averagingIntervalTimespan_version2: 15 * 40,
adjustUp_version2: 75,
adjustDown_version2: 300,
blockHeight_version3: 426000,
targetTimespan_version3: 6 * 40,
targetSpacing_version3: 40,
retargetInterval_version3: 1,
averagingInterval_version3: 6,
averagingIntervalTimespan_version3: 6 * 40,
adjustUp_version3: 2,
adjustDown_version3: 3,
/**
* Whether to reset target if a block
* has not been mined recently.
@ -578,9 +602,29 @@ testnet.pow = {
'000000000000000000000000000000000000000000000000000000083540886d',
'hex'
),
targetTimespan: 3.5 * 24 * 60 * 60,
targetSpacing: 40,
retargetInterval: 1,
targetTimespan_version1: 60 * 60,
targetSpacing_version1: 40,
retargetInterval_version1: (60 * 60) / 40,
averagingInterval_version1: (60 * 60) / 40,
averagingIntervalTimespan_version1: ((60 * 60) / 40) * 40,
adjustUp_version1: 75,
adjustDown_version1: 300,
blockHeight_version2: 50000,
targetTimespan_version2: 15 * 40,
targetSpacing_version2: 40,
retargetInterval_version2: 15,
averagingInterval_version2: 15,
averagingIntervalTimespan_version2: 15 * 40,
adjustUp_version2: 75,
adjustDown_version2: 300,
blockHeight_version3: 60000,
targetTimespan_version3: 6 * 40,
targetSpacing_version3: 40,
retargetInterval_version3: 1,
averagingInterval_version3: 6,
averagingIntervalTimespan_version3: 6 * 40,
adjustUp_version3: 2,
adjustDown_version3: 3,
targetReset: true,
noRetargeting: false
};