add pow retargeting to full chain.

This commit is contained in:
Christopher Jeffrey 2016-01-01 19:53:57 -08:00
parent 8b546a85e0
commit 5a26b7b71e
2 changed files with 82 additions and 0 deletions

View File

@ -520,6 +520,69 @@ ChainBlock.prototype.getChainwork = function() {
return (this.prev ? this.prev.chainwork : new bn(0)).add(this.proof);
};
Chain.prototype.target = function target(last) {
var proofOfWorkLimit = utils.toCompact(network.powLimit);
var adjustmentInterval = network.powTargetTimespan / network.powTargetSpacing;
var newBlockTs, heightFirst, first;
adjustmentInterval |= 0;
if (!last)
last = this.getTip();
// Do not retarget
if ((last.height + 1) % adjustmentInterval) {
if (network.powAllowMinDifficultyBlocks) {
// Special behavior for testnet:
newBlockTs = Date.now() / 1000 | 0;
if (newBlockTs > last.ts + network.powTargetSpacing * 2)
return proofOfWorkLimit;
while (last.prev
&& last.height % adjustmentInterval !== 0
&& last.bits !== proofOfWorkLimit) {
last = last.prev;
}
return last.bits;
}
return last.bits;
}
// Back 2 weeks
heightFirst = last.height - (adjustmentInterval - 1);
first = this.byHeight(heightFirst);
if (!first)
return 0;
return this.retarget(last, first.ts);
};
Chain.prototype.retarget = function retarget(last, firstTs) {
var powTargetTimespan = new bn(network.powTargetTimespan);
var actualTimespan, powLimit, target;
if (network.powNoRetargeting)
return last.bits;
actualTimespan = new bn(last.ts).subn(firstTs);
if (actualTimespan.cmp(powTargetTimespan.divn(4)) < 0)
actualTimespan = powTargetTimespan.divn(4);
if (actualTimespan.cmp(powTargetTimespan.muln(4)) > 0)
actualTimespan = powTargetTimespan.muln(4);
powLimit = network.powLimit;
target = utils.fromCompact(last.bits);
target.imul(actualTimespan);
target = target.div(powTargetTimespan);
if (target.cmp(powLimit) > 0)
target = powLimit.clone();
return utils.toCompact(target);
};
ChainBlock.prototype.toJSON = function() {
// return [
// this.hash,

View File

@ -5,6 +5,7 @@
*/
var bcoin = require('../../bcoin');
var bn = require('bn.js');
var utils = bcoin.utils;
/**
@ -107,6 +108,15 @@ main.magic = 0xd9b4bef9;
main.preload = require('./preload');
main.powLimit = new bn(
'00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff',
'hex'
);
main.powTargetTimespan = 14 * 24 * 60 * 60; // two weeks
main.powTargetSpacing = 10 * 60;
main.powAllowMinDifficultyBlocks = false;
main.powNoRetargeting = false;
/**
* Testnet (v3)
* https://en.bitcoin.it/wiki/Testnet
@ -187,3 +197,12 @@ testnet.preload = {
'ts': [testnet.genesis.ts],
'heights': [0]
};
testnet.powLimit = new bn(
'00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff',
'hex'
);
testnet.powTargetTimespan = 14 * 24 * 60 * 60; // two weeks
testnet.powTargetSpacing = 10 * 60;
testnet.powAllowMinDifficultyBlocks = true;
testnet.powNoRetargeting = false;