chain accuracy.
This commit is contained in:
parent
d5bfb124cf
commit
dee60da2e2
@ -78,6 +78,7 @@ function Chain(options) {
|
||||
this.lastUpdate = utils.now();
|
||||
this.tip = null;
|
||||
this.height = -1;
|
||||
this.synced = false;
|
||||
this.segwitActive = null;
|
||||
this.csvActive = null;
|
||||
|
||||
@ -217,8 +218,10 @@ Chain.prototype._init = function _init() {
|
||||
self.tip = tip;
|
||||
self.height = tip.height;
|
||||
|
||||
if (self.bestHeight === -1)
|
||||
if (tip.height > self.bestHeight) {
|
||||
self.bestHeight = tip.height;
|
||||
network.height = tip.height;
|
||||
}
|
||||
|
||||
self._getInitialState(function(err) {
|
||||
if (err)
|
||||
@ -234,8 +237,10 @@ Chain.prototype._init = function _init() {
|
||||
self.emit('open');
|
||||
self.emit('tip', tip);
|
||||
|
||||
if (self.isFull())
|
||||
if (!self.synced && self.isFull()) {
|
||||
self.synced = true;
|
||||
self.emit('full');
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -621,7 +626,7 @@ Chain.prototype._checkDeployments = function _checkDeployments(block, prev, call
|
||||
if (block.version < 4 && prev.isOutdated(4))
|
||||
return callback(new VerifyError(block, 'obsolete', 'bad-version', 0));
|
||||
|
||||
// Only allow version 5 blocks (segwit)
|
||||
// Only allow version 5 blocks (bip141 - segnet3)
|
||||
// once the majority of blocks are using it.
|
||||
if (network.segwitHeight !== -1 && height >= network.segwitHeight) {
|
||||
if (block.version < 5 && prev.isOutdated(5))
|
||||
@ -629,10 +634,8 @@ Chain.prototype._checkDeployments = function _checkDeployments(block, prev, call
|
||||
}
|
||||
|
||||
// Make sure the height contained in the coinbase is correct.
|
||||
if (network.block.bip34height !== -1 && height >= network.block.bip34height) {
|
||||
if (block.version >= 2 && prev.isUpgraded(2))
|
||||
state.coinbaseHeight = true;
|
||||
}
|
||||
if (block.version >= 2 && prev.isUpgraded(2))
|
||||
state.coinbaseHeight = true;
|
||||
|
||||
// Signature validation is now enforced (bip66)
|
||||
if (block.version >= 3 && prev.isUpgraded(3))
|
||||
@ -691,9 +694,9 @@ Chain.prototype._checkDeployments = function _checkDeployments(block, prev, call
|
||||
};
|
||||
|
||||
/**
|
||||
* Check block for duplicate txids in blockchain
|
||||
* history (BIP30). Note that txids are only considered
|
||||
* duplicate if they are not yet completely spent.
|
||||
* Determine whether to check block for duplicate txids in blockchain
|
||||
* history (BIP30). If we're on a chain that has bip34 activated, we
|
||||
* can skip this.
|
||||
* @private
|
||||
* @see https://github.com/bitcoin/bips/blob/master/bip-0030.mediawiki
|
||||
* @param {Block|MerkleBlock} block
|
||||
@ -711,6 +714,38 @@ Chain.prototype._checkDuplicates = function _checkDuplicates(block, prev, callba
|
||||
if (block.isGenesis())
|
||||
return callback();
|
||||
|
||||
if (network.block.bip34height === -1 || height <= network.block.bip34height)
|
||||
return this._findDuplicates(block, prev, callback);
|
||||
|
||||
self.db.get(network.block.bip34height, function(err, entry) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
|
||||
// It was no longer possible to create duplicate
|
||||
// TXs once bip34 went into effect. We can check
|
||||
// for this to avoid a DB lookup.
|
||||
if (entry && entry.hash === network.block.bip34hash)
|
||||
return callback();
|
||||
|
||||
return self._findDuplicates(block, prev, callback);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Check block for duplicate txids in blockchain
|
||||
* history (BIP30). Note that txids are only considered
|
||||
* duplicate if they are not yet completely spent.
|
||||
* @private
|
||||
* @see https://github.com/bitcoin/bips/blob/master/bip-0030.mediawiki
|
||||
* @param {Block|MerkleBlock} block
|
||||
* @param {ChainBlock} prev
|
||||
* @param {Function} callback - Returns [{@link VerifyError}].
|
||||
*/
|
||||
|
||||
Chain.prototype._findDuplicates = function _findDuplicates(block, prev, callback) {
|
||||
var self = this;
|
||||
var height = prev.height + 1;
|
||||
|
||||
// Check all transactions
|
||||
utils.forEachSerial(block.txs, function(tx, next) {
|
||||
var hash = tx.hash('hex');
|
||||
@ -724,8 +759,8 @@ Chain.prototype._checkDuplicates = function _checkDuplicates(block, prev, callba
|
||||
// Blocks 91842 and 91880 created duplicate
|
||||
// txids by using the same exact output script
|
||||
// and extraNonce.
|
||||
if (network.type === 'main') {
|
||||
if (height === 91842 || height === 91880)
|
||||
if (constants.bip30[height]) {
|
||||
if (block.hash('hex') === constants.bip30[height])
|
||||
return next();
|
||||
}
|
||||
return next(new VerifyError(block, 'invalid', 'bad-txns-BIP30', 100));
|
||||
@ -1051,8 +1086,8 @@ Chain.prototype.disconnect = function disconnect(entry, callback) {
|
||||
self.tip = entry;
|
||||
self.height = entry.height;
|
||||
|
||||
if (self.bestHeight === -1)
|
||||
network.height = entry.height;
|
||||
self.bestHeight = entry.height;
|
||||
network.height = entry.height;
|
||||
|
||||
self.emit('tip', entry);
|
||||
|
||||
@ -1106,8 +1141,8 @@ Chain.prototype.connect = function connect(entry, callback) {
|
||||
self.tip = entry;
|
||||
self.height = entry.height;
|
||||
|
||||
if (self.bestHeight === -1)
|
||||
network.height = entry.height;
|
||||
self.bestHeight = entry.height;
|
||||
network.height = entry.height;
|
||||
|
||||
self.emit('tip', entry);
|
||||
|
||||
@ -1164,9 +1199,6 @@ Chain.prototype._setBestChain = function _setBestChain(entry, prev, block, callb
|
||||
self.tip = entry;
|
||||
self.height = entry.height;
|
||||
|
||||
if (self.bestHeight === -1)
|
||||
network.height = entry.height;
|
||||
|
||||
self.emit('tip', entry);
|
||||
|
||||
return callback();
|
||||
@ -1409,6 +1441,11 @@ Chain.prototype.add = function add(block, callback, force) {
|
||||
network.height = self.bestHeight;
|
||||
}
|
||||
|
||||
if (height > self.bestHeight) {
|
||||
self.bestHeight = height;
|
||||
network.height = height;
|
||||
}
|
||||
|
||||
// If previous block wasn't ever seen,
|
||||
// add it current to orphans and break.
|
||||
if (!prev) {
|
||||
@ -1554,8 +1591,10 @@ Chain.prototype.add = function add(block, callback, force) {
|
||||
}
|
||||
|
||||
utils.nextTick(function() {
|
||||
if (self.isFull())
|
||||
if (!self.synced && self.isFull()) {
|
||||
self.synced = true;
|
||||
self.emit('full');
|
||||
}
|
||||
|
||||
if (err)
|
||||
callback(err);
|
||||
@ -1793,7 +1832,7 @@ Chain.prototype.getOrphan = function getOrphan(hash) {
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
Chain.prototype.isFull = function isFull() {
|
||||
Chain.prototype.isFullLegacy = function isFull() {
|
||||
var delta;
|
||||
|
||||
if (!this.tip)
|
||||
@ -1804,6 +1843,15 @@ Chain.prototype.isFull = function isFull() {
|
||||
return delta < 4 * 60 * 60;
|
||||
};
|
||||
|
||||
/**
|
||||
* Test the chain to see if it is synced.
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
Chain.prototype.isFull = function isFull() {
|
||||
return !this.isInitial();
|
||||
};
|
||||
|
||||
/**
|
||||
* Test the chain to see if it is still in the initial
|
||||
* syncing phase. Mimic's bitcoind's `IsInitialBlockDownload()`
|
||||
@ -1812,7 +1860,7 @@ Chain.prototype.isFull = function isFull() {
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
Chain.prototype.isInitial = function isInitial() {
|
||||
Chain.prototype.isInitialLegacy = function isInitial() {
|
||||
var now, delta;
|
||||
|
||||
if (!this.tip)
|
||||
@ -1825,6 +1873,28 @@ Chain.prototype.isInitial = function isInitial() {
|
||||
return delta < 10 && this.tip.ts < now - 24 * 60 * 60;
|
||||
};
|
||||
|
||||
/**
|
||||
* Test the chain to see if it is still in the initial
|
||||
* syncing phase. Mimic's bitcoind's `IsInitialBlockDownload()`
|
||||
* function.
|
||||
* @see IsInitalBlockDownload()
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
Chain.prototype.isInitial = function isInitial() {
|
||||
if (!this.tip)
|
||||
return true;
|
||||
|
||||
if (this.synced)
|
||||
return false;
|
||||
|
||||
if (this.height < network.checkpoints.lastHeight)
|
||||
return true;
|
||||
|
||||
return this.height < this.bestHeight - 24 * 6
|
||||
|| this.tip.ts < utils.now() - network.block.maxTipAge;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the fill percentage.
|
||||
* @returns {Number} percent - Ranges from 0.0 to 1.0.
|
||||
|
||||
@ -1545,8 +1545,7 @@ ChainDB.prototype._pruneBlock = function _pruneBlock(block, batch, callback) {
|
||||
if (!this.prune)
|
||||
return callback();
|
||||
|
||||
// Keep the genesis block
|
||||
if (block.isGenesis())
|
||||
if (block.height <= network.block.pruneAfterHeight)
|
||||
return callback();
|
||||
|
||||
futureHeight = pad32(block.height + this.keepBlocks);
|
||||
|
||||
@ -330,6 +330,16 @@ exports.block = {
|
||||
SIGHASH_LIMIT: 1300000000
|
||||
};
|
||||
|
||||
/**
|
||||
* Map of historical blocks which create duplicate transactions hashes.
|
||||
* @see https://github.com/bitcoin/bips/blob/master/bip-0030.mediawiki
|
||||
*/
|
||||
|
||||
exports.bip30 = {
|
||||
91842: 'eccae000e3c8e4e093936360431f3b7603c563c1ff6181390a4d0a0000000000',
|
||||
91880: '21d77ccb4c08386a04ac0196ae10f6a1d2c2a377558ca190f143070000000000'
|
||||
};
|
||||
|
||||
/**
|
||||
* TX-related constants.
|
||||
* @enum {Number}
|
||||
|
||||
@ -229,7 +229,10 @@ main.block = {
|
||||
majorityEnforceUpgrade: 750,
|
||||
majorityRejectOutdated: 950,
|
||||
majorityWindow: 1000,
|
||||
bip34height: 227931
|
||||
bip34height: 227931,
|
||||
bip34hash: 'b808089c756add1591b1d17bab44bba3fed9e02f942ab4894b02000000000000',
|
||||
pruneAfterHeight: 100000,
|
||||
maxTipAge: 24 * 60 * 60
|
||||
};
|
||||
|
||||
/**
|
||||
@ -271,10 +274,20 @@ main.minerConfirmationWindow = 2016; // nPowTargetTimespan / nPowTargetSpacing
|
||||
*/
|
||||
|
||||
main.deployments = {
|
||||
testdummy: {
|
||||
bit: 28,
|
||||
startTime: 1199145601, // January 1, 2008
|
||||
timeout: 1230767999 // December 31, 2008
|
||||
},
|
||||
csv: {
|
||||
bit: 0,
|
||||
startTime: 1459468800, // April 1st, 2016
|
||||
timeout: 1491004800 // April 1st, 2017
|
||||
startTime: 1462060800, // May 1st, 2016
|
||||
timeout: 1493596800 // May 1st, 2017
|
||||
},
|
||||
witness: {
|
||||
bit: 1,
|
||||
startTime: 2000000000, // Far in the future
|
||||
timeout: 2100000000
|
||||
}
|
||||
// bip109: {
|
||||
// bit: 4,
|
||||
@ -418,7 +431,10 @@ testnet.block = {
|
||||
majorityEnforceUpgrade: 51,
|
||||
majorityRejectOutdated: 75,
|
||||
majorityWindow: 100,
|
||||
bip34height: 21111
|
||||
bip34height: 21111,
|
||||
bip34hash: 'f88ecd9912d00d3f5c2a8e0f50417d3e415c75b3abe584346da9b32300000000',
|
||||
pruneAfterHeight: 1000,
|
||||
maxTipAge: 0x7fffffff
|
||||
};
|
||||
|
||||
testnet.witness = false;
|
||||
@ -428,10 +444,20 @@ testnet.segwitHeight = 2000000000;
|
||||
testnet.ruleChangeActivationThreshold = 1512; // 75% for testchains
|
||||
testnet.minerConfirmationWindow = 2016; // nPowTargetTimespan / nPowTargetSpacing
|
||||
testnet.deployments = {
|
||||
testdummy: {
|
||||
bit: 28,
|
||||
startTime: 1199145601, // January 1, 2008
|
||||
timeout: 1230767999 // December 31, 2008
|
||||
},
|
||||
csv: {
|
||||
bit: 0,
|
||||
startTime: 1459468800,
|
||||
timeout: 1491004800
|
||||
startTime: 1456790400, // March 1st, 2016
|
||||
timeout: 1493596800 // May 1st, 2017
|
||||
},
|
||||
witness: {
|
||||
bit: 1,
|
||||
startTime: 2000000000, // Far in the future
|
||||
timeout: 2100000000
|
||||
}
|
||||
};
|
||||
|
||||
@ -529,7 +555,10 @@ regtest.block = {
|
||||
majorityEnforceUpgrade: 750,
|
||||
majorityRejectOutdated: 950,
|
||||
majorityWindow: 1000,
|
||||
bip34height: -1
|
||||
bip34height: -1,
|
||||
bip34hash: null,
|
||||
pruneAfterHeight: 1000,
|
||||
maxTipAge: 24 * 60 * 60
|
||||
};
|
||||
|
||||
regtest.witness = false;
|
||||
@ -539,10 +568,20 @@ regtest.segwitHeight = -1;
|
||||
regtest.ruleChangeActivationThreshold = 108; // 75% for testchains
|
||||
regtest.minerConfirmationWindow = 144; // Faster than normal for regtest (144 instead of 2016)
|
||||
regtest.deployments = {
|
||||
testdummy: {
|
||||
bit: 28,
|
||||
startTime: 0,
|
||||
timeout: 999999999999
|
||||
},
|
||||
csv: {
|
||||
bit: 0,
|
||||
startTime: 0,
|
||||
timeout: 999999999999
|
||||
},
|
||||
witness: {
|
||||
bit: 1,
|
||||
startTime: 0,
|
||||
timeout: 999999999999
|
||||
}
|
||||
};
|
||||
|
||||
@ -591,12 +630,8 @@ segnet3.magic = 0xcaea962e;
|
||||
|
||||
segnet3.port = 28333;
|
||||
|
||||
segnet3.alertKey = new Buffer(''
|
||||
+ '04302390343f91cc401d56d68b123028bf52e5f'
|
||||
+ 'ca1939df127f63c6467cdf9c8e2c14b61104cf8'
|
||||
+ '17d0b780da337893ecc4aaff1309e536162dabb'
|
||||
+ 'db45200ca2b0a',
|
||||
'hex');
|
||||
segnet3.alertKey = new Buffer(
|
||||
'0300000000000000000000003b78ce563f89a0ed9414f5aa28ad0d96d6795f9c63', 'hex');
|
||||
|
||||
segnet3.checkpoints = {};
|
||||
segnet3.checkpoints.tsLastCheckpoint = 0;
|
||||
@ -643,7 +678,10 @@ segnet3.block = {
|
||||
majorityEnforceUpgrade: 7,
|
||||
majorityRejectOutdated: 9,
|
||||
majorityWindow: 10,
|
||||
bip34height: -1
|
||||
bip34height: -1,
|
||||
bip34hash: null,
|
||||
pruneAfterHeight: 1000,
|
||||
maxTipAge: 0x7fffffff
|
||||
};
|
||||
|
||||
segnet3.witness = true;
|
||||
@ -696,12 +734,8 @@ segnet4.magic = 0xc4a1abdc;
|
||||
|
||||
segnet4.port = 28901;
|
||||
|
||||
segnet4.alertKey = new Buffer(''
|
||||
+ '04302390343f91cc401d56d68b123028bf52e5f'
|
||||
+ 'ca1939df127f63c6467cdf9c8e2c14b61104cf8'
|
||||
+ '17d0b780da337893ecc4aaff1309e536162dabb'
|
||||
+ 'db45200ca2b0a',
|
||||
'hex');
|
||||
segnet4.alertKey = new Buffer(
|
||||
'0300000000000000000000003b78ce563f89a0ed9414f5aa28ad0d96d6795f9c63', 'hex');
|
||||
|
||||
segnet4.checkpoints = {};
|
||||
segnet4.checkpoints.tsLastCheckpoint = 0;
|
||||
@ -749,7 +783,10 @@ segnet4.block = {
|
||||
majorityEnforceUpgrade: 7,
|
||||
majorityRejectOutdated: 9,
|
||||
majorityWindow: 10,
|
||||
bip34height: -1
|
||||
bip34height: -1,
|
||||
bip34hash: null,
|
||||
pruneAfterHeight: 1000,
|
||||
maxTipAge: 0x7fffffff
|
||||
};
|
||||
|
||||
segnet4.witness = true;
|
||||
@ -759,10 +796,15 @@ segnet4.segwitHeight = -1;
|
||||
segnet4.ruleChangeActivationThreshold = 108;
|
||||
segnet4.minerConfirmationWindow = 144;
|
||||
segnet4.deployments = {
|
||||
testdummy: {
|
||||
bit: 28,
|
||||
startTime: 1199145601, // January 1, 2008
|
||||
timeout: 1230767999 // December 31, 2008
|
||||
},
|
||||
csv: {
|
||||
bit: 0,
|
||||
startTime: 1459468800, // April 1st, 2016
|
||||
timeout: 1491004800 // April 1st, 2017
|
||||
startTime: 1456790400, // March 1st, 2016
|
||||
timeout: 1493596800 // May 1st, 2017
|
||||
},
|
||||
witness: {
|
||||
bit: 1,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user