From 6062f1ce944912f928cba0984378ea88ebeb6a13 Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Mon, 4 Apr 2016 16:39:02 -0700 Subject: [PATCH] more refactoring. --- lib/bcoin/hd.js | 2 +- lib/bcoin/mtx.js | 17 ++++---- lib/bcoin/script.js | 2 +- lib/bcoin/tx.js | 96 ++++++++++++++++++++++++++------------------- 4 files changed, 64 insertions(+), 53 deletions(-) diff --git a/lib/bcoin/hd.js b/lib/bcoin/hd.js index bc642fde..3f9cecb2 100644 --- a/lib/bcoin/hd.js +++ b/lib/bcoin/hd.js @@ -416,7 +416,7 @@ HDPrivateKey.prototype.derivePath = function derivePath(path) { var indexes; if (!HDPrivateKey.isValidPath(path)) - throw new Error('invalid path'); + throw new Error('Invalid path.'); indexes = HDPrivateKey._getIndexes(path); diff --git a/lib/bcoin/mtx.js b/lib/bcoin/mtx.js index c7eef3e6..05e627c6 100644 --- a/lib/bcoin/mtx.js +++ b/lib/bcoin/mtx.js @@ -20,14 +20,14 @@ var opcodes = constants.opcodes; */ function MTX(options) { + var i; + if (!(this instanceof MTX)) return new MTX(options); if (!options) options = {}; - this.options = options; - this.type = 'tx'; this.version = options.version || 1; this.inputs = []; @@ -38,6 +38,7 @@ function MTX(options) { this.index = -1; this.ps = this.ts === 0 ? utils.now() : 0; this.changeIndex = options.changeIndex != null ? options.changeIndex : -1; + this.height = -1; this._hash = null; this._whash = null; @@ -45,18 +46,14 @@ function MTX(options) { this._size = 0; this._witnessSize = 0; - this.height = -1; - if (options.inputs) { - options.inputs.forEach(function(input) { - this.addInput(input); - }, this); + for (i = 0; i < options.inputs.length; i++) + this.addInput(options.inputs[i]); } if (options.outputs) { - options.outputs.forEach(function(output) { - this.addOutput(output); - }, this); + for (i = 0; i < options.outputs.length; i++) + this.addOutput(options.outputs[i]); } } diff --git a/lib/bcoin/script.js b/lib/bcoin/script.js index ceef0323..1cb28a26 100644 --- a/lib/bcoin/script.js +++ b/lib/bcoin/script.js @@ -32,7 +32,7 @@ function Witness(items) { if (items.items) items = items.items; - this.items = items || []; + this.items = items; this.redeem = null; } diff --git a/lib/bcoin/tx.js b/lib/bcoin/tx.js index 9caff496..18eb28e6 100644 --- a/lib/bcoin/tx.js +++ b/lib/bcoin/tx.js @@ -21,6 +21,8 @@ var BufferWriter = require('./writer'); */ function TX(data, block, index) { + var i; + if (!(this instanceof TX)) return new TX(data, block, index); @@ -37,6 +39,7 @@ function TX(data, block, index) { this.block = data.block || null; this.index = data.index != null ? data.index : -1; this.ps = this.ts === 0 ? utils.now() : 0; + this.height = data.height != null ? data.height : -1; this._hash = null; this._whash = null; @@ -44,18 +47,15 @@ function TX(data, block, index) { this._size = data._size || 0; this._witnessSize = data._witnessSize || 0; - this.height = data.height != null ? data.height : -1; + if (data.inputs) { + for (i = 0; i < data.inputs.length; i++) + this.inputs.push(new bcoin.input(data.inputs[i], this)); + } - // assert(data.inputs.length !== 0); - // assert(data.outputs.length !== 0); - - data.inputs.forEach(function(input) { - this.inputs.push(new bcoin.input(input, this)); - }, this); - - data.outputs.forEach(function(output) { - this.outputs.push(new bcoin.output(output, this)); - }, this); + if (data.outputs) { + for (i = 0; i < data.outputs.length; i++) + this.outputs.push(new bcoin.output(data.outputs[i], this)); + } if (block && this.ts === 0) { if (block.type === 'merkleblock') { @@ -385,6 +385,8 @@ TX.prototype.signatureHashV1 = function signatureHashV1(index, prev, type) { }; TX.prototype.verify = function verify(index, force, flags) { + var i, input, res; + // Valid if included in block if (!force && this.ts !== 0) return true; @@ -401,16 +403,18 @@ TX.prototype.verify = function verify(index, force, flags) { if (this.isCoinbase()) return true; - return this.inputs.every(function(input, i) { + for (i = 0; i < this.inputs.length; i++) { + input = this.inputs[i]; + if (index != null && i !== index) - return true; + continue; if (!input.coin) { - utils.debug('Warning: Not all outputs available for tx.verify().'); + utils.debug('Warning: Not all coins are available for tx.verify().'); return false; } - return Script.verify( + res = Script.verify( input.script, input.witness, input.coin.script, @@ -418,13 +422,19 @@ TX.prototype.verify = function verify(index, force, flags) { i, flags ); - }, this); + + if (!res) + return false; + } + + return true; }; TX.prototype.verifyAsync = function verifyAsync(index, force, flags, callback) { var self = this; + var res; + utils.nextTick(function() { - var res; try { res = self.verify(index, force, flags); } catch (e) { @@ -642,12 +652,13 @@ TX.prototype.isFinal = function isFinal(height, ts) { TX.prototype._getSigops = function _getSigops(scriptHash, accurate) { var total = 0; + var i, input, output, prev; - this.inputs.forEach(function(input) { - var prev; + for (i = 0; i < this.inputs.length; i++) { + input = this.inputs[i]; if (!input.coin) - return; + continue; prev = input.coin.script; @@ -655,35 +666,37 @@ TX.prototype._getSigops = function _getSigops(scriptHash, accurate) { if (scriptHash && !this.isCoinbase()) { if (!prev.isScripthash()) - return; + continue; if (!input.script.isPushOnly()) - return; + continue; prev = input.script.getRedeem(); if (!prev) - return; + continue; total += prev.getSigops(true); } - }, this); + } - this.outputs.forEach(function(output) { + for (i = 0; i < this.outputs.length; i++) { + output = this.outputs[i]; total += output.script.getSigops(accurate); - }, this); + } return total; }; TX.prototype.getSigops = function getSigops(scriptHash, accurate) { var cost = this._getSigops(scriptHash, accurate) * 4; + var i, input, output, prev; - this.inputs.forEach(function(input) { - var prev; + for (i = 0; i < this.inputs.length; i++) { + input = this.inputs[i]; if (!input.coin) - return; + continue; prev = input.coin.script; @@ -694,17 +707,14 @@ TX.prototype.getSigops = function getSigops(scriptHash, accurate) { prev = input.witness.getRedeem(); if (prev) cost += prev.getSigops(true); - } else { - cost += 0; } - }, this); + } - this.outputs.forEach(function(output) { + for (i = 0; i < this.outputs.length; i++) { + output = this.outputs[i]; if (output.script.isWitnessPubkeyhash()) cost += 1; - else - cost += 0; - }, this); + } return (cost + 3) / 4 | 0; }; @@ -871,6 +881,7 @@ TX.prototype.isStandard = function isStandard(flags, ret) { // AreInputsStandard TX.prototype.hasStandardInputs = function hasStandardInputs(flags) { var maxSigops = constants.script.maxScripthashSigops; + var VERIFY_NONE = constants.flags.VERIFY_NONE; var i, input, stack, res, redeem; if (flags == null) @@ -896,9 +907,9 @@ TX.prototype.hasStandardInputs = function hasStandardInputs(flags) { if (!input.script.isPushOnly()) return false; - stack = new Stack([]); + stack = new Stack(); - res = input.script.execute(stack, constants.flags.VERIFY_NONE, this, i, 0); + res = input.script.execute(stack, VERIFY_NONE, this, i, 0); if (!res) return false; @@ -1291,6 +1302,7 @@ TX.prototype.toExtended = function toExtended(saveCoins) { var index = this.index; var changeIndex = this.changeIndex != null ? this.changeIndex : -1; var p = new BufferWriter(); + var i, input; if (height === -1) height = 0x7fffffff; @@ -1311,14 +1323,16 @@ TX.prototype.toExtended = function toExtended(saveCoins) { if (saveCoins) { p.writeVarint(this.inputs.length); - this.inputs.forEach(function(input) { + for (i = 0; i < this.inputs.length; i++) { + input = this.inputs[i]; + if (!input.coin) { p.writeVarint(0); - return; + continue; } p.writeVarBytes(bcoin.protocol.framer.coin(input.coin, false)); - }); + } } return p.render();