diff --git a/lib/bcoin/chain.js b/lib/bcoin/chain.js index db124fa3..0ad8be6f 100644 --- a/lib/bcoin/chain.js +++ b/lib/bcoin/chain.js @@ -644,7 +644,7 @@ Chain.prototype._checkInputs = function _checkInputs(block, prev, flags, callbac if (!input.output) { utils.debug('Block is using spent inputs: %s (tx: %s, output: %s)', block.rhash, tx.rhash, - input.prevout.rhash + '/' + input.prevout.index); + utils.revHex(input.prevout.hash) + '/' + input.prevout.index); if (height < network.checkpoints.lastHeight) throw new Error('BUG: Spent inputs in historical data!'); return callback(null, false); diff --git a/lib/bcoin/coin.js b/lib/bcoin/coin.js index d5323172..e5064980 100644 --- a/lib/bcoin/coin.js +++ b/lib/bcoin/coin.js @@ -55,8 +55,6 @@ function Coin(tx, index) { if (Buffer.isBuffer(this.hash)) this.hash = utils.toHex(this.hash); - this.rhash = utils.revHex(this.hash); - // Object.freeze(this); assert(typeof this.version === 'number'); diff --git a/lib/bcoin/input.js b/lib/bcoin/input.js index 0fcafaac..1cdb4631 100644 --- a/lib/bcoin/input.js +++ b/lib/bcoin/input.js @@ -26,8 +26,7 @@ function Input(options) { this.prevout = { hash: prevout.hash, - index: prevout.index, - rhash: prevout.rhash + index: prevout.index }; if (options.output) @@ -36,39 +35,15 @@ function Input(options) { if (Buffer.isBuffer(this.prevout.hash)) this.prevout.hash = utils.toHex(this.prevout.hash); - if (!this.prevout.rhash) - this.prevout.rhash = utils.revHex(this.prevout.hash); - this.script = options.script ? options.script.slice() : []; this.sequence = options.sequence == null ? 0xffffffff : options.sequence; this._size = options._size || 0; this._offset = options._offset || 0; - // Legacy - if (options.seq != null) - this.sequence = options.seq; - if (options.script && options.script._raw) utils.hidden(this.script, '_raw', options.script._raw); } -// Legacy -Input.prototype.__defineSetter__('seq', function(sequence) { - return this.sequence = sequence; -}); - -Input.prototype.__defineGetter__('seq', function() { - return this.sequence; -}); - -Input.prototype.__defineSetter__('out', function(prevout) { - return this.prevout = prevout; -}); - -Input.prototype.__defineGetter__('out', function() { - return this.prevout; -}); - Input.prototype.__defineGetter__('data', function() { var data; @@ -345,7 +320,7 @@ Input.prototype.inspect = function inspect() { : { type: 'unknown', value: '0.0' }; output.hash = this.prevout.hash; - output.rhash = this.prevout.rhash; + output.rhash = utils.revHex(this.prevout.hash); output.index = this.prevout.index; return { diff --git a/lib/bcoin/tx.js b/lib/bcoin/tx.js index 8c2c8c4c..0ae5d883 100644 --- a/lib/bcoin/tx.js +++ b/lib/bcoin/tx.js @@ -137,96 +137,36 @@ TX.prototype.getSize = function getSize() { TX.prototype.size = TX.prototype.getSize; -TX.prototype.addInput = function addInput(i, index) { - this._addInput(i, index); +TX.prototype.addInput = function _addInput(options, index) { + var input, i; + + if (options instanceof TX) + options = bcoin.coin(options, index); + + if (options instanceof bcoin.coin) { + options = { + prevout: { hash: options.hash, index: options.index }, + output: options + }; + } + + assert(options.prevout); + + // i = this._inputIndex(options.prevout.hash, options.prevout.index); + // assert(i === -1); + + input = bcoin.input(options); + + this.inputs.push(input); + return this; }; TX.prototype.input = TX.prototype.addInput; -// tx._addInput(tx, index) -// tx._addInput(hash, index) -// tx._addInput(input) -// tx._addInput({ hash: hash, index: index }) -// tx._addInput({ tx: tx, index: index }) -TX.prototype._addInput = function _addInput(options, index) { - var coin, input, ex, i, prevout, isInput; - - if (options instanceof TX) { - options = { tx: options, index: index }; - } else if (typeof options === 'string' || Buffer.isBuffer(options)) { - options = { hash: options, index: index }; - } - - if (options.out) - options.prevout = options.out; - - if (options.seq != null) - options.sequence = options.seq; - - if (!options.prevout) { - if (options instanceof bcoin.coin) { - options = { - prevout: { hash: options.hash, index: options.index }, - output: options - }; - } else if (options.tx) { - coin = bcoin.coin(options.tx, options.index); - options = { - prevout: { hash: options.tx.hash('hex'), index: options.index }, - output: coin, - script: options.script, - sequence: options.sequence - }; - } else if (options.hash) { - options = { - prevout: { hash: options.hash, index: options.index }, - output: options.output, - script: options.script, - sequence: options.sequence - }; - } - } else { - isInput = true; - } - - input = bcoin.input({ - tx: this, - prevout: { - hash: options.prevout.hash, - index: options.prevout.index - }, - output: options.output, - script: options.script, - sequence: options.sequence, - _size: isInput ? options._size : null, - _offset: isInput ? options._offset : null - }); - - // Try modifying existing input first - i = this._inputIndex(input.prevout.hash, input.prevout.index); - if (i !== -1) { - ex = this.inputs[i]; - input.output = input.output || ex.output; - input.sequence = input.sequence != null ? input.sequence : ex.sequence; - input.script = input.script.length ? input.script : ex.script; - this.inputs[i] = input; - } else { - this.inputs.push(input); - i = this.inputs.length - 1; - } - - return i; -}; - -TX.prototype._input = TX.prototype._addInput; - TX.prototype._inputIndex = function _inputIndex(hash, index) { var i, ex; - if (hash instanceof TX) - hash = hash.hash('hex'); - for (i = 0; i < this.inputs.length; i++) { ex = this.inputs[i]; if (ex.prevout.hash === hash && ex.prevout.index === index) @@ -934,7 +874,7 @@ TX.prototype.maxSize = function maxSize(maxM, maxN) { for (i = 0; i < copy.inputs.length; i++) copy.inputs[i].script = []; - total = copy.render().length; + total = copy.render(true).length; // Add size for signatures and public keys for (i = 0; i < copy.inputs.length; i++) { @@ -1025,7 +965,7 @@ TX.prototype.getInputs = function getInputs(unspent, options) { var tx = this.clone(); var outputValue = tx.getOutputValue(); var totalkb = 1; - var inputs = []; + var chosen = []; var lastAdded = 0; var minFee = constants.tx.minFee; var dustThreshold = constants.tx.dustThreshold; @@ -1068,8 +1008,8 @@ TX.prototype.getInputs = function getInputs(unspent, options) { // Add new inputs until TX will have enough // funds to cover both minimum post cost // and fee. - index = tx._addInput(unspent[i]); - inputs.push(new bcoin.input(tx.inputs[index])); + tx.addInput(unspent[i]); + chosen.push(unspent[i]); lastAdded++; if (options.wallet) @@ -1125,7 +1065,7 @@ TX.prototype.getInputs = function getInputs(unspent, options) { if (!isFull()) { // Still failing to get enough funds. - inputs = null; + chosen = null; } else { // How much money is left after filling outputs. change = tx.getInputValue().sub(total()); @@ -1140,13 +1080,13 @@ TX.prototype.getInputs = function getInputs(unspent, options) { } // Could not subtract fee if (i === tx.outputs.length) - inputs = null; + chosen = null; } } // Return necessary inputs and change. return { - inputs: inputs, + inputs: chosen, change: change, fee: fee, total: total(), @@ -1459,7 +1399,13 @@ TX.prototype.hasPrevout = function hasPrevout() { TX.prototype.fillPrevout = function fillPrevout(txs, unspent) { var inputs; - if (txs instanceof bcoin.txpool) { + if (txs instanceof TX) { + txs = [txs]; + unspent = null; + } else if (txs instanceof bcoin.coin) { + unspent = [tx]; + txs = null; + } else if (txs instanceof bcoin.txpool) { unspent = txs._unspent; txs = txs._all; } else if (txs instanceof bcoin.wallet) { diff --git a/test/tx-test.js b/test/tx-test.js index c2cfb58a..501b920e 100644 --- a/test/tx-test.js +++ b/test/tx-test.js @@ -49,7 +49,7 @@ describe('TX', function() { it('should be verifiable', function() { var tx = bcoin.tx(parser.parseTX(new Buffer(raw, 'hex'))); var p = bcoin.tx(parser.parseTX(new Buffer(inp, 'hex'))); - tx.input(p, 1); + tx.fillPrevout(p); assert(tx.verify()); });