Merge pull request #499 from troggy/no-shuffle-output
Optionally disable outputs shuffling for createTx
This commit is contained in:
commit
0ffc4f39d5
|
@ -36,7 +36,10 @@ TxProposal.create = function(opts) {
|
||||||
x.outputs = _.map(opts.outputs, function(output) {
|
x.outputs = _.map(opts.outputs, function(output) {
|
||||||
return _.pick(output, ['amount', 'toAddress', 'message', 'script']);
|
return _.pick(output, ['amount', 'toAddress', 'message', 'script']);
|
||||||
});
|
});
|
||||||
x.outputOrder = _.shuffle(_.range(x.outputs.length + 1));
|
x.outputOrder = _.range(x.outputs.length + 1);
|
||||||
|
if (!opts.noShuffleOutputs) {
|
||||||
|
x.outputOrder = _.shuffle(x.outputOrder);
|
||||||
|
}
|
||||||
x.walletM = opts.walletM;
|
x.walletM = opts.walletM;
|
||||||
x.walletN = opts.walletN;
|
x.walletN = opts.walletN;
|
||||||
x.requiredSignatures = x.walletM;
|
x.requiredSignatures = x.walletM;
|
||||||
|
|
|
@ -1878,6 +1878,7 @@ WalletService.prototype._validateAndSanitizeTxOpts = function(wallet, opts, cb)
|
||||||
* @param {string} opts.dryRun[=false] - Optional. Simulate the action but do not change server state.
|
* @param {string} opts.dryRun[=false] - Optional. Simulate the action but do not change server state.
|
||||||
* @param {Array} opts.inputs - Optional. Inputs for this TX
|
* @param {Array} opts.inputs - Optional. Inputs for this TX
|
||||||
* @param {number} opts.fee - Optional. Use an fixed fee for this TX (only when opts.inputs is specified)
|
* @param {number} opts.fee - Optional. Use an fixed fee for this TX (only when opts.inputs is specified)
|
||||||
|
* @param {Boolean} opts.noShuffleOutputs - Optional. If set, TX outputs won't be shuffled. Defaults to false
|
||||||
* @returns {TxProposal} Transaction proposal.
|
* @returns {TxProposal} Transaction proposal.
|
||||||
*/
|
*/
|
||||||
WalletService.prototype.createTx = function(opts, cb) {
|
WalletService.prototype.createTx = function(opts, cb) {
|
||||||
|
@ -1926,6 +1927,7 @@ WalletService.prototype.createTx = function(opts, cb) {
|
||||||
customData: opts.customData,
|
customData: opts.customData,
|
||||||
inputs: opts.inputs,
|
inputs: opts.inputs,
|
||||||
fee: opts.inputs && !_.isNumber(opts.feePerKb) ? opts.fee : null,
|
fee: opts.inputs && !_.isNumber(opts.feePerKb) ? opts.fee : null,
|
||||||
|
noShuffleOutputs: opts.noShuffleOutputs
|
||||||
};
|
};
|
||||||
|
|
||||||
txp = Model.TxProposal.create(txOpts);
|
txp = Model.TxProposal.create(txOpts);
|
||||||
|
|
|
@ -2812,7 +2812,6 @@ describe('Wallet service', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should be able to publish a temporary tx proposal', function(done) {
|
it('should be able to publish a temporary tx proposal', function(done) {
|
||||||
helpers.stubUtxos(server, wallet, [1, 2], function() {
|
helpers.stubUtxos(server, wallet, [1, 2], function() {
|
||||||
var txOpts = {
|
var txOpts = {
|
||||||
|
@ -2840,7 +2839,6 @@ describe('Wallet service', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not be able to publish a temporary tx proposal created in a dry run', function(done) {
|
it('should not be able to publish a temporary tx proposal created in a dry run', function(done) {
|
||||||
helpers.stubUtxos(server, wallet, [1, 2], function() {
|
helpers.stubUtxos(server, wallet, [1, 2], function() {
|
||||||
var txOpts = {
|
var txOpts = {
|
||||||
|
@ -2896,7 +2894,6 @@ describe('Wallet service', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should fail to publish non-existent tx proposal', function(done) {
|
it('should fail to publish non-existent tx proposal', function(done) {
|
||||||
server.publishTx({
|
server.publishTx({
|
||||||
txProposalId: 'wrong-id',
|
txProposalId: 'wrong-id',
|
||||||
|
@ -2910,7 +2907,6 @@ describe('Wallet service', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should fail to publish tx proposal with wrong signature', function(done) {
|
it('should fail to publish tx proposal with wrong signature', function(done) {
|
||||||
helpers.stubUtxos(server, wallet, [1, 2], function() {
|
helpers.stubUtxos(server, wallet, [1, 2], function() {
|
||||||
var txOpts = {
|
var txOpts = {
|
||||||
|
@ -2935,7 +2931,6 @@ describe('Wallet service', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should fail to publish tx proposal not signed by the creator', function(done) {
|
it('should fail to publish tx proposal not signed by the creator', function(done) {
|
||||||
helpers.stubUtxos(server, wallet, [1, 2], function() {
|
helpers.stubUtxos(server, wallet, [1, 2], function() {
|
||||||
var txOpts = {
|
var txOpts = {
|
||||||
|
@ -2963,7 +2958,6 @@ describe('Wallet service', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should accept a tx proposal signed with a custom key', function(done) {
|
it('should accept a tx proposal signed with a custom key', function(done) {
|
||||||
var reqPrivKey = new Bitcore.PrivateKey();
|
var reqPrivKey = new Bitcore.PrivateKey();
|
||||||
var reqPubKey = reqPrivKey.toPublicKey().toString();
|
var reqPubKey = reqPrivKey.toPublicKey().toString();
|
||||||
|
@ -3013,7 +3007,6 @@ describe('Wallet service', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should fail to publish a temporary tx proposal if utxos are unavailable', function(done) {
|
it('should fail to publish a temporary tx proposal if utxos are unavailable', function(done) {
|
||||||
var txp1, txp2;
|
var txp1, txp2;
|
||||||
var txOpts = {
|
var txOpts = {
|
||||||
|
@ -3082,7 +3075,6 @@ describe('Wallet service', function() {
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should fail to list pending proposals from legacy client', function(done) {
|
it('should fail to list pending proposals from legacy client', function(done) {
|
||||||
helpers.stubUtxos(server, wallet, [1, 2], function() {
|
helpers.stubUtxos(server, wallet, [1, 2], function() {
|
||||||
var txOpts = {
|
var txOpts = {
|
||||||
|
@ -3115,7 +3107,6 @@ describe('Wallet service', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should be able to specify inputs & absolute fee', function(done) {
|
it('should be able to specify inputs & absolute fee', function(done) {
|
||||||
helpers.stubUtxos(server, wallet, [1, 2], function(utxos) {
|
helpers.stubUtxos(server, wallet, [1, 2], function(utxos) {
|
||||||
var txOpts = {
|
var txOpts = {
|
||||||
|
@ -3139,7 +3130,6 @@ describe('Wallet service', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should be able to send max funds', function(done) {
|
it('should be able to send max funds', function(done) {
|
||||||
helpers.stubUtxos(server, wallet, [1, 2], function() {
|
helpers.stubUtxos(server, wallet, [1, 2], function() {
|
||||||
var txOpts = {
|
var txOpts = {
|
||||||
|
@ -3165,7 +3155,40 @@ describe('Wallet service', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
it('should shuffle outputs unless specified', function(done) {
|
||||||
|
helpers.stubUtxos(server, wallet, 1, function() {
|
||||||
|
var txOpts = {
|
||||||
|
outputs: _.times(30, function(i) {
|
||||||
|
return {
|
||||||
|
toAddress: '18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7',
|
||||||
|
amount: (i + 1) * 100e2,
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
feePerKb: 123e2,
|
||||||
|
};
|
||||||
|
server.createTx(txOpts, function(err, txp) {
|
||||||
|
should.not.exist(err);
|
||||||
|
should.exist(txp);
|
||||||
|
var t = txp.getBitcoreTx();
|
||||||
|
var changeOutput = t.getChangeOutput().satoshis;
|
||||||
|
var outputs = _.without(_.pluck(t.outputs, 'satoshis'), changeOutput);
|
||||||
|
|
||||||
|
outputs.should.not.deep.equal(_.pluck(txOpts.outputs, 'amount'));
|
||||||
|
txOpts.noShuffleOutputs = true;
|
||||||
|
server.createTx(txOpts, function(err, txp) {
|
||||||
|
should.not.exist(err);
|
||||||
|
should.exist(txp);
|
||||||
|
|
||||||
|
t = txp.getBitcoreTx();
|
||||||
|
changeOutput = t.getChangeOutput().satoshis;
|
||||||
|
outputs = _.without(_.pluck(t.outputs, 'satoshis'), changeOutput);
|
||||||
|
|
||||||
|
outputs.should.deep.equal(_.pluck(txOpts.outputs, 'amount'));
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Backoff time', function(done) {
|
describe('Backoff time', function(done) {
|
||||||
|
|
Loading…
Reference in New Issue