refactor addInput.

This commit is contained in:
Christopher Jeffrey 2016-02-24 03:39:10 -08:00
parent 466429dbe2
commit 6ad3540664
5 changed files with 40 additions and 121 deletions

View File

@ -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);

View File

@ -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');

View File

@ -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 {

View File

@ -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) {

View File

@ -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());
});