more accurate segwit4 verification. misc.
This commit is contained in:
parent
0a7f118528
commit
a3720bd42d
2
bin/node
2
bin/node
@ -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;
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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',
|
||||
|
||||
@ -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' });
|
||||
|
||||
@ -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;
|
||||
};
|
||||
|
||||
|
||||
@ -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
|
||||
*/
|
||||
|
||||
@ -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) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user