Browse Source

refactor tx inputs selection

activeAddress
Ivan Socolsky 10 years ago
parent
commit
b5f6582b77
  1. 92
      lib/server.js
  2. 2
      test/integration/server.js

92
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) { self._getUtxos(function(err, utxos) {
var i = 0; if (err) return cb(err);
var total = 0;
var selected = [];
var inputs = _.sortBy(utxos, 'amount');
while (i < inputs.length) { utxos = _.reject(utxos, {
selected.push(inputs[i]); locked: true
total += inputs[i].satoshis; });
if (total >= txp.amount + Bitcore.Transaction.FEE_PER_KB) { var i = 0;
try { var total = 0;
// Check if there are enough fees var selected = [];
txp.inputs = selected; var inputs = _.sortBy(utxos, 'amount');
var raw = txp.getRawTx();
return; while (i < inputs.length) {
} catch (ex) { selected.push(inputs[i]);
if (ex.name != 'bitcore.ErrorTransactionFeeError') { total += inputs[i].satoshis;
throw ex.message;
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++;
i++; };
}; return cb(new ClientError('INSUFFICIENTFUNDS', 'Insufficient funds'));
txp.inputs = null; });
return;
}; };
@ -534,36 +543,25 @@ WalletService.prototype.createTx = function(opts, cb) {
if (opts.amount < Bitcore.Transaction.DUST_AMOUNT) if (opts.amount < Bitcore.Transaction.DUST_AMOUNT)
return cb(new ClientError('DUSTAMOUNT', 'Amount below dust threshold')); return cb(new ClientError('DUSTAMOUNT', 'Amount below dust threshold'));
self._getUtxos(function(err, utxos) {
if (err) return cb(err);
var changeAddress = wallet.createAddress(true);
utxos = _.reject(utxos, { var changeAddress = wallet.createAddress(true);
locked: true
});
var txp = TxProposal.create({ var txp = TxProposal.create({
creatorId: self.copayerId, creatorId: self.copayerId,
toAddress: opts.toAddress, toAddress: opts.toAddress,
amount: opts.amount, amount: opts.amount,
message: opts.message, message: opts.message,
proposalSignature: opts.proposalSignature, proposalSignature: opts.proposalSignature,
changeAddress: changeAddress, changeAddress: changeAddress,
requiredSignatures: wallet.m, requiredSignatures: wallet.m,
requiredRejections: Math.min(wallet.m, wallet.n - wallet.m + 1), 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) self._selectTxInputs(txp, function(err) {
return cb(new ClientError('INSUFFICIENTFUNDS', 'Insufficient funds')); if (err) return cb(err);
txp.inputPaths = _.pluck(txp.inputs, 'path'); $.checkState(txp.inputs);
self.storage.storeAddressAndWallet(wallet, changeAddress, function(err) { self.storage.storeAddressAndWallet(wallet, changeAddress, function(err) {
if (err) return cb(err); if (err) return cb(err);

2
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() { helpers.stubUtxos(server, wallet, [10, 10], function() {
var txOpts = helpers.createProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 11, null, TestData.copayers[0].privKey_1H_0); var txOpts = helpers.createProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 11, null, TestData.copayers[0].privKey_1H_0);
server.createTx(txOpts, function(err, tx) { server.createTx(txOpts, function(err, tx) {

Loading…
Cancel
Save