add excludeUnconfirmedUtxos arg to txp creation

This commit is contained in:
Ivan Socolsky 2015-07-20 19:40:50 -03:00
parent 38868319b9
commit 1603c200b6
3 changed files with 42 additions and 6 deletions

View File

@ -68,6 +68,7 @@ TxProposal.create = function(opts) {
x.actions = [];
x.fee = null;
x.feePerKb = opts.feePerKb;
x.excludeUnconfirmedUtxos = opts.excludeUnconfirmedUtxos;
if (_.isFunction(TxProposal._create[x.type])) {
TxProposal._create[x.type](x, opts);
@ -110,6 +111,7 @@ TxProposal.fromObj = function(obj) {
x.fee = obj.fee;
x.network = obj.network;
x.feePerKb = obj.feePerKb;
x.excludeUnconfirmedUtxos = obj.excludeUnconfirmedUtxos;
return x;
};

View File

@ -858,16 +858,28 @@ WalletService.prototype._selectTxInputs = function(txp, cb) {
self.getUtxos(function(err, utxos) {
if (err) return cb(err);
var balance = self._totalizeUtxos(utxos);
var totalAmount;
var availableAmount;
if (balance.totalAmount < txp.getTotalAmount())
var balance = self._totalizeUtxos(utxos);
if (txp.excludeUnconfirmedUtxos) {
totalAmount = balance.totalConfirmedAmount;
availableAmount = balance.totalConfirmedAvailable;
} else {
totalAmount = balance.totalAmount;
availableAmount = balance.availableAmount;
}
if (totalAmount < txp.getTotalAmount())
return cb(new ClientError('INSUFFICIENTFUNDS', 'Insufficient funds'));
if (balance.availableAmount < txp.amount)
if (availableAmount < txp.amount)
return cb(new ClientError('LOCKEDFUNDS', 'Funds are locked by pending transaction proposals'));
utxos = _.reject(utxos, {
locked: true
});
// Prepare UTXOs list
utxos = _.reject(utxos, 'locked');
if (txp.excludeUnconfirmedUtxos) {
utxos = _.filter(utxos, 'confirmations');
}
var i = 0;
var total = 0;
@ -952,6 +964,7 @@ WalletService.prototype._canCreateTx = function(copayerId, cb) {
* @param {string} opts.proposalSignature - S(toAddress|amount|message|payProUrl). Used by other copayers to verify the proposal.
* @param {string} opts.feePerKb - Optional: Use an alternative fee per KB for this TX
* @param {string} opts.payProUrl - Optional: Paypro URL for peers to verify TX
* @param {string} opts.excludeUnconfirmedUtxos - Optional: Do not use UTXOs of unconfirmed transactions as inputs
* @returns {TxProposal} Transaction proposal.
*/
WalletService.prototype.createTx = function(opts, cb) {
@ -1055,6 +1068,7 @@ WalletService.prototype.createTx = function(opts, cb) {
payProUrl: opts.payProUrl,
requiredSignatures: wallet.m,
requiredRejections: Math.min(wallet.m, wallet.n - wallet.m + 1),
excludeUnconfirmedUtxos: !!opts.excludeUnconfirmedUtxos,
});
self._selectTxInputs(txp, function(err) {

View File

@ -1671,6 +1671,26 @@ describe('Wallet service', function() {
});
});
it('should use confirmed utxos only if specified', function(done) {
helpers.stubUtxos(server, wallet, [1.3, 'u2', 'u0.1', 1.2], function(utxos) {
var txOpts = helpers.createSimpleProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 3, 'some message', TestData.copayers[0].privKey_1H_0);
txOpts.excludeUnconfirmedUtxos = true;
server.createTx(txOpts, function(err, tx) {
should.exist(err);
err.code.should.equal('INSUFFICIENTFUNDS');
err.message.should.equal('Insufficient funds');
var txOpts = helpers.createSimpleProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 2.5, 'some message', TestData.copayers[0].privKey_1H_0);
txOpts.excludeUnconfirmedUtxos = true;
server.createTx(txOpts, function(err, tx) {
should.exist(err);
err.code.should.equal('INSUFFICIENTFUNDS');
err.message.should.equal('Insufficient funds for fee');
done();
});
});
});
});
it('should fail gracefully if unable to reach the blockchain', function(done) {
blockchainExplorer.getUnspentUtxos = sinon.stub().callsArgWith(1, 'dummy error');
server.createAddress({}, function(err, address) {