more accurate segwit4 verification. misc.

This commit is contained in:
Christopher Jeffrey 2016-04-07 02:03:38 -07:00
parent 0a7f118528
commit a3720bd42d
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD
8 changed files with 102 additions and 63 deletions

View File

@ -1,6 +1,6 @@
#!/usr/bin/env node
var bcoin = require('bcoin')({ debug: true });
var bcoin = require('bcoin')({ debug: true, debugFile: true });
var utils = bcoin.utils;
var assert = utils.assert;

View File

@ -1,6 +1,6 @@
#!/usr/bin/env node
var bcoin = require('bcoin')({ debug: true });
var bcoin = require('bcoin')({ debug: true, debugFile: true });
var utils = bcoin.utils;
var assert = utils.assert;

View File

@ -148,9 +148,8 @@ Block.prototype.getMerkleRoot = function getMerkleRoot(enc) {
Block.prototype.getCommitmentHash = function getCommitmentHash(enc) {
var leaves = [];
var i, witnessNonce, witnessRoot, commitmentHash;
witnessNonce = this.txs[0].inputs[0].witness.items[0];
var witnessNonce = this.witnessNonce;
var i, witnessRoot, commitmentHash;
if (!witnessNonce)
return;
@ -170,6 +169,24 @@ Block.prototype.getCommitmentHash = function getCommitmentHash(enc) {
: commitmentHash;
};
Block.prototype.__defineGetter__('witnessNonce', function() {
var coinbase = this.txs[0];
if (!coinbase)
return;
if (coinbase.inputs.length !== 1)
return;
if (coinbase.inputs[0].witness.items.length !== 1)
return;
if (coinbase.inputs[0].witness.items[0].length !== 32)
return;
return coinbase.inputs[0].witness.items[0];
});
Block.prototype.__defineGetter__('commitmentHash', function() {
var coinbase, i, commitment, commitmentHash;
@ -178,6 +195,9 @@ Block.prototype.__defineGetter__('commitmentHash', function() {
coinbase = this.txs[0];
if (!coinbase)
return;
for (i = 0; i < coinbase.outputs.length; i++) {
commitment = coinbase.outputs[i].script;
if (commitment.isCommitment()) {
@ -211,7 +231,7 @@ Block.prototype._verify = function _verify(ret) {
}
// First TX must be a coinbase
if (!this.txs.length || !this.txs[0].isCoinbase()) {
if (this.txs.length === 0 || !this.txs[0].isCoinbase()) {
ret.reason = 'bad-cb-missing';
ret.score = 100;
return false;

View File

@ -405,7 +405,7 @@ Chain.prototype._verify = function _verify(block, prev, callback) {
var flags = constants.flags.MANDATORY_VERIFY_FLAGS;
var lockFlags = constants.flags.MANDATORY_LOCKTIME_FLAGS;
var height, ts, i, tx, coinbaseHeight;
var medianTime, segwit;
var medianTime, segwit, commitmentHash;
var ret = {};
function done(err, result) {
@ -492,12 +492,14 @@ Chain.prototype._verify = function _verify(block, prev, callback) {
// Segregrated witness is now usable
if (network.type === 'segnet3' && height >= network.segwitHeight) {
if (block.version >= 5 && prev.isUpgraded(5)) {
flags |= constants.flags.VERIFY_WITNESS;
segwit = true;
self.segwitActive = true;
} else if (block.version >= 5) {
self.segwitActive = false;
if (block.version >= 5) {
if (prev.isUpgraded(5)) {
flags |= constants.flags.VERIFY_WITNESS;
segwit = true;
self.segwitActive = true;
} else {
self.segwitActive = false;
}
}
}
@ -536,13 +538,24 @@ Chain.prototype._verify = function _verify(block, prev, callback) {
}
if (segwit) {
if (block.commitmentHash !== block.getCommitmentHash('hex')) {
return done(new VerifyError(block,
'invalid',
'bad-blk-wit-length',
100));
commitmentHash = block.commitmentHash;
if (commitmentHash) {
if (!block.witnessNonce) {
return done(new VerifyError(block,
'invalid',
'bad-witness-merkle-size',
100));
}
if (commitmentHash !== block.getCommitmentHash('hex')) {
return done(new VerifyError(block,
'invalid',
'bad-witness-merkle-match',
100));
}
}
} else {
}
if (!commitmentHash) {
if (block.hasWitness()) {
return done(new VerifyError(block,
'invalid',

View File

@ -31,6 +31,9 @@ function Environment(options) {
this.options = options;
this._ensured = false;
this._debug = null;
this.isBrowser =
(typeof process !== 'undefined' && process.browser)
|| typeof window !== 'undefined';
@ -46,9 +49,6 @@ function Environment(options) {
this.debugFile = options.debugFile;
if (options.debugFile == null)
this.debugFile = true;
if (process.env.BCOIN_DEBUGFILE != null) {
if (process.env.BCOIN_DEBUGFILE === '0'
|| process.env.BCOIN_DEBUGFILE === '1') {
@ -66,11 +66,6 @@ function Environment(options) {
if (process.env.BCOIN_PROFILE != null)
this.profile = +process.env.BCOIN_PROFILE === 1;
this.fresh = options.fresh;
if (process.env.BCOIN_FRESH != null)
this.fresh = +process.env.BCOIN_FRESH === 1;
this.useWorkers = options.useWorkers;
if (process.env.BCOIN_USE_WORKERS != null)
@ -127,13 +122,13 @@ function Environment(options) {
this.chain = require('./chain')(this);
this.mempool = require('./mempool')(this);
this.keypair = require('./keypair')(this);
this.hd = require('./hd')(this);
this.address = require('./address')(this);
this.wallet = require('./wallet')(this);
this.walletdb = require('./walletdb')(this);
this.provider = this.walletdb.provider;
this.wallet = require('./wallet')(this);
this.peer = require('./peer')(this);
this.pool = require('./pool')(this);
this.hd = require('./hd')(this);
this.miner = require('./miner')(this);
this.minerblock = this.miner.minerblock;
this.http = require('./http')(this);
@ -151,9 +146,6 @@ Environment.prototype.ensurePrefix = function ensurePrefix() {
this._ensured = true;
if (this.fresh && this.prefix.indexOf('bcoin') !== -1)
this.rimraf(this.prefix);
try {
fs.statSync(this.prefix);
} catch (e) {
@ -161,31 +153,26 @@ Environment.prototype.ensurePrefix = function ensurePrefix() {
}
};
Environment.prototype.rimraf = function rimraf(file) {
var cp;
if (this.isBrowser)
return;
cp = require('child_' + 'process');
assert(typeof file === 'string');
assert(file !== '/');
assert(file !== process.env.HOME);
cp.execFileSync('rm', ['-rf', file], { stdio: 'ignore' });
};
Environment.prototype.debug = function debug() {
var args = Array.prototype.slice.call(arguments);
var msg;
if (this.isBrowser) {
if (this.debugLogs) {
msg = typeof args[0] === 'object'
? args[0]
: utils.format(args, false).slice(0, -1);
console.error(msg);
}
return;
}
if (this.debugLogs) {
msg = utils.format(args, true);
process.stderr.write(msg);
}
if (this.debugFile && !this.isBrowser) {
if (this.debugFile) {
if (!this._debug) {
this.ensurePrefix();
this._debug = fs.createWriteStream(this.debugFile, { flags: 'a' });

View File

@ -44,6 +44,7 @@ function Miner(options) {
this.running = false;
this.timeout = null;
this.loaded = false;
this.block = null;
@ -53,7 +54,10 @@ function Miner(options) {
utils.inherits(Miner, EventEmitter);
Miner.prototype.open = function open(callback) {
return utils.nextTick(callback);
if (this.loaded)
return utils.nextTick(callback);
return this.once('open', callback);
};
Miner.prototype.close =
@ -105,6 +109,13 @@ Miner.prototype._init = function _init() {
stat.height,
stat.best);
});
this.chain.open(function(err) {
if (err)
return self.emit('error', err);
self.loaded = true;
self.emit('open');
});
};
Miner.prototype.start = function start() {
@ -263,7 +274,7 @@ function MinerBlock(options) {
this.coinbase.addInput({
prevout: {
hash: utils.toHex(constants.zeroHash),
hash: constants.nullHash,
index: 0xffffffff
},
coin: null,
@ -283,7 +294,7 @@ function MinerBlock(options) {
// miner succeeded.
new Buffer(options.coinbaseFlags, 'ascii')
]),
witness: new bcoin.script.witness([]),
witness: new bcoin.script.witness(),
sequence: 0xffffffff
});
@ -296,10 +307,11 @@ function MinerBlock(options) {
this.block = new bcoin.block({
version: options.version,
prevBlock: this.tip.hash,
merkleRoot: constants.zeroHash,
merkleRoot: constants.nullHash,
ts: Math.max(utils.now(), this.tip.ts + 1),
bits: options.target,
nonce: 0
nonce: 0,
height: this.height
});
this.block.txs.push(this.coinbase);
@ -311,7 +323,7 @@ function MinerBlock(options) {
this.witnessNonce = utils.dsha256(new Buffer(this.tip.hash, 'hex'));
this.coinbase.inputs[0].witness.items[0] = this.witnessNonce;
this.coinbase.addOutput({
script: new bcoin.script([]),
script: new bcoin.script(),
value: new bn(0)
});
}
@ -478,8 +490,10 @@ MinerBlock.prototype.mineAsync = function mine(callback) {
};
MinerBlock.prototype.destroy = function destroy() {
clearTimeout(this.timeout);
this.timeout = null;
if (this.timeout) {
clearTimeout(this.timeout);
this.timeout = null;
}
this.block = null;
};

View File

@ -18,12 +18,6 @@ if (bcoin.profile && !bcoin.isBrowser) {
fs = require('f' + 's');
}
if (profiler) {
utils.nextTick(function() {
bcoin.debug('Starting node with profiler enabled.');
});
}
/**
* Profile
*/

View File

@ -708,7 +708,18 @@ utils.format = function format(args, color) {
utils.print = function print() {
var args = Array.prototype.slice.call(arguments);
return process.stdout.write(utils.format(args, true));
var msg;
if (utils.isBrowser) {
msg = typeof args[0] === 'object'
? args[0]
: utils.format(args, false).slice(0, -1);
console.log(msg);
return;
}
msg = utils.format(args, true);
process.stdout.write(msg);
};
utils.merge = function merge(target) {