From 97d4809f683cc311d353edded8208d4872a91c2e Mon Sep 17 00:00:00 2001 From: Ivan Socolsky Date: Thu, 12 Mar 2015 11:34:41 -0300 Subject: [PATCH 1/6] use Bitcore instance from BWU --- lib/model/address.js | 2 +- lib/model/copayer.js | 5 ++--- lib/model/txproposal.js | 2 +- lib/server.js | 4 ++-- package.json | 1 - test/integration/server.js | 2 +- test/models/txproposal.js | 2 +- 7 files changed, 8 insertions(+), 10 deletions(-) diff --git a/lib/model/address.js b/lib/model/address.js index 8ef4db0..a5da342 100644 --- a/lib/model/address.js +++ b/lib/model/address.js @@ -1,6 +1,6 @@ 'use strict'; -var Bitcore = require('bitcore'); +var Bitcore = require('bitcore-wallet-utils').Bitcore; function Address() { this.version = '1.0.0'; diff --git a/lib/model/copayer.js b/lib/model/copayer.js index 1cfffd4..830a55f 100644 --- a/lib/model/copayer.js +++ b/lib/model/copayer.js @@ -4,12 +4,11 @@ var $ = require('preconditions').singleton(); var _ = require('lodash'); var util = require('util'); -var Bitcore = require('bitcore'); -var HDPublicKey = Bitcore.HDPublicKey; var Uuid = require('uuid'); var AddressManager = require('./addressmanager'); var WalletUtils = require('bitcore-wallet-utils'); - +var Bitcore = WalletUtils.Bitcore; +var HDPublicKey = Bitcore.HDPublicKey; function Copayer() { this.version = '1.0.0'; diff --git a/lib/model/txproposal.js b/lib/model/txproposal.js index ef77ec4..9f3bcc7 100644 --- a/lib/model/txproposal.js +++ b/lib/model/txproposal.js @@ -2,7 +2,7 @@ var _ = require('lodash'); var Uuid = require('uuid'); -var Bitcore = require('bitcore'); +var Bitcore = require('bitcore-wallet-utils').Bitcore; var Address = Bitcore.Address; var TxProposalAction = require('./txproposalaction'); diff --git a/lib/server.js b/lib/server.js index 4481849..1b4e707 100644 --- a/lib/server.js +++ b/lib/server.js @@ -8,7 +8,8 @@ var inherits = require('inherits'); var events = require('events'); var nodeutil = require('util'); -var Bitcore = require('bitcore'); +var WalletUtils = require('bitcore-wallet-utils'); +var Bitcore = WalletUtils.Bitcore; var PublicKey = Bitcore.PublicKey; var HDPublicKey = Bitcore.HDPublicKey; var Address = Bitcore.Address; @@ -17,7 +18,6 @@ var Explorers = require('bitcore-explorers'); var ClientError = require('./clienterror'); var Utils = require('./utils'); var Storage = require('./storage'); -var WalletUtils = require('bitcore-wallet-utils'); var Wallet = require('./model/wallet'); var Copayer = require('./model/copayer'); diff --git a/package.json b/package.json index a2c6aba..1ecbe19 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,6 @@ }, "dependencies": { "async": "^0.9.0", - "bitcore": "^0.11.2", "bitcore-wallet-utils": "0.0.3", "bitcore-explorers": "^0.9.1", "body-parser": "^1.11.0", diff --git a/test/integration/server.js b/test/integration/server.js index 6b49596..dc2f016 100644 --- a/test/integration/server.js +++ b/test/integration/server.js @@ -11,10 +11,10 @@ var levelup = require('levelup'); var memdown = require('memdown'); var log = require('npmlog'); log.debug = log.verbose; -var Bitcore = require('bitcore'); var Utils = require('../../lib/utils'); var WalletUtils = require('bitcore-wallet-utils'); +var Bitcore = WalletUtils.Bitcore; var Storage = require('../../lib/storage'); var Wallet = require('../../lib/model/wallet'); diff --git a/test/models/txproposal.js b/test/models/txproposal.js index 119ab88..35b5ce8 100644 --- a/test/models/txproposal.js +++ b/test/models/txproposal.js @@ -5,7 +5,7 @@ var chai = require('chai'); var sinon = require('sinon'); var should = chai.should(); var TXP = require('../../lib/model/txproposal'); -var Bitcore = require('bitcore'); +var Bitcore = require('bitcore-wallet-utils').Bitcore; describe('TXProposal', function() { From 31035a533f06abaa4b3b1da73561079842299686 Mon Sep 17 00:00:00 2001 From: Ivan Socolsky Date: Thu, 12 Mar 2015 11:47:39 -0300 Subject: [PATCH 2/6] use actual client signing code in tests --- test/integration/server.js | 65 ++++++++++---------------------------- 1 file changed, 17 insertions(+), 48 deletions(-) diff --git a/test/integration/server.js b/test/integration/server.js index dc2f016..3a5ae14 100644 --- a/test/integration/server.js +++ b/test/integration/server.js @@ -168,38 +168,7 @@ helpers.stubHistory = function(txs) { blockExplorer.getTransactions = sinon.stub().callsArgWith(1, null, txs); }; -helpers.clientSign = function(txp, xprivHex) { - //Derive proper key to sign, for each input - var privs = [], - derived = {}; - var xpriv = new Bitcore.HDPrivateKey(xprivHex); - - _.each(txp.inputs, function(i) { - if (!derived[i.path]) { - derived[i.path] = xpriv.derive(i.path).privateKey; - privs.push(derived[i.path]); - } - }); - - var t = new Bitcore.Transaction(); - - _.each(txp.inputs, function(i) { - t.from(i, i.publicKeys, txp.requiredSignatures); - }); - - t.to(txp.toAddress, txp.amount) - .change(txp.changeAddress.address); - - var signatures = _.map(privs, function(priv, i) { - return t.getSignatures(priv); - }); - - signatures = _.map(_.sortBy(_.flatten(signatures), 'inputIndex'), function(s) { - return s.signature.toDER().toString('hex'); - }); - - return signatures; -}; +helpers.clientSign = WalletUtils.signTxp; helpers.createProposalOpts = function(toAddress, amount, message, signingKey) { var opts = { @@ -1236,7 +1205,7 @@ describe('Copay server', function() { var tx = txs[0]; tx.id.should.equal(txid); - var signatures = helpers.clientSign(tx, TestData.copayers[0].xPrivKey_45H); + var signatures = helpers.clientSign(tx, TestData.copayers[0].xPrivKey); server.signTx({ txProposalId: txid, signatures: signatures, @@ -1263,7 +1232,7 @@ describe('Copay server', function() { server.getPendingTxs({}, function(err, txs) { var tx = txs[0]; tx.id.should.equal(txid); - var signatures = helpers.clientSign(tx, TestData.copayers[1].xPrivKey_45H); + var signatures = helpers.clientSign(tx, TestData.copayers[1].xPrivKey); server.signTx({ txProposalId: txid, signatures: signatures, @@ -1279,7 +1248,7 @@ describe('Copay server', function() { var tx = txs[0]; tx.id.should.equal(txid); - var signatures = helpers.clientSign(tx, TestData.copayers[0].xPrivKey_45H); + var signatures = helpers.clientSign(tx, TestData.copayers[0].xPrivKey); signatures[0] = 1; server.signTx({ @@ -1314,7 +1283,7 @@ describe('Copay server', function() { var tx = txs[0]; tx.id.should.equal(txid); - var signatures = _.take(helpers.clientSign(tx, TestData.copayers[0].xPrivKey_45H), 2); + var signatures = _.take(helpers.clientSign(tx, TestData.copayers[0].xPrivKey), 2); server.signTx({ txProposalId: txid, signatures: signatures, @@ -1331,7 +1300,7 @@ describe('Copay server', function() { var tx = txs[0]; tx.id.should.equal(txid); - var signatures = helpers.clientSign(tx, TestData.copayers[0].xPrivKey_45H); + var signatures = helpers.clientSign(tx, TestData.copayers[0].xPrivKey); server.signTx({ txProposalId: txid, signatures: signatures, @@ -1354,7 +1323,7 @@ describe('Copay server', function() { server.rejectTx({ txProposalId: txid, }, function(err) { - var signatures = helpers.clientSign(tx, TestData.copayers[0].xPrivKey_45H); + var signatures = helpers.clientSign(tx, TestData.copayers[0].xPrivKey); server.signTx({ txProposalId: txid, signatures: signatures, @@ -1402,7 +1371,7 @@ describe('Copay server', function() { txProposalId: txid }, function(err, tx) { should.not.exist(err); - var signatures = helpers.clientSign(tx, TestData.copayers[2].xPrivKey_45H); + var signatures = helpers.clientSign(tx, TestData.copayers[2].xPrivKey); server.signTx({ txProposalId: txid, signatures: signatures, @@ -1429,7 +1398,7 @@ describe('Copay server', function() { server.createTx(txOpts, function(err, txp) { should.not.exist(err); should.exist(txp); - var signatures = helpers.clientSign(txp, TestData.copayers[0].xPrivKey_45H); + var signatures = helpers.clientSign(txp, TestData.copayers[0].xPrivKey); server.signTx({ txProposalId: txp.id, signatures: signatures, @@ -1571,7 +1540,7 @@ describe('Copay server', function() { }); }, function(txp, next) { - var signatures = helpers.clientSign(txp, TestData.copayers[0].xPrivKey_45H); + var signatures = helpers.clientSign(txp, TestData.copayers[0].xPrivKey); server.signTx({ txProposalId: txpId, signatures: signatures, @@ -1602,7 +1571,7 @@ describe('Copay server', function() { }, function(txp, next) { helpers.getAuthServer(wallet.copayers[1].id, function(server, wallet) { - var signatures = helpers.clientSign(txp, TestData.copayers[1].xPrivKey_45H); + var signatures = helpers.clientSign(txp, TestData.copayers[1].xPrivKey); server.signTx({ txProposalId: txpId, signatures: signatures, @@ -1917,7 +1886,7 @@ describe('Copay server', function() { server.getPendingTxs({}, function(err, txs) { helpers.stubBroadcastFail(); var tx = txs[0]; - var signatures = helpers.clientSign(tx, TestData.copayers[0].xPrivKey_45H); + var signatures = helpers.clientSign(tx, TestData.copayers[0].xPrivKey); server.signTx({ txProposalId: tx.id, signatures: signatures, @@ -1959,7 +1928,7 @@ describe('Copay server', function() { it('should notify sign, acceptance, and broadcast, and emit', function(done) { server.getPendingTxs({}, function(err, txs) { var tx = txs[2]; - var signatures = helpers.clientSign(tx, TestData.copayers[0].xPrivKey_45H); + var signatures = helpers.clientSign(tx, TestData.copayers[0].xPrivKey); sinon.spy(server, 'emit'); server.signTx({ txProposalId: tx.id, @@ -2102,7 +2071,7 @@ describe('Copay server', function() { }); it('should allow creator to remove an signed TX by himself', function(done) { - var signatures = helpers.clientSign(txp, TestData.copayers[0].xPrivKey_45H); + var signatures = helpers.clientSign(txp, TestData.copayers[0].xPrivKey); server.signTx({ txProposalId: txp.id, signatures: signatures, @@ -2124,7 +2093,7 @@ describe('Copay server', function() { async.waterfall([ function(next) { - var signatures = helpers.clientSign(txp, TestData.copayers[0].xPrivKey_45H); + var signatures = helpers.clientSign(txp, TestData.copayers[0].xPrivKey); server.signTx({ txProposalId: txp.id, signatures: signatures, @@ -2188,7 +2157,7 @@ describe('Copay server', function() { it('should not allow creator copayer to remove an TX signed by other copayer', function(done) { helpers.getAuthServer(wallet.copayers[1].id, function(server2) { - var signatures = helpers.clientSign(txp, TestData.copayers[1].xPrivKey_45H); + var signatures = helpers.clientSign(txp, TestData.copayers[1].xPrivKey); server2.signTx({ txProposalId: txp.id, signatures: signatures, @@ -2325,7 +2294,7 @@ describe('Copay server', function() { should.not.exist(err); should.exist(tx); - var signatures = helpers.clientSign(tx, TestData.copayers[0].xPrivKey_45H); + var signatures = helpers.clientSign(tx, TestData.copayers[0].xPrivKey); server.signTx({ txProposalId: tx.id, signatures: signatures, From e06a788e0513947ac000e4899ae9d4dcd9ac75dd Mon Sep 17 00:00:00 2001 From: Ivan Socolsky Date: Thu, 12 Mar 2015 11:49:01 -0300 Subject: [PATCH 3/6] build tx using BWU --- lib/model/txproposal.js | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/lib/model/txproposal.js b/lib/model/txproposal.js index 9f3bcc7..bc6dc76 100644 --- a/lib/model/txproposal.js +++ b/lib/model/txproposal.js @@ -2,7 +2,8 @@ var _ = require('lodash'); var Uuid = require('uuid'); -var Bitcore = require('bitcore-wallet-utils').Bitcore; +var WalletUtils = require('bitcore-wallet-utils'); +var Bitcore = WalletUtils.Bitcore; var Address = Bitcore.Address; var TxProposalAction = require('./txproposalaction'); @@ -89,16 +90,7 @@ TxProposal.prototype._getCurrentSignatures = function() { TxProposal.prototype.getBitcoreTx = function() { var self = this; - var t = new Bitcore.Transaction(); - - _.each(this.inputs, function(i) { - t.from(i, i.publicKeys, self.requiredSignatures) - }); - - t.to(this.toAddress, this.amount) - .change(this.changeAddress.address); - - t._updateChangeOutput(); + var t = WalletUtils.buildTx(this); var sigs = this._getCurrentSignatures(); _.each(sigs, function(x) { From 4a53da8690496aa4b83b9e3be3311708034ae324 Mon Sep 17 00:00:00 2001 From: Ivan Socolsky Date: Thu, 12 Mar 2015 12:01:44 -0300 Subject: [PATCH 4/6] shuffle outputs --- lib/model/txproposal.js | 2 ++ test/models/txproposal.js | 14 +++++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/lib/model/txproposal.js b/lib/model/txproposal.js index bc6dc76..1846e50 100644 --- a/lib/model/txproposal.js +++ b/lib/model/txproposal.js @@ -32,6 +32,7 @@ TxProposal.create = function(opts) { x.requiredRejections = opts.requiredRejections; x.status = 'pending'; x.actions = []; + x.outputOrder = _.shuffle(_.range(2)); return x; }; @@ -58,6 +59,7 @@ TxProposal.fromObj = function(obj) { x.actions = _.map(obj.actions, function(action) { return TxProposalAction.fromObj(action); }); + x.outputOrder = obj.outputOrder; return x; }; diff --git a/test/models/txproposal.js b/test/models/txproposal.js index 35b5ce8..58e5dd8 100644 --- a/test/models/txproposal.js +++ b/test/models/txproposal.js @@ -22,6 +22,17 @@ describe('TXProposal', function() { var t = txp.getBitcoreTx(); should.exist(t); }); + it('should order ouputs as specified by outputOrder', function() { + var txp = TXP.fromObj(aTXP()); + + txp.outputOrder = [0, 1]; + var t = txp._getBitcoreTx(); + t.getChangeOutput().should.deep.equal(t.outputs[1]); + + txp.outputOrder = [1, 0]; + var t = txp._getBitcoreTx(); + t.getChangeOutput().should.deep.equal(t.outputs[0]); + }); }); @@ -108,6 +119,7 @@ var aTXP = function() { "requiredSignatures": 2, "requiredRejections": 1, "status": "pending", - "actions": [] + "actions": [], + "outputOrder": [0, 1], } }; From c3722fc2191cffbb5ee7073037532f47ac248a96 Mon Sep 17 00:00:00 2001 From: Ivan Socolsky Date: Thu, 12 Mar 2015 12:11:16 -0300 Subject: [PATCH 5/6] v0.0.4 --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 1ecbe19..4638121 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "bitcore-wallet-service", "description": "A service for Mutisig HD Bitcoin Wallets", "author": "BitPay Inc", - "version": "0.0.5", + "version": "0.0.6", "keywords": [ "bitcoin", "copay", @@ -19,7 +19,7 @@ }, "dependencies": { "async": "^0.9.0", - "bitcore-wallet-utils": "0.0.3", + "bitcore-wallet-utils": "^0.0.4", "bitcore-explorers": "^0.9.1", "body-parser": "^1.11.0", "coveralls": "^2.11.2", From de21e086a9b2060b15eaa0e0f54509e6aff7a0c0 Mon Sep 17 00:00:00 2001 From: Ivan Socolsky Date: Fri, 13 Mar 2015 11:59:09 -0300 Subject: [PATCH 6/6] rebase --- test/models/txproposal.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/models/txproposal.js b/test/models/txproposal.js index 58e5dd8..9b864f3 100644 --- a/test/models/txproposal.js +++ b/test/models/txproposal.js @@ -26,11 +26,11 @@ describe('TXProposal', function() { var txp = TXP.fromObj(aTXP()); txp.outputOrder = [0, 1]; - var t = txp._getBitcoreTx(); + var t = txp.getBitcoreTx(); t.getChangeOutput().should.deep.equal(t.outputs[1]); txp.outputOrder = [1, 0]; - var t = txp._getBitcoreTx(); + var t = txp.getBitcoreTx(); t.getChangeOutput().should.deep.equal(t.outputs[0]); }); });