diff --git a/lib/blockchain/chain.js b/lib/blockchain/chain.js index 01122e0c..1c0d2d76 100644 --- a/lib/blockchain/chain.js +++ b/lib/blockchain/chain.js @@ -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); }; diff --git a/lib/protocol/networks.js b/lib/protocol/networks.js index 59473de3..7edec919 100644 --- a/lib/protocol/networks.js +++ b/lib/protocol/networks.js @@ -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 };