chain: implement bip91 and bip148.
This commit is contained in:
parent
9219e23d8c
commit
3a0c9b60e2
@ -23,6 +23,7 @@ const CoinView = require('../coins/coinview');
|
||||
const Script = require('../script/script');
|
||||
const {VerifyError} = require('../protocol/errors');
|
||||
const co = require('../utils/co');
|
||||
const thresholdStates = common.thresholdStates;
|
||||
|
||||
/**
|
||||
* Represents a blockchain.
|
||||
@ -106,6 +107,12 @@ Chain.prototype._open = async function open() {
|
||||
if (this.options.coinCache)
|
||||
this.logger.info('Coin cache is enabled.');
|
||||
|
||||
if (this.options.bip91)
|
||||
this.logger.warning('BIP91 enabled. Segsignal will be enforced.');
|
||||
|
||||
if (this.options.bip148)
|
||||
this.logger.warning('BIP148 enabled. UASF will be enforced.');
|
||||
|
||||
await this.db.open();
|
||||
|
||||
tip = await this.db.getTip();
|
||||
@ -219,6 +226,7 @@ Chain.prototype.isGenesis = function isGenesis(block) {
|
||||
*/
|
||||
|
||||
Chain.prototype.verify = async function verify(block, prev, flags) {
|
||||
let deployments = this.network.deployments;
|
||||
let hash = block.hash('hex');
|
||||
let now = this.network.now();
|
||||
let height = prev.height + 1;
|
||||
@ -315,6 +323,12 @@ Chain.prototype.verify = async function verify(block, prev, flags) {
|
||||
// Get the new deployment state.
|
||||
state = await this.getDeployments(block.ts, prev);
|
||||
|
||||
// Enforce BIP91/BIP148.
|
||||
if (state.hasBIP91() || state.hasBIP148()) {
|
||||
if (!consensus.hasBit(block.version, deployments.segwit.bit))
|
||||
throw new VerifyError(block, 'invalid', 'bad-no-segwit', 0);
|
||||
}
|
||||
|
||||
// Get timestamp for tx.isFinal().
|
||||
ts = state.hasMTP() ? mtp : block.ts;
|
||||
|
||||
@ -404,7 +418,7 @@ Chain.prototype.getDeployments = async function getDeployments(ts, prev) {
|
||||
let deployments = this.network.deployments;
|
||||
let height = prev.height + 1;
|
||||
let state = new DeploymentState();
|
||||
let active;
|
||||
let witness;
|
||||
|
||||
// For some reason bitcoind has p2sh in the
|
||||
// mandatory flags by default, when in reality
|
||||
@ -431,21 +445,47 @@ Chain.prototype.getDeployments = async function getDeployments(ts, prev) {
|
||||
|
||||
// CHECKSEQUENCEVERIFY and median time
|
||||
// past locktimes are now usable (bip9 & bip113).
|
||||
active = await this.isActive(prev, deployments.csv);
|
||||
if (active) {
|
||||
if (await this.isActive(prev, deployments.csv)) {
|
||||
state.flags |= Script.flags.VERIFY_CHECKSEQUENCEVERIFY;
|
||||
state.lockFlags |= common.lockFlags.VERIFY_SEQUENCE;
|
||||
state.lockFlags |= common.lockFlags.MEDIAN_TIME_PAST;
|
||||
}
|
||||
|
||||
// Segregrated witness is now usable (bip141).
|
||||
active = await this.isActive(prev, deployments.segwit);
|
||||
if (active) {
|
||||
// Check the state of the segwit deployment.
|
||||
witness = await this.getState(prev, deployments.segwit);
|
||||
|
||||
// Segregrated witness (bip141) is now usable
|
||||
// along with SCRIPT_VERIFY_NULLDUMMY (bip147).
|
||||
if (witness === thresholdStates.ACTIVE) {
|
||||
state.flags |= Script.flags.VERIFY_WITNESS;
|
||||
// BIP147
|
||||
state.flags |= Script.flags.VERIFY_NULLDUMMY;
|
||||
}
|
||||
|
||||
// Segsignal is now enforced (bip91).
|
||||
if (this.options.bip91) {
|
||||
if (witness === thresholdStates.STARTED) {
|
||||
if (await this.isActive(prev, deployments.segsignal))
|
||||
state.bip91 = true;
|
||||
}
|
||||
}
|
||||
|
||||
// UASF is now enforced (bip148) (mainnet-only).
|
||||
if (this.options.bip148 && this.network === Network.main) {
|
||||
if (witness !== thresholdStates.LOCKED_IN
|
||||
&& witness !== thresholdStates.ACTIVE) {
|
||||
// The BIP148 MTP check is nonsensical in
|
||||
// that it includes the _current_ entry's
|
||||
// timestamp. This requires some hackery,
|
||||
// since bcoin only operates on the sane
|
||||
// assumption that deployment checks should
|
||||
// only ever examine the values of the
|
||||
// previous block (necessary for mining).
|
||||
let mtp = await prev.getMedianTime(ts);
|
||||
if (mtp >= 1501545600 && mtp <= 1510704000)
|
||||
state.bip148 = true;
|
||||
}
|
||||
}
|
||||
|
||||
return state;
|
||||
};
|
||||
|
||||
@ -473,6 +513,12 @@ Chain.prototype.setDeploymentState = function setDeploymentState(state) {
|
||||
if (!this.state.hasWitness() && state.hasWitness())
|
||||
this.logger.warning('Segwit has been activated.');
|
||||
|
||||
if (!this.state.hasBIP91() && state.hasBIP91())
|
||||
this.logger.warning('BIP91 has been activated.');
|
||||
|
||||
if (!this.state.hasBIP148() && state.hasBIP148())
|
||||
this.logger.warning('BIP148 has been activated.');
|
||||
|
||||
this.state = state;
|
||||
};
|
||||
|
||||
@ -2056,7 +2102,7 @@ Chain.prototype.findLocator = async function findLocator(locator) {
|
||||
|
||||
Chain.prototype.isActive = async function isActive(prev, deployment) {
|
||||
let state = await this.getState(prev, deployment);
|
||||
return state === common.thresholdStates.ACTIVE;
|
||||
return state === thresholdStates.ACTIVE;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -2071,22 +2117,27 @@ Chain.prototype.isActive = async function isActive(prev, deployment) {
|
||||
*/
|
||||
|
||||
Chain.prototype.getState = async function getState(prev, deployment) {
|
||||
let period = this.network.minerWindow;
|
||||
let window = this.network.minerWindow;
|
||||
let threshold = this.network.activationThreshold;
|
||||
let thresholdStates = common.thresholdStates;
|
||||
let bit = deployment.bit;
|
||||
let compute = [];
|
||||
let entry, state;
|
||||
|
||||
if (((prev.height + 1) % period) !== 0) {
|
||||
let height = prev.height - ((prev.height + 1) % period);
|
||||
if (deployment.threshold !== -1)
|
||||
threshold = deployment.threshold;
|
||||
|
||||
if (deployment.window !== -1)
|
||||
window = deployment.window;
|
||||
|
||||
if (((prev.height + 1) % window) !== 0) {
|
||||
let height = prev.height - ((prev.height + 1) % window);
|
||||
prev = await prev.getAncestor(height);
|
||||
|
||||
if (!prev)
|
||||
return thresholdStates.DEFINED;
|
||||
|
||||
assert(prev.height === height);
|
||||
assert(((prev.height + 1) % period) === 0);
|
||||
assert(((prev.height + 1) % window) === 0);
|
||||
}
|
||||
|
||||
entry = prev;
|
||||
@ -2111,7 +2162,7 @@ Chain.prototype.getState = async function getState(prev, deployment) {
|
||||
|
||||
compute.push(entry);
|
||||
|
||||
height = entry.height - period;
|
||||
height = entry.height - window;
|
||||
entry = await entry.getAncestor(height);
|
||||
}
|
||||
|
||||
@ -2144,7 +2195,7 @@ Chain.prototype.getState = async function getState(prev, deployment) {
|
||||
break;
|
||||
}
|
||||
|
||||
for (let i = 0; i < period; i++) {
|
||||
for (let i = 0; i < window; i++) {
|
||||
if (block.hasBit(bit))
|
||||
count++;
|
||||
|
||||
@ -2193,8 +2244,8 @@ Chain.prototype.computeBlockVersion = async function computeBlockVersion(prev) {
|
||||
for (let deployment of this.network.deploys) {
|
||||
let state = await this.getState(prev, deployment);
|
||||
|
||||
if (state === common.thresholdStates.LOCKED_IN
|
||||
|| state === common.thresholdStates.STARTED) {
|
||||
if (state === thresholdStates.LOCKED_IN
|
||||
|| state === thresholdStates.STARTED) {
|
||||
version |= 1 << deployment.bit;
|
||||
}
|
||||
}
|
||||
@ -2356,11 +2407,12 @@ function ChainOptions(options) {
|
||||
this.bufferKeys = ChainDB.layout.binary;
|
||||
|
||||
this.spv = false;
|
||||
this.bip91 = false;
|
||||
this.bip148 = false;
|
||||
this.prune = false;
|
||||
this.indexTX = false;
|
||||
this.indexAddress = false;
|
||||
this.forceWitness = false;
|
||||
this.forcePrune = false;
|
||||
this.forceFlags = false;
|
||||
|
||||
this.coinCache = 0;
|
||||
this.entryCache = 5000;
|
||||
@ -2445,16 +2497,19 @@ ChainOptions.prototype.fromOptions = function fromOptions(options) {
|
||||
this.indexAddress = options.indexAddress;
|
||||
}
|
||||
|
||||
if (options.forceWitness != null) {
|
||||
assert(typeof options.forceWitness === 'boolean');
|
||||
this.forceWitness = options.forceWitness;
|
||||
if (options.forceFlags != null) {
|
||||
assert(typeof options.forceFlags === 'boolean');
|
||||
this.forceFlags = options.forceFlags;
|
||||
}
|
||||
|
||||
if (options.forcePrune != null) {
|
||||
assert(typeof options.forcePrune === 'boolean');
|
||||
this.forcePrune = options.forcePrune;
|
||||
if (options.forcePrune)
|
||||
this.prune = true;
|
||||
if (options.bip91 != null) {
|
||||
assert(typeof options.bip91 === 'boolean');
|
||||
this.bip91 = options.bip91;
|
||||
}
|
||||
|
||||
if (options.bip148 != null) {
|
||||
assert(typeof options.bip148 === 'boolean');
|
||||
this.bip148 = options.bip148;
|
||||
}
|
||||
|
||||
if (options.coinCache != null) {
|
||||
@ -2507,6 +2562,8 @@ function DeploymentState() {
|
||||
this.flags &= ~Script.flags.VERIFY_P2SH;
|
||||
this.lockFlags = common.lockFlags.MANDATORY_LOCKTIME_FLAGS;
|
||||
this.bip34 = false;
|
||||
this.bip91 = false;
|
||||
this.bip148 = false;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2572,6 +2629,24 @@ DeploymentState.prototype.hasWitness = function hasWitness() {
|
||||
return (this.flags & Script.flags.VERIFY_WITNESS) !== 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Test whether bip91 is active.
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
DeploymentState.prototype.hasBIP91 = function hasBIP91() {
|
||||
return this.bip91;
|
||||
};
|
||||
|
||||
/**
|
||||
* Test whether bip148 is active.
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
DeploymentState.prototype.hasBIP148 = function hasBIP148() {
|
||||
return this.bip148;
|
||||
};
|
||||
|
||||
/**
|
||||
* Orphan
|
||||
* @constructor
|
||||
|
||||
@ -495,7 +495,7 @@ ChainDB.prototype.getFlags = async function getFlags() {
|
||||
ChainDB.prototype.verifyFlags = async function verifyFlags(state) {
|
||||
let options = this.options;
|
||||
let flags = await this.getFlags();
|
||||
let needsWitness = false;
|
||||
let needsSave = false;
|
||||
let needsPrune = false;
|
||||
|
||||
if (!flags)
|
||||
@ -511,13 +511,25 @@ ChainDB.prototype.verifyFlags = async function verifyFlags(state) {
|
||||
throw new Error('Cannot retroactively disable SPV.');
|
||||
|
||||
if (!flags.witness) {
|
||||
if (!options.forceWitness)
|
||||
if (!options.forceFlags)
|
||||
throw new Error('Cannot retroactively enable witness.');
|
||||
needsWitness = true;
|
||||
needsSave = true;
|
||||
}
|
||||
|
||||
if (options.bip91 !== flags.bip91) {
|
||||
if (!options.forceFlags)
|
||||
throw new Error('Cannot retroactively alter BIP91 flag.');
|
||||
needsSave = true;
|
||||
}
|
||||
|
||||
if (options.bip148 !== flags.bip148) {
|
||||
if (!options.forceFlags)
|
||||
throw new Error('Cannot retroactively alter BIP148 flag.');
|
||||
needsSave = true;
|
||||
}
|
||||
|
||||
if (options.prune && !flags.prune) {
|
||||
if (!options.forcePrune)
|
||||
if (!options.forceFlags)
|
||||
throw new Error('Cannot retroactively prune.');
|
||||
needsPrune = true;
|
||||
}
|
||||
@ -537,8 +549,8 @@ ChainDB.prototype.verifyFlags = async function verifyFlags(state) {
|
||||
if (!options.indexAddress && flags.indexAddress)
|
||||
throw new Error('Cannot retroactively disable address indexing.');
|
||||
|
||||
if (needsWitness) {
|
||||
await this.logger.info('Writing witness bit to chain flags.');
|
||||
if (needsSave) {
|
||||
await this.logger.info('Rewriting chain flags.');
|
||||
await this.saveFlags();
|
||||
}
|
||||
|
||||
@ -589,7 +601,7 @@ ChainDB.prototype.saveDeployments = function saveDeployments() {
|
||||
*/
|
||||
|
||||
ChainDB.prototype.writeDeployments = function writeDeployments(batch) {
|
||||
let bw = new StaticWriter(1 + 9 * this.network.deploys.length);
|
||||
let bw = new StaticWriter(1 + 17 * this.network.deploys.length);
|
||||
|
||||
bw.writeU8(this.network.deploys.length);
|
||||
|
||||
@ -597,6 +609,8 @@ ChainDB.prototype.writeDeployments = function writeDeployments(batch) {
|
||||
bw.writeU8(deployment.bit);
|
||||
bw.writeU32(deployment.startTime);
|
||||
bw.writeU32(deployment.timeout);
|
||||
bw.write32(deployment.threshold);
|
||||
bw.write32(deployment.window);
|
||||
}
|
||||
|
||||
batch.put(layout.V, bw.render());
|
||||
@ -623,11 +637,15 @@ ChainDB.prototype.checkDeployments = async function checkDeployments() {
|
||||
let bit = br.readU8();
|
||||
let start = br.readU32();
|
||||
let timeout = br.readU32();
|
||||
let threshold = br.read32();
|
||||
let window = br.read32();
|
||||
let deployment = this.network.byBit(bit);
|
||||
|
||||
if (deployment
|
||||
&& start === deployment.startTime
|
||||
&& timeout === deployment.timeout) {
|
||||
&& timeout === deployment.timeout
|
||||
&& threshold === deployment.threshold
|
||||
&& window === deployment.window) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -644,8 +662,17 @@ ChainDB.prototype.checkDeployments = async function checkDeployments() {
|
||||
*/
|
||||
|
||||
ChainDB.prototype.verifyDeployments = async function verifyDeployments() {
|
||||
let invalid = await this.checkDeployments();
|
||||
let batch;
|
||||
let invalid, batch;
|
||||
|
||||
try {
|
||||
invalid = await this.checkDeployments();
|
||||
} catch (e) {
|
||||
if (e.type !== 'EncodingError')
|
||||
throw e;
|
||||
invalid = [];
|
||||
for (let {bit} of this.network.deploys)
|
||||
invalid.push(bit);
|
||||
}
|
||||
|
||||
if (invalid.length === 0)
|
||||
return true;
|
||||
@ -1946,6 +1973,8 @@ function ChainFlags(options) {
|
||||
this.network = Network.primary;
|
||||
this.spv = false;
|
||||
this.witness = true;
|
||||
this.bip91 = false;
|
||||
this.bip148 = false;
|
||||
this.prune = false;
|
||||
this.indexTX = false;
|
||||
this.indexAddress = false;
|
||||
@ -1962,6 +1991,16 @@ ChainFlags.prototype.fromOptions = function fromOptions(options) {
|
||||
this.spv = options.spv;
|
||||
}
|
||||
|
||||
if (options.bip91 != null) {
|
||||
assert(typeof options.bip91 === 'boolean');
|
||||
this.bip91 = options.bip91;
|
||||
}
|
||||
|
||||
if (options.bip148 != null) {
|
||||
assert(typeof options.bip148 === 'boolean');
|
||||
this.bip148 = options.bip148;
|
||||
}
|
||||
|
||||
if (options.prune != null) {
|
||||
assert(typeof options.prune === 'boolean');
|
||||
this.prune = options.prune;
|
||||
@ -2003,6 +2042,12 @@ ChainFlags.prototype.toRaw = function toRaw() {
|
||||
if (this.indexAddress)
|
||||
flags |= 1 << 4;
|
||||
|
||||
if (this.bip91)
|
||||
flags |= 1 << 5;
|
||||
|
||||
if (this.bip148)
|
||||
flags |= 1 << 6;
|
||||
|
||||
bw.writeU32(this.network.magic);
|
||||
bw.writeU32(flags);
|
||||
bw.writeU32(0);
|
||||
@ -2023,6 +2068,8 @@ ChainFlags.prototype.fromRaw = function fromRaw(data) {
|
||||
this.prune = (flags & 4) !== 0;
|
||||
this.indexTX = (flags & 8) !== 0;
|
||||
this.indexAddress = (flags & 16) !== 0;
|
||||
this.bip91 = (flags & 32) !== 0;
|
||||
this.bip148 = (flags & 64) !== 0;
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
@ -267,14 +267,23 @@ ChainEntry.prototype.getNextEntry = async function getNextEntry() {
|
||||
/**
|
||||
* Calculate median time past.
|
||||
* @method
|
||||
* @param {Number?} ts
|
||||
* @returns {Promise} - Returns Number.
|
||||
*/
|
||||
|
||||
ChainEntry.prototype.getMedianTime = async function getMedianTime() {
|
||||
ChainEntry.prototype.getMedianTime = async function getMedianTime(ts) {
|
||||
let timespan = ChainEntry.MEDIAN_TIMESPAN;
|
||||
let entry = this;
|
||||
let median = [];
|
||||
|
||||
// In case we ever want to check
|
||||
// the MTP of the _current_ block
|
||||
// (necessary for BIP148).
|
||||
if (ts != null) {
|
||||
median.push(ts);
|
||||
timespan -= 1;
|
||||
}
|
||||
|
||||
for (let i = 0; i < timespan && entry; i++) {
|
||||
let cache;
|
||||
|
||||
@ -331,10 +340,7 @@ ChainEntry.prototype.hasUnknown = function hasUnknown() {
|
||||
*/
|
||||
|
||||
ChainEntry.prototype.hasBit = function hasBit(bit) {
|
||||
let bits = this.version & consensus.VERSION_TOP_MASK;
|
||||
let topBits = consensus.VERSION_TOP_BITS;
|
||||
let mask = 1 << bit;
|
||||
return (bits >>> 0) === topBits && (this.version & mask) !== 0;
|
||||
return consensus.hasBit(this.version, bit);
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@ -1247,6 +1247,9 @@ RPC.prototype.getBlockTemplate = async function getBlockTemplate(args, help) {
|
||||
if (lpid)
|
||||
await this.handleLongpoll(lpid);
|
||||
|
||||
if (!rules)
|
||||
rules = [];
|
||||
|
||||
return await this.createTemplate(maxVersion, coinbase, rules);
|
||||
};
|
||||
|
||||
@ -1322,6 +1325,14 @@ RPC.prototype._createTemplate = async function _createTemplate(maxVersion, coinb
|
||||
});
|
||||
}
|
||||
|
||||
if (this.chain.options.bip91) {
|
||||
rules.push('segwit');
|
||||
rules.push('segsignal');
|
||||
}
|
||||
|
||||
if (this.chain.options.bip148)
|
||||
rules.push('segwit');
|
||||
|
||||
// Calculate version based on given rules.
|
||||
for (let deploy of this.network.deploys) {
|
||||
let state = await this.chain.getState(this.chain.tip, deploy);
|
||||
@ -1335,15 +1346,16 @@ RPC.prototype._createTemplate = async function _createTemplate(maxVersion, coinb
|
||||
version |= 1 << deploy.bit;
|
||||
case common.thresholdStates.STARTED:
|
||||
if (!deploy.force) {
|
||||
if (!rules || rules.indexOf(name) === -1)
|
||||
if (rules.indexOf(name) === -1)
|
||||
version &= ~(1 << deploy.bit);
|
||||
name = '!' + name;
|
||||
if (deploy.required)
|
||||
name = '!' + name;
|
||||
}
|
||||
vbavailable[name] = deploy.bit;
|
||||
break;
|
||||
case common.thresholdStates.ACTIVE:
|
||||
if (!deploy.force) {
|
||||
if (!rules || rules.indexOf(name) === -1) {
|
||||
if (!deploy.force && deploy.required) {
|
||||
if (rules.indexOf(name) === -1) {
|
||||
throw new RPCError(errs.INVALID_PARAMETER,
|
||||
`Client must support ${name}.`);
|
||||
}
|
||||
@ -1431,7 +1443,7 @@ RPC.prototype._createTemplate = async function _createTemplate(maxVersion, coinb
|
||||
json.coinbasevalue = attempt.getReward();
|
||||
}
|
||||
|
||||
if (rules && rules.indexOf('segwit') !== -1)
|
||||
if (rules.indexOf('segwit') !== -1)
|
||||
json.default_witness_commitment = attempt.getWitnessScript().toJSON();
|
||||
|
||||
return json;
|
||||
|
||||
@ -56,8 +56,9 @@ function FullNode(options) {
|
||||
prefix: this.config.prefix,
|
||||
maxFiles: this.config.num('max-files'),
|
||||
cacheSize: this.config.mb('cache-size'),
|
||||
forceWitness: this.config.bool('force-witness'),
|
||||
forcePrune: this.config.bool('force-prune'),
|
||||
forceFlags: this.config.bool('force-flags'),
|
||||
bip91: this.config.bool('bip91'),
|
||||
bip148: this.config.bool('bip148'),
|
||||
prune: this.config.bool('prune'),
|
||||
checkpoints: this.config.bool('checkpoints'),
|
||||
coinCache: this.config.mb('coin-cache'),
|
||||
|
||||
@ -52,8 +52,10 @@ function SPVNode(options) {
|
||||
maxFiles: this.config.num('max-files'),
|
||||
cacheSize: this.config.mb('cache-size'),
|
||||
entryCache: this.config.num('entry-cache'),
|
||||
forceWitness: this.config.bool('force-witness'),
|
||||
forceFlags: this.config.bool('force-flags'),
|
||||
checkpoints: this.config.bool('checkpoints'),
|
||||
bip91: this.config.bool('bip91'),
|
||||
bip148: this.config.bool('bip148'),
|
||||
spv: true
|
||||
});
|
||||
|
||||
|
||||
@ -332,3 +332,17 @@ exports.getReward = function getReward(height, interval) {
|
||||
|
||||
return exports.HALF_REWARD >>> (halvings - 1);
|
||||
};
|
||||
|
||||
/**
|
||||
* Test version bit.
|
||||
* @param {Number} version
|
||||
* @param {Number} bit
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
exports.hasBit = function hasBit(version, bit) {
|
||||
let bits = version & exports.VERSION_TOP_MASK;
|
||||
let topBits = exports.VERSION_TOP_BITS;
|
||||
let mask = 1 << bit;
|
||||
return (bits >>> 0) === topBits && (version & mask) !== 0;
|
||||
};
|
||||
|
||||
@ -335,18 +335,14 @@ 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
|
||||
threshold: -1,
|
||||
window: -1,
|
||||
required: false,
|
||||
force: true
|
||||
},
|
||||
segwit: {
|
||||
@ -354,7 +350,30 @@ main.deployments = {
|
||||
bit: 1,
|
||||
startTime: 1479168000, // November 15th, 2016.
|
||||
timeout: 1510704000, // November 15th, 2017.
|
||||
threshold: -1,
|
||||
window: -1,
|
||||
required: true,
|
||||
force: false
|
||||
},
|
||||
segsignal: {
|
||||
name: 'segsignal',
|
||||
bit: 4,
|
||||
startTime: 1496275200, // June 1st, 2017.
|
||||
timeout: 1510704000, // November 15th, 2017.
|
||||
threshold: 269, // 80%
|
||||
window: 336, // ~2.33 days
|
||||
required: false,
|
||||
force: false
|
||||
},
|
||||
testdummy: {
|
||||
name: 'testdummy',
|
||||
bit: 28,
|
||||
startTime: 1199145601, // January 1, 2008
|
||||
timeout: 1230767999, // December 31, 2008
|
||||
threshold: -1,
|
||||
window: -1,
|
||||
required: false,
|
||||
force: true
|
||||
}
|
||||
};
|
||||
|
||||
@ -367,6 +386,7 @@ main.deployments = {
|
||||
main.deploys = [
|
||||
main.deployments.csv,
|
||||
main.deployments.segwit,
|
||||
main.deployments.segsignal,
|
||||
main.deployments.testdummy
|
||||
];
|
||||
|
||||
@ -555,18 +575,14 @@ testnet.activationThreshold = 1512; // 75% for testchains
|
||||
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
|
||||
threshold: -1,
|
||||
window: -1,
|
||||
required: false,
|
||||
force: true
|
||||
},
|
||||
segwit: {
|
||||
@ -574,13 +590,37 @@ testnet.deployments = {
|
||||
bit: 1,
|
||||
startTime: 1462060800, // May 1st 2016
|
||||
timeout: 1493596800, // May 1st 2017
|
||||
threshold: -1,
|
||||
window: -1,
|
||||
required: true,
|
||||
force: false
|
||||
},
|
||||
segsignal: {
|
||||
name: 'segsignal',
|
||||
bit: 4,
|
||||
startTime: 0xffffffff,
|
||||
timeout: 0xffffffff,
|
||||
threshold: 269,
|
||||
window: 336,
|
||||
required: false,
|
||||
force: false
|
||||
},
|
||||
testdummy: {
|
||||
name: 'testdummy',
|
||||
bit: 28,
|
||||
startTime: 1199145601, // January 1, 2008
|
||||
timeout: 1230767999, // December 31, 2008
|
||||
threshold: -1,
|
||||
window: -1,
|
||||
required: false,
|
||||
force: true
|
||||
}
|
||||
};
|
||||
|
||||
testnet.deploys = [
|
||||
testnet.deployments.csv,
|
||||
testnet.deployments.segwit,
|
||||
testnet.deployments.segsignal,
|
||||
testnet.deployments.testdummy
|
||||
];
|
||||
|
||||
@ -695,18 +735,14 @@ regtest.activationThreshold = 108; // 75% for testchains
|
||||
regtest.minerWindow = 144; // Faster than normal for regtest (144 instead of 2016)
|
||||
|
||||
regtest.deployments = {
|
||||
testdummy: {
|
||||
name: 'testdummy',
|
||||
bit: 28,
|
||||
startTime: 0,
|
||||
timeout: 0xffffffff,
|
||||
force: true
|
||||
},
|
||||
csv: {
|
||||
name: 'csv',
|
||||
bit: 0,
|
||||
startTime: 0,
|
||||
timeout: 0xffffffff,
|
||||
threshold: -1,
|
||||
window: -1,
|
||||
required: false,
|
||||
force: true
|
||||
},
|
||||
segwit: {
|
||||
@ -714,13 +750,37 @@ regtest.deployments = {
|
||||
bit: 1,
|
||||
startTime: 0,
|
||||
timeout: 0xffffffff,
|
||||
threshold: -1,
|
||||
window: -1,
|
||||
required: true,
|
||||
force: false
|
||||
},
|
||||
segsignal: {
|
||||
name: 'segsignal',
|
||||
bit: 4,
|
||||
startTime: 0xffffffff,
|
||||
timeout: 0xffffffff,
|
||||
threshold: 269,
|
||||
window: 336,
|
||||
required: false,
|
||||
force: false
|
||||
},
|
||||
testdummy: {
|
||||
name: 'testdummy',
|
||||
bit: 28,
|
||||
startTime: 0,
|
||||
timeout: 0xffffffff,
|
||||
threshold: -1,
|
||||
window: -1,
|
||||
required: false,
|
||||
force: true
|
||||
}
|
||||
};
|
||||
|
||||
regtest.deploys = [
|
||||
regtest.deployments.csv,
|
||||
regtest.deployments.segwit,
|
||||
regtest.deployments.segsignal,
|
||||
regtest.deployments.testdummy
|
||||
];
|
||||
|
||||
@ -837,18 +897,14 @@ segnet4.activationThreshold = 108;
|
||||
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
|
||||
threshold: -1,
|
||||
window: -1,
|
||||
required: false,
|
||||
force: true
|
||||
},
|
||||
segwit: {
|
||||
@ -856,13 +912,37 @@ segnet4.deployments = {
|
||||
bit: 1,
|
||||
startTime: 0,
|
||||
timeout: 0xffffffff,
|
||||
threshold: -1,
|
||||
window: -1,
|
||||
required: true,
|
||||
force: false
|
||||
},
|
||||
segsignal: {
|
||||
name: 'segsignal',
|
||||
bit: 4,
|
||||
startTime: 0xffffffff,
|
||||
timeout: 0xffffffff,
|
||||
threshold: 269,
|
||||
window: 336,
|
||||
required: false,
|
||||
force: false
|
||||
},
|
||||
testdummy: {
|
||||
name: 'testdummy',
|
||||
bit: 28,
|
||||
startTime: 1199145601, // January 1, 2008
|
||||
timeout: 1230767999, // December 31, 2008
|
||||
threshold: -1,
|
||||
window: -1,
|
||||
required: false,
|
||||
force: true
|
||||
}
|
||||
};
|
||||
|
||||
segnet4.deploys = [
|
||||
segnet4.deployments.csv,
|
||||
segnet4.deployments.segwit,
|
||||
segnet4.deployments.segsignal,
|
||||
segnet4.deployments.testdummy
|
||||
];
|
||||
|
||||
@ -979,18 +1059,14 @@ simnet.activationThreshold = 75; // 75% for testchains
|
||||
simnet.minerWindow = 100; // 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: 0, // March 1st, 2016
|
||||
timeout: 0xffffffff, // May 1st, 2017
|
||||
threshold: -1,
|
||||
window: -1,
|
||||
required: false,
|
||||
force: true
|
||||
},
|
||||
segwit: {
|
||||
@ -998,13 +1074,37 @@ simnet.deployments = {
|
||||
bit: 1,
|
||||
startTime: 0, // May 1st 2016
|
||||
timeout: 0xffffffff, // May 1st 2017
|
||||
threshold: -1,
|
||||
window: -1,
|
||||
required: true,
|
||||
force: false
|
||||
},
|
||||
segsignal: {
|
||||
name: 'segsignal',
|
||||
bit: 4,
|
||||
startTime: 0xffffffff,
|
||||
timeout: 0xffffffff,
|
||||
threshold: 269,
|
||||
window: 336,
|
||||
required: false,
|
||||
force: false
|
||||
},
|
||||
testdummy: {
|
||||
name: 'testdummy',
|
||||
bit: 28,
|
||||
startTime: 1199145601, // January 1, 2008
|
||||
timeout: 1230767999, // December 31, 2008
|
||||
threshold: -1,
|
||||
window: -1,
|
||||
required: false,
|
||||
force: true
|
||||
}
|
||||
};
|
||||
|
||||
simnet.deploys = [
|
||||
simnet.deployments.csv,
|
||||
simnet.deployments.segwit,
|
||||
simnet.deployments.segsignal,
|
||||
simnet.deployments.testdummy
|
||||
];
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user