chain deployment state.
This commit is contained in:
parent
eb4f16f2b7
commit
4b7d4a3c8d
@ -498,14 +498,8 @@ Chain.prototype._verify = function _verify(block, prev, callback) {
|
|||||||
return callback(new VerifyError(block, 'invalid', ret.reason, ret.score));
|
return callback(new VerifyError(block, 'invalid', ret.reason, ret.score));
|
||||||
|
|
||||||
// Skip the genesis block. Skip all blocks in spv mode.
|
// Skip the genesis block. Skip all blocks in spv mode.
|
||||||
if (this.options.spv || this.isGenesis(block)) {
|
if (this.options.spv || this.isGenesis(block))
|
||||||
return callback(null, {
|
return callback(null, new DeploymentState());
|
||||||
flags: constants.flags.MANDATORY_VERIFY_FLAGS,
|
|
||||||
lockFlags: constants.flags.MANDATORY_LOCKTIME_FLAGS,
|
|
||||||
segwit: false,
|
|
||||||
csv: false
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensure it's not an orphan
|
// Ensure it's not an orphan
|
||||||
if (!prev) {
|
if (!prev) {
|
||||||
@ -542,15 +536,15 @@ Chain.prototype._verify = function _verify(block, prev, callback) {
|
|||||||
return callback(err);
|
return callback(err);
|
||||||
|
|
||||||
// Expose the state of csv and segwit globally.
|
// Expose the state of csv and segwit globally.
|
||||||
self.csvActive = state.csv;
|
self.csvActive = state.hasCSV();
|
||||||
self.segwitActive = state.segwit;
|
self.segwitActive = state.hasWitness();
|
||||||
|
|
||||||
// Can't verify any further when merkleblock or headers.
|
// Can't verify any further when merkleblock or headers.
|
||||||
if (self.options.spv)
|
if (self.options.spv)
|
||||||
return callback(null, state);
|
return callback(null, state);
|
||||||
|
|
||||||
// Make sure the height contained in the coinbase is correct.
|
// Make sure the height contained in the coinbase is correct.
|
||||||
if (state.coinbaseHeight) {
|
if (state.hasBIP34()) {
|
||||||
if (block.getCoinbaseHeight() !== height) {
|
if (block.getCoinbaseHeight() !== height) {
|
||||||
return callback(new VerifyError(block,
|
return callback(new VerifyError(block,
|
||||||
'invalid',
|
'invalid',
|
||||||
@ -560,7 +554,7 @@ Chain.prototype._verify = function _verify(block, prev, callback) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check the commitment hash for segwit.
|
// Check the commitment hash for segwit.
|
||||||
if (state.segwit) {
|
if (state.hasWitness()) {
|
||||||
commitmentHash = block.commitmentHash;
|
commitmentHash = block.commitmentHash;
|
||||||
if (commitmentHash) {
|
if (commitmentHash) {
|
||||||
if (!block.witnessNonce) {
|
if (!block.witnessNonce) {
|
||||||
@ -635,13 +629,7 @@ Chain.prototype._verify = function _verify(block, prev, callback) {
|
|||||||
Chain.prototype._checkDeployments = function _checkDeployments(block, prev, ancestors, callback) {
|
Chain.prototype._checkDeployments = function _checkDeployments(block, prev, ancestors, callback) {
|
||||||
var self = this;
|
var self = this;
|
||||||
var height = prev.height + 1;
|
var height = prev.height + 1;
|
||||||
var state = {
|
var state = new DeploymentState();
|
||||||
flags: constants.flags.MANDATORY_VERIFY_FLAGS,
|
|
||||||
lockFlags: constants.flags.MANDATORY_LOCKTIME_FLAGS,
|
|
||||||
coinbaseHeight: false,
|
|
||||||
segwit: false,
|
|
||||||
csv: false
|
|
||||||
};
|
|
||||||
|
|
||||||
// For some reason bitcoind has p2sh in the
|
// For some reason bitcoind has p2sh in the
|
||||||
// mandatory flags by default, when in reality
|
// mandatory flags by default, when in reality
|
||||||
@ -651,8 +639,8 @@ Chain.prototype._checkDeployments = function _checkDeployments(block, prev, ance
|
|||||||
// not have a signature. See:
|
// not have a signature. See:
|
||||||
// 6a26d2ecb67f27d1fa5524763b49029d7106e91e3cc05743073461a719776192
|
// 6a26d2ecb67f27d1fa5524763b49029d7106e91e3cc05743073461a719776192
|
||||||
// 9c08a4d78931342b37fd5f72900fb9983087e6f46c4a097d8a1f52c74e28eaf6
|
// 9c08a4d78931342b37fd5f72900fb9983087e6f46c4a097d8a1f52c74e28eaf6
|
||||||
if (block.ts < constants.block.BIP16_TIME)
|
if (block.ts >= constants.block.BIP16_TIME)
|
||||||
state.flags &= ~constants.flags.VERIFY_P2SH;
|
state.flags |= constants.flags.VERIFY_P2SH;
|
||||||
|
|
||||||
// Only allow version 2 blocks (coinbase height)
|
// Only allow version 2 blocks (coinbase height)
|
||||||
// once the majority of blocks are using it.
|
// once the majority of blocks are using it.
|
||||||
@ -678,7 +666,7 @@ Chain.prototype._checkDeployments = function _checkDeployments(block, prev, ance
|
|||||||
|
|
||||||
// Make sure the height contained in the coinbase is correct.
|
// Make sure the height contained in the coinbase is correct.
|
||||||
if (block.version >= 2 && prev.isUpgraded(2, ancestors))
|
if (block.version >= 2 && prev.isUpgraded(2, ancestors))
|
||||||
state.coinbaseHeight = true;
|
state.bip34 = true;
|
||||||
|
|
||||||
// Signature validation is now enforced (bip66)
|
// Signature validation is now enforced (bip66)
|
||||||
if (block.version >= 3 && prev.isUpgraded(3, ancestors))
|
if (block.version >= 3 && prev.isUpgraded(3, ancestors))
|
||||||
@ -690,10 +678,8 @@ Chain.prototype._checkDeployments = function _checkDeployments(block, prev, ance
|
|||||||
|
|
||||||
// Segregrated witness is now usable (bip141 - segnet3)
|
// Segregrated witness is now usable (bip141 - segnet3)
|
||||||
if (this.network.segwitHeight !== -1 && height >= this.network.segwitHeight) {
|
if (this.network.segwitHeight !== -1 && height >= this.network.segwitHeight) {
|
||||||
if (block.version >= 5 && prev.isUpgraded(5, ancestors)) {
|
if (block.version >= 5 && prev.isUpgraded(5, ancestors))
|
||||||
state.flags |= constants.flags.VERIFY_WITNESS;
|
state.flags |= constants.flags.VERIFY_WITNESS;
|
||||||
state.segwit = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
utils.serial([
|
utils.serial([
|
||||||
@ -708,7 +694,6 @@ Chain.prototype._checkDeployments = function _checkDeployments(block, prev, ance
|
|||||||
state.flags |= constants.flags.VERIFY_CHECKSEQUENCEVERIFY;
|
state.flags |= constants.flags.VERIFY_CHECKSEQUENCEVERIFY;
|
||||||
state.lockFlags |= constants.flags.VERIFY_SEQUENCE;
|
state.lockFlags |= constants.flags.VERIFY_SEQUENCE;
|
||||||
state.lockFlags |= constants.flags.MEDIAN_TIME_PAST;
|
state.lockFlags |= constants.flags.MEDIAN_TIME_PAST;
|
||||||
state.csv = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return next();
|
return next();
|
||||||
@ -720,10 +705,8 @@ Chain.prototype._checkDeployments = function _checkDeployments(block, prev, ance
|
|||||||
if (err)
|
if (err)
|
||||||
return next(err);
|
return next(err);
|
||||||
|
|
||||||
if (active) {
|
if (active)
|
||||||
state.flags |= constants.flags.VERIFY_WITNESS;
|
state.flags |= constants.flags.VERIFY_WITNESS;
|
||||||
state.segwit = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return next();
|
return next();
|
||||||
});
|
});
|
||||||
@ -2366,8 +2349,8 @@ Chain.prototype._getInitialState = function _getInitialState(callback) {
|
|||||||
if (err)
|
if (err)
|
||||||
return callback(err);
|
return callback(err);
|
||||||
|
|
||||||
self.csvActive = state.csv;
|
self.csvActive = state.hasCSV();
|
||||||
self.segwitActive = state.segwit;
|
self.segwitActive = state.hasWitness();
|
||||||
|
|
||||||
return callback();
|
return callback();
|
||||||
});
|
});
|
||||||
@ -2509,6 +2492,78 @@ Chain.prototype.checkLocks = function checkLocks(prev, tx, flags, callback) {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents the deployment state of the chain.
|
||||||
|
* @constructor
|
||||||
|
* @property {VerifyFlags} flags
|
||||||
|
* @property {LockFlags} lockFlags
|
||||||
|
* @property {Boolean} bip34
|
||||||
|
*/
|
||||||
|
|
||||||
|
function DeploymentState() {
|
||||||
|
if (!(this instanceof DeploymentState))
|
||||||
|
return new DeploymentState();
|
||||||
|
|
||||||
|
this.flags = constants.flags.MANDATORY_VERIFY_FLAGS;
|
||||||
|
this.flags &= ~constants.flags.VERIFY_P2SH;
|
||||||
|
this.lockFlags = constants.flags.MANDATORY_LOCKTIME_FLAGS;
|
||||||
|
this.bip34 = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test whether p2sh is active.
|
||||||
|
* @returns {Boolean}
|
||||||
|
*/
|
||||||
|
|
||||||
|
DeploymentState.prototype.hasP2SH = function hasP2SH() {
|
||||||
|
return (this.flags & constants.flags.VERIFY_P2SH) !== 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test whether bip34 (coinbase height) is active.
|
||||||
|
* @returns {Boolean}
|
||||||
|
*/
|
||||||
|
|
||||||
|
DeploymentState.prototype.hasBIP34 = function hasBIP34() {
|
||||||
|
return this.bip34;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test whether bip66 (VERIFY_DERSIG) is active.
|
||||||
|
* @returns {Boolean}
|
||||||
|
*/
|
||||||
|
|
||||||
|
DeploymentState.prototype.hasBIP66 = function hasBIP66() {
|
||||||
|
return (this.flags & constants.flags.VERIFY_DERSIG) !== 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test whether cltv is active.
|
||||||
|
* @returns {Boolean}
|
||||||
|
*/
|
||||||
|
|
||||||
|
DeploymentState.prototype.hasCLTV = function hasCLTV() {
|
||||||
|
return (this.flags & constants.flags.VERIFY_CHECKLOCKTIMEVERIFY) !== 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test whether csv is active.
|
||||||
|
* @returns {Boolean}
|
||||||
|
*/
|
||||||
|
|
||||||
|
DeploymentState.prototype.hasCSV = function hasCSV() {
|
||||||
|
return (this.flags & constants.flags.VERIFY_CHECKSEQUENCEVERIFY) !== 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test whether segwit is active.
|
||||||
|
* @returns {Boolean}
|
||||||
|
*/
|
||||||
|
|
||||||
|
DeploymentState.prototype.hasWitness = function hasWitness() {
|
||||||
|
return (this.flags & constants.flags.VERIFY_WITNESS) !== 0;
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Expose
|
* Expose
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -2719,9 +2719,13 @@ MasterKey.prototype.toJSON = function toJSON() {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
MasterKey.prototype.fromJSON = function fromJSON(json) {
|
MasterKey.prototype.fromJSON = function fromJSON(json) {
|
||||||
|
assert(typeof json.encrypted === 'boolean');
|
||||||
|
|
||||||
this.encrypted = json.encrypted;
|
this.encrypted = json.encrypted;
|
||||||
|
|
||||||
if (json.encrypted) {
|
if (json.encrypted) {
|
||||||
|
assert(typeof json.iv === 'string');
|
||||||
|
assert(typeof json.ciphertext === 'string');
|
||||||
this.iv = new Buffer(json.iv, 'hex');
|
this.iv = new Buffer(json.iv, 'hex');
|
||||||
this.ciphertext = new Buffer(json.ciphertext, 'hex');
|
this.ciphertext = new Buffer(json.ciphertext, 'hex');
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user