Merge pull request #949 from eordano/fix/multipleTxin
When creating a Transaction, don't allow the user to repeat an utxo
This commit is contained in:
commit
eeb94ee727
|
@ -337,6 +337,13 @@ Transaction.prototype.from = function(utxo, pubkeys, threshold) {
|
||||||
});
|
});
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
var exists = _.any(this.inputs, function(input) {
|
||||||
|
// TODO: Maybe prevTxId should be a string? Or defined as read only property?
|
||||||
|
return input.prevTxId.toString('hex') === utxo.txId && input.outputIndex === utxo.outputIndex;
|
||||||
|
});
|
||||||
|
if (exists) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (pubkeys && threshold) {
|
if (pubkeys && threshold) {
|
||||||
this._fromMultisigUtxo(utxo, pubkeys, threshold);
|
this._fromMultisigUtxo(utxo, pubkeys, threshold);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -120,6 +120,40 @@ describe('Transaction', function() {
|
||||||
var changeAddressP2SH = '2N7T3TAetJrSCruQ39aNrJvYLhG1LJosujf';
|
var changeAddressP2SH = '2N7T3TAetJrSCruQ39aNrJvYLhG1LJosujf';
|
||||||
var privateKey = 'cSBnVM4xvxarwGQuAfQFwqDg9k5tErHUHzgWsEfD4zdwUasvqRVY';
|
var privateKey = 'cSBnVM4xvxarwGQuAfQFwqDg9k5tErHUHzgWsEfD4zdwUasvqRVY';
|
||||||
|
|
||||||
|
var simpleUtxoWith1BTC = {
|
||||||
|
address: fromAddress,
|
||||||
|
txId: 'a477af6b2667c29670467e4e0728b685ee07b240235771862318e29ddbe58458',
|
||||||
|
outputIndex: 0,
|
||||||
|
script: Script.buildPublicKeyHashOut(fromAddress).toString(),
|
||||||
|
satoshis: 1e8
|
||||||
|
};
|
||||||
|
|
||||||
|
describe('adding inputs', function() {
|
||||||
|
|
||||||
|
it('it only adds once one utxo', function() {
|
||||||
|
var tx = new Transaction();
|
||||||
|
tx.from(simpleUtxoWith1BTC);
|
||||||
|
tx.from(simpleUtxoWith1BTC);
|
||||||
|
tx.inputs.length.should.equal(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('not enough information errors', function() {
|
||||||
|
it('fails when Inputs are not subclassed and isFullySigned is called', function() {
|
||||||
|
var tx = new Transaction(tx_1_hex);
|
||||||
|
expect(function() {
|
||||||
|
return tx.isFullySigned();
|
||||||
|
}).to.throw(errors.Transaction.UnableToVerifySignature);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('fails when Inputs are not subclassed and verifySignature is called', function() {
|
||||||
|
var tx = new Transaction(tx_1_hex);
|
||||||
|
expect(function() {
|
||||||
|
return tx.isValidSignature({inputIndex: 0});
|
||||||
|
}).to.throw(errors.Transaction.UnableToVerifySignature);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('change address', function() {
|
describe('change address', function() {
|
||||||
it('can calculate simply the output amount', function() {
|
it('can calculate simply the output amount', function() {
|
||||||
var transaction = new Transaction()
|
var transaction = new Transaction()
|
||||||
|
@ -190,30 +224,6 @@ describe('Transaction', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
var simpleUtxoWith1BTC = {
|
|
||||||
address: fromAddress,
|
|
||||||
txId: 'a477af6b2667c29670467e4e0728b685ee07b240235771862318e29ddbe58458',
|
|
||||||
outputIndex: 0,
|
|
||||||
script: Script.buildPublicKeyHashOut(fromAddress).toString(),
|
|
||||||
satoshis: 1e8
|
|
||||||
};
|
|
||||||
|
|
||||||
describe('not enough information errors', function() {
|
|
||||||
it('fails when Inputs are not subclassed and isFullySigned is called', function() {
|
|
||||||
var tx = new Transaction(tx_1_hex);
|
|
||||||
expect(function() {
|
|
||||||
return tx.isFullySigned();
|
|
||||||
}).to.throw(errors.Transaction.UnableToVerifySignature);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('fails when Inputs are not subclassed and verifySignature is called', function() {
|
|
||||||
var tx = new Transaction(tx_1_hex);
|
|
||||||
expect(function() {
|
|
||||||
return tx.isValidSignature({inputIndex: 0});
|
|
||||||
}).to.throw(errors.Transaction.UnableToVerifySignature);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('serialization', function() {
|
describe('serialization', function() {
|
||||||
it('stores the change address correctly', function() {
|
it('stores the change address correctly', function() {
|
||||||
var serialized = new Transaction()
|
var serialized = new Transaction()
|
||||||
|
|
Loading…
Reference in New Issue