chain: versionbits refactor.
This commit is contained in:
parent
390f7d8ddb
commit
1f22013ce0
@ -436,6 +436,7 @@ Chain.prototype.verify = co(function* verify(block, prev) {
|
||||
*/
|
||||
|
||||
Chain.prototype.getDeployments = co(function* getDeployments(block, prev) {
|
||||
var deployments = this.network.deployments;
|
||||
var height = prev.height + 1;
|
||||
var state = new DeploymentState();
|
||||
var active;
|
||||
@ -496,7 +497,7 @@ Chain.prototype.getDeployments = co(function* getDeployments(block, prev) {
|
||||
|
||||
// CHECKSEQUENCEVERIFY and median time
|
||||
// past locktimes are now usable (bip9 & bip113).
|
||||
active = yield this.isActive(prev, 'csv');
|
||||
active = yield this.isActive(prev, deployments.csv);
|
||||
if (active) {
|
||||
state.flags |= constants.flags.VERIFY_CHECKSEQUENCEVERIFY;
|
||||
state.lockFlags |= constants.flags.VERIFY_SEQUENCE;
|
||||
@ -504,7 +505,7 @@ Chain.prototype.getDeployments = co(function* getDeployments(block, prev) {
|
||||
}
|
||||
|
||||
// Segregrated witness is now usable (bip141 - segnet4)
|
||||
active = yield this.isActive(prev, 'witness');
|
||||
active = yield this.isActive(prev, deployments.witness);
|
||||
if (active) {
|
||||
if (this.options.witness)
|
||||
state.flags |= constants.flags.VERIFY_WITNESS;
|
||||
@ -645,7 +646,7 @@ Chain.prototype.verifyInputs = co(function* verifyInputs(block, prev, state) {
|
||||
}
|
||||
|
||||
// Verify sequence locks.
|
||||
valid = yield this.checkLocks(prev, tx, state.lockFlags);
|
||||
valid = yield this.verifyLocks(prev, tx, state.lockFlags);
|
||||
|
||||
if (!valid) {
|
||||
throw new VerifyError(block,
|
||||
@ -936,6 +937,13 @@ Chain.prototype.setBestChain = co(function* setBestChain(entry, block, prev) {
|
||||
yield this.reorganize(entry, block);
|
||||
}
|
||||
|
||||
// Warn of unknown versionbits.
|
||||
if (entry.hasUnknown()) {
|
||||
this.logger.warning(
|
||||
'Unknown version bits in block %d: %d.',
|
||||
entry.height, entry.version);
|
||||
}
|
||||
|
||||
// Otherwise, everything is in order.
|
||||
// Do "contextual" verification on our block
|
||||
// now that we're certain its previous
|
||||
@ -995,6 +1003,13 @@ Chain.prototype.saveAlternate = co(function* saveAlternate(entry, block, prev) {
|
||||
throw e;
|
||||
}
|
||||
|
||||
// Warn of unknown versionbits.
|
||||
if (entry.hasUnknown()) {
|
||||
this.logger.warning(
|
||||
'Unknown version bits in block %d: %d.',
|
||||
entry.height, entry.version);
|
||||
}
|
||||
|
||||
yield this.db.save(entry, block);
|
||||
});
|
||||
|
||||
@ -1912,7 +1927,7 @@ Chain.prototype.findLocator = co(function* findLocator(locator) {
|
||||
* @returns {Promise} - Returns Number.
|
||||
*/
|
||||
|
||||
Chain.prototype.isActive = co(function* isActive(prev, id) {
|
||||
Chain.prototype.isActive = co(function* isActive(prev, deployment) {
|
||||
var state;
|
||||
|
||||
if (!this.options.witness) {
|
||||
@ -1920,7 +1935,7 @@ Chain.prototype.isActive = co(function* isActive(prev, id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
state = yield this.getState(prev, id);
|
||||
state = yield this.getState(prev, deployment);
|
||||
|
||||
return state === constants.thresholdStates.ACTIVE;
|
||||
});
|
||||
@ -1935,20 +1950,14 @@ Chain.prototype.isActive = co(function* isActive(prev, id) {
|
||||
* @returns {Promise} - Returns Number.
|
||||
*/
|
||||
|
||||
Chain.prototype.getState = co(function* getState(prev, id) {
|
||||
Chain.prototype.getState = co(function* getState(prev, deployment) {
|
||||
var period = this.network.minerWindow;
|
||||
var threshold = this.network.activationThreshold;
|
||||
var deployment = this.network.deployments[id];
|
||||
var thresholdStates = constants.thresholdStates;
|
||||
var bit = deployment.bit;
|
||||
var timeStart, timeTimeout, compute, height;
|
||||
var i, entry, count, state, block, medianTime;
|
||||
|
||||
assert(deployment);
|
||||
|
||||
timeStart = deployment.startTime;
|
||||
timeTimeout = deployment.timeout;
|
||||
compute = [];
|
||||
var compute = [];
|
||||
var i, entry, count, state;
|
||||
var block, time, height;
|
||||
|
||||
if (!prev)
|
||||
return thresholdStates.DEFINED;
|
||||
@ -1972,9 +1981,9 @@ Chain.prototype.getState = co(function* getState(prev, id) {
|
||||
break;
|
||||
}
|
||||
|
||||
medianTime = yield entry.getMedianTimeAsync();
|
||||
time = yield entry.getMedianTimeAsync();
|
||||
|
||||
if (medianTime < timeStart) {
|
||||
if (time < deployment.startTime) {
|
||||
state = thresholdStates.DEFINED;
|
||||
this.db.stateCache.set(bit, entry, state);
|
||||
break;
|
||||
@ -1991,23 +2000,23 @@ Chain.prototype.getState = co(function* getState(prev, id) {
|
||||
|
||||
switch (state) {
|
||||
case thresholdStates.DEFINED:
|
||||
medianTime = yield entry.getMedianTimeAsync();
|
||||
time = yield entry.getMedianTimeAsync();
|
||||
|
||||
if (medianTime >= timeTimeout) {
|
||||
if (time >= deployment.timeout) {
|
||||
state = thresholdStates.FAILED;
|
||||
break;
|
||||
}
|
||||
|
||||
if (medianTime >= timeStart) {
|
||||
if (time >= deployment.startTime) {
|
||||
state = thresholdStates.STARTED;
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
case thresholdStates.STARTED:
|
||||
medianTime = yield entry.getMedianTimeAsync();
|
||||
time = yield entry.getMedianTimeAsync();
|
||||
|
||||
if (medianTime >= timeTimeout) {
|
||||
if (time >= deployment.timeout) {
|
||||
state = thresholdStates.FAILED;
|
||||
break;
|
||||
}
|
||||
@ -2016,7 +2025,7 @@ Chain.prototype.getState = co(function* getState(prev, id) {
|
||||
count = 0;
|
||||
|
||||
for (i = 0; i < period; i++) {
|
||||
if (block.hasBit(deployment))
|
||||
if (block.hasBit(bit))
|
||||
count++;
|
||||
|
||||
if (count >= threshold) {
|
||||
@ -2054,18 +2063,16 @@ Chain.prototype.getState = co(function* getState(prev, id) {
|
||||
*/
|
||||
|
||||
Chain.prototype.computeBlockVersion = co(function* computeBlockVersion(prev) {
|
||||
var keys = Object.keys(this.network.deployments);
|
||||
var version = 0;
|
||||
var i, id, deployment, state;
|
||||
var i, deployment, state;
|
||||
|
||||
for (i = 0; i < keys.length; i++) {
|
||||
id = keys[i];
|
||||
deployment = this.network.deployments[id];
|
||||
state = yield this.getState(prev, id);
|
||||
for (i = 0; i < this.network.deploys.length; i++) {
|
||||
deployment = this.network.deploys[i];
|
||||
state = yield this.getState(prev, deployment);
|
||||
|
||||
if (state === constants.thresholdStates.LOCKED_IN
|
||||
|| state === constants.thresholdStates.STARTED) {
|
||||
version |= (1 << deployment.bit);
|
||||
version |= 1 << deployment.bit;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2165,31 +2172,6 @@ Chain.prototype.getLocks = co(function* getLocks(prev, tx, flags) {
|
||||
return new LockTimes(minHeight, minTime);
|
||||
});
|
||||
|
||||
/**
|
||||
* Evaluate sequence locks.
|
||||
* @param {ChainEntry} prev
|
||||
* @param {Number} minHeight
|
||||
* @param {Number} minTime
|
||||
* @returns {Promise} - Returns Boolean.
|
||||
*/
|
||||
|
||||
Chain.prototype.evalLocks = co(function* evalLocks(prev, minHeight, minTime) {
|
||||
var medianTime;
|
||||
|
||||
if (minHeight >= prev.height + 1)
|
||||
return false;
|
||||
|
||||
if (minTime === -1)
|
||||
return true;
|
||||
|
||||
medianTime = yield prev.getMedianTimeAsync();
|
||||
|
||||
if (minTime >= medianTime)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
/**
|
||||
* Verify sequence locks.
|
||||
* @param {TX} tx
|
||||
@ -2198,9 +2180,22 @@ Chain.prototype.evalLocks = co(function* evalLocks(prev, minHeight, minTime) {
|
||||
* @returns {Promise} - Returns Boolean.
|
||||
*/
|
||||
|
||||
Chain.prototype.checkLocks = co(function* checkLocks(prev, tx, flags) {
|
||||
var times = yield this.getLocks(prev, tx, flags);
|
||||
return yield this.evalLocks(prev, times.height, times.time);
|
||||
Chain.prototype.verifyLocks = co(function* verifyLocks(prev, tx, flags) {
|
||||
var locks = yield this.getLocks(prev, tx, flags);
|
||||
var medianTime;
|
||||
|
||||
if (locks.height >= prev.height + 1)
|
||||
return false;
|
||||
|
||||
if (locks.time === -1)
|
||||
return true;
|
||||
|
||||
medianTime = yield prev.getMedianTimeAsync();
|
||||
|
||||
if (locks.time >= medianTime)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
/**
|
||||
|
||||
@ -144,6 +144,8 @@ ChainDB.prototype._open = co(function* open() {
|
||||
block = Block.fromRaw(this.network.genesisBlock, 'hex');
|
||||
block.setHeight(0);
|
||||
entry = ChainEntry.fromBlock(this.chain, block);
|
||||
|
||||
this.logger.info('Writing genesis block to ChainDB.');
|
||||
yield this.save(entry, block, new CoinView());
|
||||
}
|
||||
|
||||
@ -793,8 +795,8 @@ ChainDB.prototype.getStateCache = co(function* getStateCache() {
|
||||
var i, items, item;
|
||||
|
||||
items = yield this.db.range({
|
||||
gte: layout.s(0, constants.ZERO_HASH),
|
||||
lte: layout.s(255, constants.MAX_HASH),
|
||||
gte: layout.v(0, constants.ZERO_HASH),
|
||||
lte: layout.v(255, constants.MAX_HASH),
|
||||
values: true
|
||||
});
|
||||
|
||||
@ -816,8 +818,8 @@ ChainDB.prototype.invalidateCache = co(function* invalidateCache(bit, batch) {
|
||||
var i, keys, key;
|
||||
|
||||
keys = yield this.db.keys({
|
||||
gte: layout.s(bit, constants.ZERO_HASH),
|
||||
lte: layout.s(bit, constants.MAX_HASH)
|
||||
gte: layout.v(bit, constants.ZERO_HASH),
|
||||
lte: layout.v(bit, constants.MAX_HASH)
|
||||
});
|
||||
|
||||
for (i = 0; i < keys.length; i++) {
|
||||
@ -833,11 +835,12 @@ ChainDB.prototype.invalidateCache = co(function* invalidateCache(bit, batch) {
|
||||
|
||||
ChainDB.prototype.verifyDeployments = co(function* verifyDeployments() {
|
||||
var expected = this.stateCache.toDeployments();
|
||||
var current = yield this.db.get(layout.v);
|
||||
var current = yield this.db.get(layout.V);
|
||||
var i, invalid, bit, batch;
|
||||
|
||||
if (!current) {
|
||||
yield this.db.put(layout.v, expected);
|
||||
this.logger.info('Writing deployment params to ChainDB.');
|
||||
yield this.db.put(layout.V, expected);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -855,7 +858,7 @@ ChainDB.prototype.verifyDeployments = co(function* verifyDeployments() {
|
||||
yield this.invalidateCache(bit, batch);
|
||||
}
|
||||
|
||||
batch.put(layout.v, expected);
|
||||
batch.put(layout.V, expected);
|
||||
|
||||
yield batch.write();
|
||||
|
||||
@ -1358,7 +1361,7 @@ ChainDB.prototype.saveUpdates = function saveUpdates() {
|
||||
|
||||
for (i = 0; i < updates.length; i++) {
|
||||
update = updates[i];
|
||||
this.put(layout.s(update.bit, update.hash), update.toRaw());
|
||||
this.put(layout.v(update.bit, update.hash), update.toRaw());
|
||||
}
|
||||
};
|
||||
|
||||
@ -2001,34 +2004,33 @@ ChainState.fromRaw = function fromRaw(data) {
|
||||
*/
|
||||
|
||||
function StateCache(network) {
|
||||
this.deployments = network.deployments;
|
||||
this.bits = {};
|
||||
this.cache = {};
|
||||
this.network = network;
|
||||
this.cache = [];
|
||||
this.updates = [];
|
||||
this._init();
|
||||
}
|
||||
|
||||
StateCache.prototype._init = function _init() {
|
||||
var keys = Object.keys(this.deployments);
|
||||
var i, key, deployment, bit;
|
||||
var i, deployment;
|
||||
|
||||
for (i = 0; i < keys.length; i++) {
|
||||
key = keys[i];
|
||||
deployment = this.deployments[key];
|
||||
bit = deployment.bit;
|
||||
this.cache[bit] = {};
|
||||
this.bits[bit] = deployment;
|
||||
for (i = 0; i < 32; i++)
|
||||
this.cache.push(null);
|
||||
|
||||
for (i = 0; i < this.network.deploys.length; i++) {
|
||||
deployment = this.network.deploys[i];
|
||||
assert(!this.cache[deployment.bit]);
|
||||
this.cache[deployment.bit] = {};
|
||||
}
|
||||
};
|
||||
|
||||
StateCache.prototype.toDeployments = function toDeployments() {
|
||||
var p = new BufferWriter();
|
||||
var keys = Object.keys(this.deployments);
|
||||
var i, key, deployment;
|
||||
var i, deployment;
|
||||
|
||||
for (i = 0; i < keys.length; i++) {
|
||||
key = keys[i];
|
||||
deployment = this.deployments[key];
|
||||
p.writeU8(this.network.deploys.length);
|
||||
|
||||
for (i = 0; i < this.network.deploys.length; i++) {
|
||||
deployment = this.network.deploys[i];
|
||||
p.writeU8(deployment.bit);
|
||||
p.writeU32(deployment.startTime);
|
||||
p.writeU32(deployment.timeout);
|
||||
@ -2040,13 +2042,16 @@ StateCache.prototype.toDeployments = function toDeployments() {
|
||||
StateCache.prototype.verifyDeployments = function verifyDeployments(raw) {
|
||||
var p = new BufferReader(raw);
|
||||
var invalid = [];
|
||||
var deployment, bit, start, timeout;
|
||||
var i, count, deployment;
|
||||
var bit, start, timeout;
|
||||
|
||||
while (p.left()) {
|
||||
count = p.readU8();
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
bit = p.readU8();
|
||||
start = p.readU32();
|
||||
timeout = p.readU32();
|
||||
deployment = this.bits[bit];
|
||||
deployment = this.network.byBit(bit);
|
||||
|
||||
if (deployment
|
||||
&& start === deployment.startTime
|
||||
@ -2103,7 +2108,7 @@ StateCache.prototype.drop = function drop() {
|
||||
};
|
||||
|
||||
StateCache.prototype.setRaw = function setRaw(key, value) {
|
||||
var pair = layout.ss(key);
|
||||
var pair = layout.vv(key);
|
||||
var bit = pair[0];
|
||||
var hash = pair[1];
|
||||
var state = value[0];
|
||||
|
||||
@ -362,16 +362,31 @@ ChainEntry.prototype.isHistorical = function isHistorical() {
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Test whether the entry contains an unknown version bit.
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
ChainEntry.prototype.hasUnknown = function hasUnknown() {
|
||||
var bits = this.version & constants.versionbits.TOP_MASK;
|
||||
var topBits = constants.versionbits.TOP_BITS;
|
||||
|
||||
if ((bits >>> 0) !== topBits)
|
||||
return false;
|
||||
|
||||
return (this.version & this.network.unknownBits) !== 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Test whether the entry contains a version bit.
|
||||
* @param {Object} deployment
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
ChainEntry.prototype.hasBit = function hasBit(deployment) {
|
||||
ChainEntry.prototype.hasBit = function hasBit(bit) {
|
||||
var bits = this.version & constants.versionbits.TOP_MASK;
|
||||
var topBits = constants.versionbits.TOP_BITS;
|
||||
var mask = 1 << deployment.bit;
|
||||
var mask = 1 << bit;
|
||||
return (bits >>> 0) === topBits && (this.version & mask) !== 0;
|
||||
};
|
||||
|
||||
|
||||
@ -13,7 +13,7 @@ var pad32 = util.pad32;
|
||||
var layout = {
|
||||
R: 'R',
|
||||
O: 'O',
|
||||
v: 'v',
|
||||
V: 'v',
|
||||
e: function e(hash) {
|
||||
return 'e' + hex(hash);
|
||||
},
|
||||
@ -41,10 +41,10 @@ var layout = {
|
||||
u: function u(hash) {
|
||||
return 'u' + hex(hash);
|
||||
},
|
||||
s: function s(bit, hash) {
|
||||
return 's' + pad8(bit) + hex(hash);
|
||||
v: function v(bit, hash) {
|
||||
return 'v' + pad8(bit) + hex(hash);
|
||||
},
|
||||
ss: function ss(key) {
|
||||
vv: function vv(key) {
|
||||
return [+key.slice(1, 4), key.slice(4, 36)];
|
||||
},
|
||||
T: function T(address, hash) {
|
||||
|
||||
@ -30,7 +30,7 @@
|
||||
var layout = {
|
||||
R: new Buffer([0x52]),
|
||||
O: new Buffer([0x4f]),
|
||||
v: new Buffer([0x76]),
|
||||
V: new Buffer([0x76]),
|
||||
e: function e(hash) {
|
||||
return pair(0x65, hash);
|
||||
},
|
||||
@ -58,14 +58,14 @@ var layout = {
|
||||
u: function u(hash) {
|
||||
return pair(0x75, hash);
|
||||
},
|
||||
s: function s(bit, hash) {
|
||||
v: function v(bit, hash) {
|
||||
var key = new Buffer(1 + 1 + 32);
|
||||
key[0] = 0x73;
|
||||
key[0] = 0x76;
|
||||
key[1] = bit;
|
||||
write(key, hash, 2);
|
||||
return key;
|
||||
},
|
||||
ss: function ss(key) {
|
||||
vv: function vv(key) {
|
||||
return [key[1], key.toString('hex', 2, 34)];
|
||||
},
|
||||
T: function T(address, hash) {
|
||||
|
||||
@ -848,7 +848,7 @@ Mempool.prototype.verify = co(function* verify(entry) {
|
||||
var ret = new VerifyResult();
|
||||
var now, minFee, count, result;
|
||||
|
||||
result = yield this.checkLocks(tx, lockFlags);
|
||||
result = yield this.verifyLocks(tx, lockFlags);
|
||||
|
||||
if (!result) {
|
||||
throw new VerifyError(tx,
|
||||
@ -1522,8 +1522,8 @@ Mempool.prototype.getSnapshot = function getSnapshot() {
|
||||
* @returns {Promise} - Returns Boolean.
|
||||
*/
|
||||
|
||||
Mempool.prototype.checkLocks = function checkLocks(tx, flags) {
|
||||
return this.chain.checkLocks(this.chain.tip, tx, flags);
|
||||
Mempool.prototype.verifyLocks = function verifyLocks(tx, flags) {
|
||||
return this.chain.verifyLocks(this.chain.tip, tx, flags);
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@ -8,7 +8,9 @@
|
||||
'use strict';
|
||||
|
||||
var assert = require('assert');
|
||||
var util = require('../utils/util');
|
||||
var networks = require('./networks');
|
||||
var constants = require('./constants');
|
||||
|
||||
/**
|
||||
* Represents a network.
|
||||
@ -39,6 +41,8 @@ function Network(options) {
|
||||
this.activationThreshold = options.activationThreshold;
|
||||
this.minerWindow = options.minerWindow;
|
||||
this.deployments = options.deployments;
|
||||
this.deploys = options.deploys;
|
||||
this.unknownBits = ~constants.versionbits.TOP_MASK;
|
||||
this.keyPrefix = options.keyPrefix;
|
||||
this.addressPrefix = options.addressPrefix;
|
||||
this.requireStandard = options.requireStandard;
|
||||
@ -49,6 +53,8 @@ function Network(options) {
|
||||
this.selfConnect = options.selfConnect;
|
||||
this.requestMempool = options.requestMempool;
|
||||
this.batchSize = options.batchSize;
|
||||
|
||||
this._init();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -76,6 +82,39 @@ Network.segnet3 = null;
|
||||
Network.segnet4 = null;
|
||||
Network.simnet = null;
|
||||
|
||||
/**
|
||||
* Get a deployment by bit index.
|
||||
* @param {Number} bit
|
||||
* @returns {Object}
|
||||
*/
|
||||
|
||||
Network.prototype._init = function _init() {
|
||||
var bits = 0;
|
||||
var i, deployment;
|
||||
|
||||
for (i = 0; i < this.deploys.length; i++) {
|
||||
deployment = this.deploys[i];
|
||||
bits |= 1 << deployment.bit;
|
||||
}
|
||||
|
||||
bits |= constants.versionbits.TOP_MASK;
|
||||
|
||||
this.unknownBits = ~bits;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a deployment by bit index.
|
||||
* @param {Number} bit
|
||||
* @returns {Object}
|
||||
*/
|
||||
|
||||
Network.prototype.byBit = function byBit(bit) {
|
||||
var index = util.binarySearch(this.deploys, bit, cmpBit);
|
||||
if (index === -1)
|
||||
return null;
|
||||
return this.deploys[index];
|
||||
};
|
||||
|
||||
/**
|
||||
* Determine how many blocks to request
|
||||
* based on current height of the chain.
|
||||
@ -240,6 +279,14 @@ Network.isNetwork = function isNetwork(obj) {
|
||||
|
||||
Network.set(process.env.BCOIN_NETWORK || 'main');
|
||||
|
||||
/*
|
||||
* Helpers
|
||||
*/
|
||||
|
||||
function cmpBit(a, b) {
|
||||
return a.bit - b;
|
||||
}
|
||||
|
||||
/*
|
||||
* Expose
|
||||
*/
|
||||
|
||||
@ -334,24 +334,28 @@ main.minerWindow = 2016; // nPowTargetTimespan / nPowTargetSpacing
|
||||
|
||||
main.deployments = {
|
||||
testdummy: {
|
||||
name: 'testdummy',
|
||||
bit: 28,
|
||||
startTime: 1199145601, // January 1, 2008
|
||||
timeout: 1230767999, // December 31, 2008
|
||||
force: true
|
||||
},
|
||||
csv: {
|
||||
name: 'csv',
|
||||
bit: 0,
|
||||
startTime: 1462060800, // May 1st, 2016
|
||||
timeout: 1493596800, // May 1st, 2017
|
||||
force: true
|
||||
},
|
||||
witness: {
|
||||
name: 'witness',
|
||||
bit: 1,
|
||||
startTime: 1479168000, // November 15th, 2016.
|
||||
timeout: 1510704000, // November 15th, 2017.
|
||||
force: false
|
||||
},
|
||||
mast: {
|
||||
name: 'mast',
|
||||
bit: 2,
|
||||
startTime: 0xffffffff, // Far in the future
|
||||
timeout: 0xffffffff,
|
||||
@ -359,6 +363,19 @@ main.deployments = {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Deployments for versionbits (array form, sorted).
|
||||
* @const {Array}
|
||||
* @default
|
||||
*/
|
||||
|
||||
main.deploys = [
|
||||
main.deployments.csv,
|
||||
main.deployments.witness,
|
||||
main.deployments.mast,
|
||||
main.deployments.testdummy
|
||||
];
|
||||
|
||||
/**
|
||||
* Key prefixes.
|
||||
* @enum {Number}
|
||||
@ -562,24 +579,28 @@ testnet.minerWindow = 2016; // nPowTargetTimespan / nPowTargetSpacing
|
||||
|
||||
testnet.deployments = {
|
||||
testdummy: {
|
||||
name: 'testdummy',
|
||||
bit: 28,
|
||||
startTime: 1199145601, // January 1, 2008
|
||||
timeout: 1230767999, // December 31, 2008
|
||||
force: true
|
||||
},
|
||||
csv: {
|
||||
name: 'csv',
|
||||
bit: 0,
|
||||
startTime: 1456790400, // March 1st, 2016
|
||||
timeout: 1493596800, // May 1st, 2017
|
||||
force: true
|
||||
},
|
||||
witness: {
|
||||
name: 'witness',
|
||||
bit: 1,
|
||||
startTime: 1462060800, // May 1st 2016
|
||||
timeout: 1493596800, // May 1st 2017
|
||||
force: false
|
||||
},
|
||||
mast: {
|
||||
name: 'mast',
|
||||
bit: 2,
|
||||
startTime: 0xffffffff, // Far in the future
|
||||
timeout: 0xffffffff,
|
||||
@ -587,6 +608,13 @@ testnet.deployments = {
|
||||
}
|
||||
};
|
||||
|
||||
testnet.deploys = [
|
||||
testnet.deployments.csv,
|
||||
testnet.deployments.witness,
|
||||
testnet.deployments.mast,
|
||||
testnet.deployments.testdummy
|
||||
];
|
||||
|
||||
testnet.keyPrefix = {
|
||||
privkey: 0xef,
|
||||
xpubkey: 0x043587cf,
|
||||
@ -709,24 +737,28 @@ regtest.minerWindow = 144; // Faster than normal for regtest (144 instead of 201
|
||||
|
||||
regtest.deployments = {
|
||||
testdummy: {
|
||||
name: 'testdummy',
|
||||
bit: 28,
|
||||
startTime: 0,
|
||||
timeout: 0xffffffff,
|
||||
force: true
|
||||
},
|
||||
csv: {
|
||||
name: 'csv',
|
||||
bit: 0,
|
||||
startTime: 0,
|
||||
timeout: 0xffffffff,
|
||||
force: true
|
||||
},
|
||||
witness: {
|
||||
name: 'witness',
|
||||
bit: 1,
|
||||
startTime: 0,
|
||||
timeout: 0xffffffff,
|
||||
force: false
|
||||
},
|
||||
mast: {
|
||||
name: 'mast',
|
||||
bit: 2,
|
||||
startTime: 0xffffffff, // Far in the future
|
||||
timeout: 0xffffffff,
|
||||
@ -734,6 +766,13 @@ regtest.deployments = {
|
||||
}
|
||||
};
|
||||
|
||||
regtest.deploys = [
|
||||
regtest.deployments.csv,
|
||||
regtest.deployments.witness,
|
||||
regtest.deployments.mast,
|
||||
regtest.deployments.testdummy
|
||||
];
|
||||
|
||||
regtest.keyPrefix = {
|
||||
privkey: 0xef,
|
||||
xpubkey: 0x043587cf,
|
||||
@ -857,6 +896,8 @@ segnet3.minerWindow = 144;
|
||||
|
||||
segnet3.deployments = {};
|
||||
|
||||
segnet3.deploys = [];
|
||||
|
||||
segnet3.keyPrefix = {
|
||||
privkey: 0x9e,
|
||||
xpubkey: 0x053587cf,
|
||||
@ -978,18 +1019,21 @@ segnet4.minerWindow = 144;
|
||||
|
||||
segnet4.deployments = {
|
||||
testdummy: {
|
||||
name: 'testdummy',
|
||||
bit: 28,
|
||||
startTime: 1199145601, // January 1, 2008
|
||||
timeout: 1230767999, // December 31, 2008
|
||||
force: true
|
||||
},
|
||||
csv: {
|
||||
name: 'csv',
|
||||
bit: 0,
|
||||
startTime: 1456790400, // March 1st, 2016
|
||||
timeout: 1493596800, // May 1st, 2017
|
||||
force: true
|
||||
},
|
||||
witness: {
|
||||
name: 'witness',
|
||||
bit: 1,
|
||||
startTime: 0,
|
||||
timeout: 999999999999,
|
||||
@ -997,6 +1041,12 @@ segnet4.deployments = {
|
||||
}
|
||||
};
|
||||
|
||||
segnet4.deploys = [
|
||||
segnet4.deployments.csv,
|
||||
segnet4.deployments.witness,
|
||||
segnet4.deployments.testdummy
|
||||
];
|
||||
|
||||
segnet4.keyPrefix = {
|
||||
privkey: 0x9e,
|
||||
xpubkey: 0x053587cf,
|
||||
@ -1120,24 +1170,28 @@ simnet.minerWindow = 2016; // nPowTargetTimespan / nPowTargetSpacing
|
||||
|
||||
simnet.deployments = {
|
||||
testdummy: {
|
||||
name: 'testdummy',
|
||||
bit: 28,
|
||||
startTime: 1199145601, // January 1, 2008
|
||||
timeout: 1230767999, // December 31, 2008
|
||||
force: true
|
||||
},
|
||||
csv: {
|
||||
name: 'csv',
|
||||
bit: 0,
|
||||
startTime: 1456790400, // March 1st, 2016
|
||||
timeout: 1493596800, // May 1st, 2017
|
||||
force: true
|
||||
},
|
||||
witness: {
|
||||
name: 'witness',
|
||||
bit: 1,
|
||||
startTime: 1462060800, // May 1st 2016
|
||||
timeout: 1493596800, // May 1st 2017
|
||||
force: false
|
||||
},
|
||||
mast: {
|
||||
name: 'mast',
|
||||
bit: 2,
|
||||
startTime: 0xffffffff, // Far in the future
|
||||
timeout: 0xffffffff,
|
||||
@ -1145,6 +1199,13 @@ simnet.deployments = {
|
||||
}
|
||||
};
|
||||
|
||||
simnet.deploys = [
|
||||
simnet.deployments.csv,
|
||||
simnet.deployments.witness,
|
||||
simnet.deployments.mast,
|
||||
simnet.deployments.testdummy
|
||||
];
|
||||
|
||||
simnet.keyPrefix = {
|
||||
privkey: 0x64,
|
||||
xpubkey: 0x0420bd3a,
|
||||
|
||||
@ -263,10 +263,11 @@ describe('Chain', function() {
|
||||
}));
|
||||
|
||||
it('should activate csv', cob(function* () {
|
||||
var deployments = chain.network.deployments;
|
||||
var i, block, prev, state, cache;
|
||||
|
||||
prev = yield chain.tip.getPrevious();
|
||||
state = yield chain.getState(prev, 'csv');
|
||||
state = yield chain.getState(prev, deployments.csv);
|
||||
assert(state === 0);
|
||||
|
||||
for (i = 0; i < 417; i++) {
|
||||
@ -275,17 +276,17 @@ describe('Chain', function() {
|
||||
switch (chain.height) {
|
||||
case 144:
|
||||
prev = yield chain.tip.getPrevious();
|
||||
state = yield chain.getState(prev, 'csv');
|
||||
state = yield chain.getState(prev, deployments.csv);
|
||||
assert(state === 1);
|
||||
break;
|
||||
case 288:
|
||||
prev = yield chain.tip.getPrevious();
|
||||
state = yield chain.getState(prev, 'csv');
|
||||
state = yield chain.getState(prev, deployments.csv);
|
||||
assert(state === 2);
|
||||
break;
|
||||
case 432:
|
||||
prev = yield chain.tip.getPrevious();
|
||||
state = yield chain.getState(prev, 'csv');
|
||||
state = yield chain.getState(prev, deployments.csv);
|
||||
assert(state === 3);
|
||||
break;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user