This commit is contained in:
Christopher Jeffrey 2016-03-30 19:10:59 -07:00
parent 9b4e363a80
commit f62ceb8515
8 changed files with 232 additions and 115 deletions

View File

@ -502,52 +502,73 @@ Chain.prototype._verify = function _verify(block, prev, callback) {
// if (block.version >= 8 && prev.isUpgraded(8))
// lockFlags |= constants.flags.MEDIAN_TIME_PAST;
// Can't verify any further when merkleblock or headers.
if (block.type !== 'block')
return done(null, flags);
if (network.type === 'segnet4') {
self.getState(prev, null, 'witness', function(err, state) {
if (err)
return callback(err);
// Make sure the height contained in the coinbase is correct.
if (coinbaseHeight) {
if (block.getCoinbaseHeight() !== height)
return done(new VerifyError(block, 'invalid', 'bad-cb-height', 100));
}
if (state === constants.thresholdStates.ACTIVE) {
flags |= constants.flags.VERIFY_WITNESS;
segwit = true;
self.segwitActive = true;
} else {
self.segwitActive = false;
}
if (block.version >= 5 && segwit) {
if (block.commitmentHash !== block.getCommitmentHash()) {
return done(new VerifyError(block,
'invalid',
'bad-blk-wit-length',
100));
}
return finish();
});
} else {
if (block.hasWitness()) {
return done(new VerifyError(block,
'invalid',
'unexpected-witness',
100));
}
finish();
}
// Get timestamp for tx.isFinal().
ts = (lockFlags & constants.flags.MEDIAN_TIME_PAST)
? medianTime
: block.ts;
function finish() {
// Can't verify any further when merkleblock or headers.
if (block.type !== 'block')
return done(null, flags);
// Check all transactions
for (i = 0; i < block.txs.length; i++) {
tx = block.txs[i];
// Transactions must be finalized with
// regards to nSequence and nLockTime.
if (!tx.isFinal(height, ts)) {
return done(new VerifyError(block,
'invalid',
'bad-txns-nonfinal',
10));
// Make sure the height contained in the coinbase is correct.
if (coinbaseHeight) {
if (block.getCoinbaseHeight() !== height)
return done(new VerifyError(block, 'invalid', 'bad-cb-height', 100));
}
}
return done(null, flags);
if (block.version >= 5 && segwit) {
if (block.commitmentHash !== block.getCommitmentHash()) {
return done(new VerifyError(block,
'invalid',
'bad-blk-wit-length',
100));
}
} else {
if (block.hasWitness()) {
return done(new VerifyError(block,
'invalid',
'unexpected-witness',
100));
}
}
// Get timestamp for tx.isFinal().
ts = (lockFlags & constants.flags.MEDIAN_TIME_PAST)
? medianTime
: block.ts;
// Check all transactions
for (i = 0; i < block.txs.length; i++) {
tx = block.txs[i];
// Transactions must be finalized with
// regards to nSequence and nLockTime.
if (!tx.isFinal(height, ts)) {
return done(new VerifyError(block,
'invalid',
'bad-txns-nonfinal',
10));
}
}
return done(null, flags);
}
});
};
@ -1770,7 +1791,7 @@ Chain.prototype.getState = function getState(prev, block, id, callback) {
timeTimeout = deployment.timeout;
compute = [];
if (block && block.isGenesis())
if (!prev)
return callback(null, constants.thresholdStates.DEFINED);
if (((prev.height + 1) % period) !== 0) {
@ -1778,9 +1799,11 @@ Chain.prototype.getState = function getState(prev, block, id, callback) {
return prev.getAncestorByHeight(height, function(err, ancestor) {
if (err)
return callback(err);
if (!ancestor)
return callback(null, constants.thresholdStates.DEFINED);
return self.getState(ancestor, block, callback);
if (ancestor) {
assert(ancestor.height === height);
assert(((ancestor.height + 1) % period) === 0);
}
return self.getState(ancestor, block, id, callback);
});
}
@ -1918,6 +1941,24 @@ Chain.prototype.isSegwitActive = function isSegwitActive(callback) {
var tip = this.tip;
var unlock;
if (!network.witness) {
this.segwitActive = false;
return utils.asyncify(callback)(null, false);
}
if (network.type === 'segnet4') {
return this.tip.getPrevious(function(err, prev) {
if (err)
return callback(err);
return self.getState(prev, null, 'witness', function(err, state) {
if (err)
return callback(err);
return callback(null, state === constants.thresholdStates.ACTIVE);
});
});
}
if (this.segwitActive != null)
return utils.asyncify(callback)(null, this.segwitActive);
@ -1933,6 +1974,11 @@ Chain.prototype.isSegwitActive = function isSegwitActive(callback) {
callback = utils.wrap(callback, unlock);
if (tip.ancestors.length) {
self.segwitActive = tip.isUpgraded(5);
return callback(null, self.segwitActive);
}
tip.ensureAncestors(function(err) {
if (err)
return callback(err);

View File

@ -143,8 +143,12 @@ ChainBlock.prototype.isMainChain = function isMainChain(callback) {
};
ChainBlock.prototype.getAncestorByHeight = function getAncestorByHeight(height, callback) {
if (height < 0)
return utils.nextTick(callback);
assert(height >= 0);
assert(height <= this.height);
return this.getAncestor(this.height - height, function(err, entry) {
if (err)
return callback(err);
@ -164,10 +168,10 @@ ChainBlock.prototype.getAncestor = function getAncestor(index, callback) {
if (err)
return callback(err);
if (ancestors.length !== index + 1)
if (ancestors.length < index + 1)
return callback();
return callback(null, ancestors[ancestors.length - 1]);
return callback(null, ancestors[index]);
});
};

View File

@ -54,7 +54,7 @@ Fullnode.prototype._init = function _init() {
// Pool needs access to the chain.
this.pool = new bcoin.pool(this, {
witness: this.network.type === 'segnet',
witness: this.network.witness,
spv: false
});

View File

@ -202,7 +202,7 @@ exports.block = {
};
exports.tx = {
version: 1,
version: 2,
maxSize: 100000,
minFee: 10000,
bareMultisig: true,
@ -291,11 +291,9 @@ exports.flags = {
VERIFY_DISCOURAGE_UPGRADABLE_NOPS: (1 << 7),
VERIFY_CLEANSTACK: (1 << 8),
VERIFY_CHECKLOCKTIMEVERIFY: (1 << 9),
VERIFY_WITNESS: (1 << 10),
VERIFY_DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM: (1 << 11),
// NOTE: Should be (1 << 10) - but that conflicts with segwit
VERIFY_CHECKSEQUENCEVERIFY: (1 << 12),
VERIFY_CHECKSEQUENCEVERIFY: (1 << 10),
VERIFY_WITNESS: (1 << 11),
VERIFY_DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM: (1 << 12),
VERIFY_SEQUENCE: (1 << 0),
MEDIAN_TIME_PAST: (1 << 1)
};

View File

@ -12,14 +12,14 @@ var utils = require('../utils');
*/
var network = exports;
var main, testnet, regtest, segnet;
var main, testnet, regtest, segnet3, segnet4;
network.set = function set(type) {
var net = network[type];
utils.merge(network, net);
};
network.types = ['main', 'testnet', 'regtest', 'segnet'];
network.types = ['main', 'testnet', 'regtest', 'segnet3', 'segnet4'];
/**
* Main
@ -364,20 +364,20 @@ regtest.deployments = {
regtest.height = -1;
/**
* Segnet
* segnet3
*/
segnet = network.segnet = {};
segnet3 = network.segnet3 = {};
segnet.type = 'segnet';
segnet3.type = 'segnet3';
segnet.prefixes = {
segnet3.prefixes = {
privkey: 158,
xpubkey: 0x053587cf,
xprivkey: 0x05358394
};
segnet.address = {
segnet3.address = {
prefixes: {
pubkeyhash: 30,
scripthash: 50,
@ -390,40 +390,40 @@ segnet.address = {
}
};
segnet.address.prefixesByVal = utils.revMap(segnet.address.prefixes);
segnet.address.versionsByVal = utils.revMap(segnet.address.versions);
segnet3.address.prefixesByVal = utils.revMap(segnet3.address.prefixes);
segnet3.address.versionsByVal = utils.revMap(segnet3.address.versions);
segnet.seeds = [
segnet3.seeds = [
'104.243.38.34',
'104.155.1.158',
'119.246.245.241',
'46.101.235.82'
];
segnet.port = 28333;
segnet3.port = 28333;
segnet.alertKey = new Buffer(''
segnet3.alertKey = new Buffer(''
+ '04302390343f91cc401d56d68b123028bf52e5f'
+ 'ca1939df127f63c6467cdf9c8e2c14b61104cf8'
+ '17d0b780da337893ecc4aaff1309e536162dabb'
+ 'db45200ca2b0a',
'hex');
segnet.checkpoints = [];
segnet3.checkpoints = [];
segnet.checkpoints = segnet.checkpoints.reduce(function(out, block) {
segnet3.checkpoints = segnet3.checkpoints.reduce(function(out, block) {
out[block.height] = utils.revHex(block.hash);
return block;
}, {});
segnet.checkpoints.tsLastCheckpoint = 0;
segnet.checkpoints.txsLastCheckpoint = 0;
segnet.checkpoints.txsPerDay = 300;
segnet.checkpoints.lastHeight = 0;
segnet3.checkpoints.tsLastCheckpoint = 0;
segnet3.checkpoints.txsLastCheckpoint = 0;
segnet3.checkpoints.txsPerDay = 300;
segnet3.checkpoints.lastHeight = 0;
segnet.halvingInterval = 210000;
segnet3.halvingInterval = 210000;
segnet.genesis = {
segnet3.genesis = {
version: 1,
hash: utils.revHex(
'0d5b9c518ddf053fcac71730830df4526a9949c08f34acf6a1d30464d22f02aa'
@ -437,49 +437,99 @@ segnet.genesis = {
nonce: 0
};
segnet.magic = 0xcaea962e;
segnet3.magic = 0xcaea962e;
segnet.powLimit = new bn(
segnet3.powLimit = new bn(
'00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff',
'hex'
);
segnet.powTargetTimespan = 14 * 24 * 60 * 60; // two weeks
segnet.powTargetSpacing = 10 * 60;
segnet.powDiffInterval = segnet.powTargetTimespan / segnet.powTargetSpacing | 0;
segnet.powAllowMinDifficultyBlocks = true;
segnet.powNoRetargeting = false;
segnet3.powTargetTimespan = 14 * 24 * 60 * 60; // two weeks
segnet3.powTargetSpacing = 10 * 60;
segnet3.powDiffInterval = segnet3.powTargetTimespan / segnet3.powTargetSpacing | 0;
segnet3.powAllowMinDifficultyBlocks = true;
segnet3.powNoRetargeting = false;
segnet.block = {
segnet3.block = {
majorityEnforceUpgrade: 7,
majorityRejectOutdated: 9,
majorityWindow: 10,
bip34height: -1
};
segnet.segwitHeight = 0;
segnet3.segwitHeight = 0;
segnet.genesisBlock = '0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a7d719856ffff001d000000000101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff4d04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000';
segnet3.genesisBlock = '0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a7d719856ffff001d000000000101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff4d04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000';
segnet.ruleChangeActivationThreshold = 108;
segnet.minerConfirmationWindow = 144;
segnet.deployments = {};
segnet3.ruleChangeActivationThreshold = 108;
segnet3.minerConfirmationWindow = 144;
segnet3.deployments = {};
segnet.height = -1;
segnet3.height = -1;
segnet3.witness = true;
segnet4 = network.segnet4 = {};
utils.merge(segnet4, segnet3);
segnet4.type = 'segnet4';
segnet4.seeds = [
'37.34.48.17'
];
segnet4.port = 28901;
segnet4.segwitHeight = -1;
segnet4.magic = 0xc4a1abdc;
segnet4.powLimit = new bn(
// 512x lower min difficulty than mainnet
'000001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff',
'hex'
);
segnet4.deployments = utils.merge({}, main.deployments, {
witness: {
bit: 1,
startTime: 0,
timeout: 999999999999
}
// bip109: {
// bit: 28,
// startTime: 1453939200, // Jan 28th, 2016
// timeout: 1514764800 // Jan 1st, 2018
// }
});
segnet4.genesis = {
version: 1,
hash: 'b291211d4bb2b7e1b7a4758225e69e50104091a637213d033295c010f55ffb18',
prevBlock: '0000000000000000000000000000000000000000000000000000000000000000',
merkleRoot: utils.revHex(
'4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b'
),
ts: 1452831101,
bits: 503447551,
nonce: 0
};
segnet4.genesisBlock = '0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a7d719856ffff011e000000000101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff4d04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000';
network.xprivkeys = {
'76066276': 'main',
'70615956': 'testnet',
'87393172': 'segnet',
'87393172': 'segnet3',
'xprv': 'main',
'tprv': 'testnet',
'2791': 'segnet'
'2791': 'segnet3',
'2791': 'segnet4'
};
network.xpubkeys = {
'76067358': 'main',
'70617039': 'testnet',
'87394255': 'segnet',
'87394255': 'segnet3',
'xpub': 'main',
'tpub': 'testnet',
'2793': 'segnet'
'2793': 'segnet3',
'2793': 'segnet4'
};

View File

@ -47,7 +47,7 @@ SPVNode.prototype._init = function _init() {
});
this.pool = new bcoin.pool(this, {
witness: this.network.type === 'segnet',
witness: this.network.witness,
spv: true
});

View File

@ -443,7 +443,7 @@ WalletDB.prototype.create = function create(options, callback) {
}
done();
} else {
if (bcoin.protocol.network.type === 'segnet')
if (bcoin.protocol.network.witness)
options.witness = options.witness !== false;
options.provider = new Provider(self);

View File

@ -1,11 +1,12 @@
var bcoin = require('bcoin');
var constants = bcoin.protocol.constants;
var network = bcoin.protocol.network;
var utils = bcoin.utils;
var bn = bcoin.bn;
var bn = require('bn.js');
function createGenesisBlock(options) {
var parser = bcoin.protocol.parser;
var tx, block;
var tx, block, txRaw, blockRaw;
if (!options.flags) {
options.flags = new Buffer(
@ -14,12 +15,14 @@ function createGenesisBlock(options) {
}
if (!options.script) {
options.script = [
new Buffer('04678afdb0fe5548271967f1a67130b7105cd6a828e039'
+ '09a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c3'
+ '84df7ba0b8d578a4c702b6bf11d5f', 'hex'),
'checksig'
];
options.script = {
code: [
new Buffer('04678afdb0fe5548271967f1a67130b7105cd6a828e039'
+ '09a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c3'
+ '84df7ba0b8d578a4c702b6bf11d5f', 'hex'),
constants.opcodes.OP_CHECKSIG
]
};
}
if (!options.reward)
@ -32,11 +35,13 @@ function createGenesisBlock(options) {
hash: utils.toHex(constants.zeroHash),
index: 0xffffffff
},
script: [
new bn(486604799, 'le').toBuffer(),
new bn(4, 'le').toBuffer(),
options.flags
],
script: {
code: [
new bn(486604799, 'le').toBuffer(),
new bn(4, 'le').toBuffer(),
options.flags
]
},
sequence: 0xffffffff
}],
outputs: [{
@ -46,29 +51,33 @@ function createGenesisBlock(options) {
locktime: 0
};
tx._raw = bcoin.protocol.framer.tx(tx);
txRaw = bcoin.protocol.framer.tx(tx);
tx._raw = txRaw;
tx._size = txRaw.length;
tx._witnessSize = 0;
block = {
version: options.version,
prevBlock: utils.toHex(constants.zeroHash),
merkleRoot: utils.toHex(utils.dsha256(tx._raw)),
merkleRoot: utils.toHex(utils.dsha256(txRaw)),
ts: options.ts,
bits: options.bits,
nonce: options.nonce,
txs: [tx]
};
block._raw = bcoin.protocol.framer.block(block);
blockRaw = bcoin.protocol.framer.block(block);
block = parser.parseBlock(block._raw);
block = parser.parseBlock(blockRaw);
block._hash = utils.dsha256(block._raw.slice(0, 80));
block._hash = utils.dsha256(blockRaw.slice(0, 80));
block.hash = utils.toHex(block._hash);
block.network = true;
block._raw = blockRaw;
block._size = blockRaw.length;
block._witnessSize = 0;
block.height = 0;
tx = block.txs[0];
tx.network = true;
tx.height = 0;
tx.ts = block.ts;
tx._hash = block.merkleRoot;
@ -98,7 +107,7 @@ var regtest = createGenesisBlock({
nonce: 2
});
var segnet = createGenesisBlock({
var segnet3 = createGenesisBlock({
version: 1,
// ts: 1452368293,
ts: 1452831101,
@ -106,10 +115,17 @@ var segnet = createGenesisBlock({
nonce: 0
});
var segnet4 = createGenesisBlock({
version: 1,
ts: 1452831101,
bits: utils.toCompact(network.segnet4.powLimit),
nonce: 0
});
utils.print(main);
utils.print(testnet);
utils.print(regtest);
utils.print(segnet);
utils.print(segnet3);
utils.print('main hash: %s', utils.revHex(main.hash));
utils.print('main raw: %s', utils.toHex(main._raw));
utils.print('');
@ -118,5 +134,8 @@ utils.print('testnet raw: %s', utils.toHex(testnet._raw));
utils.print('');
utils.print('regtest hash: %s', utils.revHex(regtest.hash));
utils.print('regtest raw: %s', utils.toHex(regtest._raw));
utils.print('segnet hash: %s', utils.revHex(segnet.hash));
utils.print('segnet raw: %s', utils.toHex(segnet._raw));
utils.print('segnet3 hash: %s', utils.revHex(segnet3.hash));
utils.print('segnet3 raw: %s', utils.toHex(segnet3._raw));
utils.print('segnet4 hash: %s', utils.revHex(segnet4.hash));
utils.print('segnet4 raw: %s', utils.toHex(segnet4._raw));
utils.print(segnet4);