From b5f6582b777b1cda98702a34221b3d856c4ec46c Mon Sep 17 00:00:00 2001 From: Ivan Socolsky Date: Wed, 11 Mar 2015 15:04:42 -0300 Subject: [PATCH] refactor tx inputs selection --- lib/server.js | 98 +++++++++++++++++++------------------- test/integration/server.js | 2 +- 2 files changed, 49 insertions(+), 51 deletions(-) diff --git a/lib/server.js b/lib/server.js index b2d2520..014bb22 100644 --- a/lib/server.js +++ b/lib/server.js @@ -464,33 +464,42 @@ WalletService.prototype.getBalance = function(opts, cb) { }); }; +WalletService.prototype._selectTxInputs = function(txp, cb) { + var self = this; -WalletService.prototype._selectUtxos = function(txp, utxos) { - var i = 0; - var total = 0; - var selected = []; - var inputs = _.sortBy(utxos, 'amount'); + self._getUtxos(function(err, utxos) { + if (err) return cb(err); - while (i < inputs.length) { - selected.push(inputs[i]); - total += inputs[i].satoshis; + utxos = _.reject(utxos, { + locked: true + }); - if (total >= txp.amount + Bitcore.Transaction.FEE_PER_KB) { - try { - // Check if there are enough fees - txp.inputs = selected; - var raw = txp.getRawTx(); - return; - } catch (ex) { - if (ex.name != 'bitcore.ErrorTransactionFeeError') { - throw ex.message; + var i = 0; + var total = 0; + var selected = []; + var inputs = _.sortBy(utxos, 'amount'); + + while (i < inputs.length) { + selected.push(inputs[i]); + total += inputs[i].satoshis; + + if (total >= txp.amount + Bitcore.Transaction.FEE_PER_KB) { + try { + // Check if there are enough fees + txp.inputs = selected; + var raw = txp.getRawTx(); + txp.inputPaths = _.pluck(txp.inputs, 'path'); + return cb(); + } catch (ex) { + if (ex.name != 'bitcore.ErrorTransactionFeeError') { + return cb(ex); + } } } - } - i++; - }; - txp.inputs = null; - return; + i++; + }; + return cb(new ClientError('INSUFFICIENTFUNDS', 'Insufficient funds')); + }); }; @@ -534,36 +543,25 @@ WalletService.prototype.createTx = function(opts, cb) { if (opts.amount < Bitcore.Transaction.DUST_AMOUNT) return cb(new ClientError('DUSTAMOUNT', 'Amount below dust threshold')); - self._getUtxos(function(err, utxos) { + + var changeAddress = wallet.createAddress(true); + + var txp = TxProposal.create({ + creatorId: self.copayerId, + toAddress: opts.toAddress, + amount: opts.amount, + message: opts.message, + proposalSignature: opts.proposalSignature, + changeAddress: changeAddress, + requiredSignatures: wallet.m, + requiredRejections: Math.min(wallet.m, wallet.n - wallet.m + 1), + }); + + + self._selectTxInputs(txp, function(err) { if (err) return cb(err); - var changeAddress = wallet.createAddress(true); - - utxos = _.reject(utxos, { - locked: true - }); - - var txp = TxProposal.create({ - creatorId: self.copayerId, - toAddress: opts.toAddress, - amount: opts.amount, - message: opts.message, - proposalSignature: opts.proposalSignature, - changeAddress: changeAddress, - requiredSignatures: wallet.m, - requiredRejections: Math.min(wallet.m, wallet.n - wallet.m + 1), - }); - - try { - self._selectUtxos(txp, utxos); - } catch (ex) { - return cb(new ClientError(ex.toString())); - } - - if (!txp.inputs) - return cb(new ClientError('INSUFFICIENTFUNDS', 'Insufficient funds')); - - txp.inputPaths = _.pluck(txp.inputs, 'path'); + $.checkState(txp.inputs); self.storage.storeAddressAndWallet(wallet, changeAddress, function(err) { if (err) return cb(err); diff --git a/test/integration/server.js b/test/integration/server.js index 0afe5b0..cfd878d 100644 --- a/test/integration/server.js +++ b/test/integration/server.js @@ -984,7 +984,7 @@ describe('Copay server', function() { }); }); - it.only('should fail with different error for insufficient funds and locked funds', function(done) { + it('should fail with different error for insufficient funds and locked funds', function(done) { helpers.stubUtxos(server, wallet, [10, 10], function() { var txOpts = helpers.createProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 11, null, TestData.copayers[0].privKey_1H_0); server.createTx(txOpts, function(err, tx) {