From 23cddbe47f4a13c3a78fcc2d68c7f079f66e79c3 Mon Sep 17 00:00:00 2001 From: Ivan Socolsky Date: Fri, 29 Jan 2016 10:51:06 -0300 Subject: [PATCH] fix broadcasting new proposals --- lib/model/txproposal.js | 4 + test/integration/helpers.js | 11 ++ test/integration/server.js | 347 +++++++++++++++++++++--------------- 3 files changed, 216 insertions(+), 146 deletions(-) diff --git a/lib/model/txproposal.js b/lib/model/txproposal.js index 2a3d115..af4f764 100644 --- a/lib/model/txproposal.js +++ b/lib/model/txproposal.js @@ -209,6 +209,10 @@ TxProposal.prototype.getBitcoreTx = function() { return t; }; +TxProposal.prototype.getNetworkName = function() { + return this.network; +}; + TxProposal.prototype.getRawTx = function() { var t = this.getBitcoreTx(); diff --git a/test/integration/helpers.js b/test/integration/helpers.js index 0f2e9d3..e816790 100644 --- a/test/integration/helpers.js +++ b/test/integration/helpers.js @@ -468,4 +468,15 @@ helpers.createAddresses = function(server, wallet, main, change, cb) { }); }; +helpers.createAndPublishTx = function(server, txOpts, signingKey, cb) { + server.createTx(txOpts, function(err, txp) { + should.not.exist(err); + var publishOpts = helpers.getProposalSignatureOpts(txp, signingKey); + server.publishTx(publishOpts, function(err) { + should.not.exist(err); + return cb(txp); + }); + }); +}; + module.exports = helpers; diff --git a/test/integration/server.js b/test/integration/server.js index 43267d8..16cbce6 100644 --- a/test/integration/server.js +++ b/test/integration/server.js @@ -3429,207 +3429,262 @@ describe('Wallet service', function() { describe('#broadcastTx & #broadcastRawTx', function() { var server, wallet, txpid, txid; - beforeEach(function(done) { - helpers.createAndJoinWallet(1, 1, function(s, w) { - server = s; - wallet = w; - helpers.stubUtxos(server, wallet, [10, 10], function() { - var txOpts = helpers.createSimpleProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 9, TestData.copayers[0].privKey_1H_0, { - message: 'some message' - }); - server.createTxLegacy(txOpts, function(err, txp) { - should.not.exist(err); - should.exist(txp); - var signatures = helpers.clientSign(txp, TestData.copayers[0].xPrivKey_44H_0H_0H); - server.signTx({ - txProposalId: txp.id, - signatures: signatures, - }, function(err, txp) { + describe('Legacy', function() { + + beforeEach(function(done) { + helpers.createAndJoinWallet(1, 1, function(s, w) { + server = s; + wallet = w; + helpers.stubUtxos(server, wallet, [10, 10], function() { + var txOpts = helpers.createSimpleProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 9, TestData.copayers[0].privKey_1H_0, { + message: 'some message' + }); + server.createTxLegacy(txOpts, function(err, txp) { should.not.exist(err); should.exist(txp); - txp.isAccepted().should.be.true; - txp.isBroadcasted().should.be.false; - txid = txp.txid; - txpid = txp.id; - done(); + var signatures = helpers.clientSign(txp, TestData.copayers[0].xPrivKey_44H_0H_0H); + server.signTx({ + txProposalId: txp.id, + signatures: signatures, + }, function(err, txp) { + should.not.exist(err); + should.exist(txp); + txp.isAccepted().should.be.true; + txp.isBroadcasted().should.be.false; + txid = txp.txid; + txpid = txp.id; + done(); + }); }); }); }); }); - }); - it('should broadcast a tx', function(done) { - var clock = sinon.useFakeTimers(1234000, 'Date'); - helpers.stubBroadcast(); - server.broadcastTx({ - txProposalId: txpid - }, function(err) { - should.not.exist(err); - server.getTx({ + it('should broadcast a tx', function(done) { + var clock = sinon.useFakeTimers(1234000, 'Date'); + helpers.stubBroadcast(); + server.broadcastTx({ txProposalId: txpid - }, function(err, txp) { + }, function(err) { should.not.exist(err); - should.not.exist(txp.raw); - txp.txid.should.equal(txid); - txp.isBroadcasted().should.be.true; - txp.broadcastedOn.should.equal(1234); - clock.restore(); - done(); + server.getTx({ + txProposalId: txpid + }, function(err, txp) { + should.not.exist(err); + should.not.exist(txp.raw); + txp.txid.should.equal(txid); + txp.isBroadcasted().should.be.true; + txp.broadcastedOn.should.equal(1234); + clock.restore(); + done(); + }); }); }); - }); - it('should broadcast a raw tx', function(done) { - helpers.stubBroadcast(); - server.broadcastRawTx({ - network: 'testnet', - rawTx: 'raw tx', - }, function(err, txid) { - should.not.exist(err); - should.exist(txid); - done(); + it('should broadcast a raw tx', function(done) { + helpers.stubBroadcast(); + server.broadcastRawTx({ + network: 'testnet', + rawTx: 'raw tx', + }, function(err, txid) { + should.not.exist(err); + should.exist(txid); + done(); + }); }); - }); - it('should fail to brodcast a tx already marked as broadcasted', function(done) { - helpers.stubBroadcast(); - server.broadcastTx({ - txProposalId: txpid - }, function(err) { - should.not.exist(err); + it('should fail to brodcast a tx already marked as broadcasted', function(done) { + helpers.stubBroadcast(); server.broadcastTx({ txProposalId: txpid }, function(err) { - should.exist(err); - err.code.should.equal('TX_ALREADY_BROADCASTED'); - done(); - }); - }); - }); - - it('should auto process already broadcasted txs', function(done) { - helpers.stubBroadcast(); - server.getPendingTxs({}, function(err, txs) { - should.not.exist(err); - txs.length.should.equal(1); - blockchainExplorer.getTransaction = sinon.stub().callsArgWith(1, null, { - txid: 999 - }); - server.getPendingTxs({}, function(err, txs) { should.not.exist(err); - txs.length.should.equal(0); - done(); + server.broadcastTx({ + txProposalId: txpid + }, function(err) { + should.exist(err); + err.code.should.equal('TX_ALREADY_BROADCASTED'); + done(); + }); }); }); - }); - it('should process only broadcasted txs', function(done) { - helpers.stubBroadcast(); - var txOpts = helpers.createSimpleProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 9, TestData.copayers[0].privKey_1H_0, { - message: 'some message 2' - }); - server.createTxLegacy(txOpts, function(err, txp) { - should.not.exist(err); + it('should auto process already broadcasted txs', function(done) { + helpers.stubBroadcast(); server.getPendingTxs({}, function(err, txs) { should.not.exist(err); - txs.length.should.equal(2); + txs.length.should.equal(1); blockchainExplorer.getTransaction = sinon.stub().callsArgWith(1, null, { txid: 999 }); server.getPendingTxs({}, function(err, txs) { should.not.exist(err); - txs.length.should.equal(1); - txs[0].status.should.equal('pending'); - should.not.exist(txs[0].txid); + txs.length.should.equal(0); done(); }); }); }); - }); - - - + it('should process only broadcasted txs', function(done) { + helpers.stubBroadcast(); + var txOpts = helpers.createSimpleProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 9, TestData.copayers[0].privKey_1H_0, { + message: 'some message 2' + }); + server.createTxLegacy(txOpts, function(err, txp) { + should.not.exist(err); + server.getPendingTxs({}, function(err, txs) { + should.not.exist(err); + txs.length.should.equal(2); + blockchainExplorer.getTransaction = sinon.stub().callsArgWith(1, null, { + txid: 999 + }); + server.getPendingTxs({}, function(err, txs) { + should.not.exist(err); + txs.length.should.equal(1); + txs[0].status.should.equal('pending'); + should.not.exist(txs[0].txid); + done(); + }); + }); + }); + }); - it('should fail to brodcast a not yet accepted tx', function(done) { - helpers.stubBroadcast(); - var txOpts = helpers.createSimpleProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 9, TestData.copayers[0].privKey_1H_0, { - message: 'some message' + it('should fail to brodcast a not yet accepted tx', function(done) { + helpers.stubBroadcast(); + var txOpts = helpers.createSimpleProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 9, TestData.copayers[0].privKey_1H_0, { + message: 'some message' + }); + server.createTxLegacy(txOpts, function(err, txp) { + should.not.exist(err); + should.exist(txp); + server.broadcastTx({ + txProposalId: txp.id + }, function(err) { + should.exist(err); + err.code.should.equal('TX_NOT_ACCEPTED'); + done(); + }); + }); }); - server.createTxLegacy(txOpts, function(err, txp) { - should.not.exist(err); - should.exist(txp); + + it('should keep tx as accepted if unable to broadcast it', function(done) { + blockchainExplorer.broadcast = sinon.stub().callsArgWith(1, 'broadcast error'); + blockchainExplorer.getTransaction = sinon.stub().callsArgWith(1, null, null); server.broadcastTx({ - txProposalId: txp.id + txProposalId: txpid }, function(err) { should.exist(err); - err.code.should.equal('TX_NOT_ACCEPTED'); - done(); + err.toString().should.equal('broadcast error'); + server.getTx({ + txProposalId: txpid + }, function(err, txp) { + should.not.exist(err); + should.exist(txp.txid); + txp.isBroadcasted().should.be.false; + should.not.exist(txp.broadcastedOn); + txp.isAccepted().should.be.true; + done(); + }); }); }); - }); - it('should keep tx as accepted if unable to broadcast it', function(done) { - blockchainExplorer.broadcast = sinon.stub().callsArgWith(1, 'broadcast error'); - blockchainExplorer.getTransaction = sinon.stub().callsArgWith(1, null, null); - server.broadcastTx({ - txProposalId: txpid - }, function(err) { - should.exist(err); - err.toString().should.equal('broadcast error'); - server.getTx({ + it('should mark tx as broadcasted if accepted but already in blockchain', function(done) { + blockchainExplorer.broadcast = sinon.stub().callsArgWith(1, 'broadcast error'); + blockchainExplorer.getTransaction = sinon.stub().callsArgWith(1, null, { + txid: '999' + }); + server.broadcastTx({ txProposalId: txpid - }, function(err, txp) { + }, function(err) { should.not.exist(err); - should.exist(txp.txid); - txp.isBroadcasted().should.be.false; - should.not.exist(txp.broadcastedOn); - txp.isAccepted().should.be.true; - done(); + server.getTx({ + txProposalId: txpid + }, function(err, txp) { + should.not.exist(err); + should.exist(txp.txid); + txp.isBroadcasted().should.be.true; + should.exist(txp.broadcastedOn); + done(); + }); }); }); - }); - it('should mark tx as broadcasted if accepted but already in blockchain', function(done) { - blockchainExplorer.broadcast = sinon.stub().callsArgWith(1, 'broadcast error'); - blockchainExplorer.getTransaction = sinon.stub().callsArgWith(1, null, { - txid: '999' - }); - server.broadcastTx({ - txProposalId: txpid - }, function(err) { - should.not.exist(err); - server.getTx({ + it('should keep tx as accepted if broadcast fails and cannot check tx in blockchain', function(done) { + blockchainExplorer.broadcast = sinon.stub().callsArgWith(1, 'broadcast error'); + blockchainExplorer.getTransaction = sinon.stub().callsArgWith(1, 'bc check error'); + server.broadcastTx({ txProposalId: txpid - }, function(err, txp) { - should.not.exist(err); - should.exist(txp.txid); - txp.isBroadcasted().should.be.true; - should.exist(txp.broadcastedOn); - done(); + }, function(err) { + should.exist(err); + err.toString().should.equal('bc check error'); + server.getTx({ + txProposalId: txpid + }, function(err, txp) { + should.not.exist(err); + should.exist(txp.txid); + txp.isBroadcasted().should.be.false; + should.not.exist(txp.broadcastedOn); + txp.isAccepted().should.be.true; + done(); + }); }); }); }); - it('should keep tx as accepted if broadcast fails and cannot check tx in blockchain', function(done) { - blockchainExplorer.broadcast = sinon.stub().callsArgWith(1, 'broadcast error'); - blockchainExplorer.getTransaction = sinon.stub().callsArgWith(1, 'bc check error'); - server.broadcastTx({ - txProposalId: txpid - }, function(err) { - should.exist(err); - err.toString().should.equal('bc check error'); - server.getTx({ + describe('New', function() { + beforeEach(function(done) { + helpers.createAndJoinWallet(1, 1, function(s, w) { + server = s; + wallet = w; + helpers.stubUtxos(server, wallet, [10, 10], function() { + var txOpts = { + outputs: [{ + toAddress: '18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', + amount: 9e8, + }], + message: 'some message', + }; + helpers.createAndPublishTx(server, txOpts, TestData.copayers[0].privKey_1H_0, function(txp) { + should.exist(txp); + var signatures = helpers.clientSign(txp, TestData.copayers[0].xPrivKey_44H_0H_0H); + server.signTx({ + txProposalId: txp.id, + signatures: signatures, + }, function(err, txp) { + should.not.exist(err); + should.exist(txp); + txp.isAccepted().should.be.true; + txp.isBroadcasted().should.be.false; + txid = txp.txid; + txpid = txp.id; + done(); + }); + }); + }); + }); + }); + + it('should broadcast a tx', function(done) { + var clock = sinon.useFakeTimers(1234000, 'Date'); + helpers.stubBroadcast(); + server.broadcastTx({ txProposalId: txpid - }, function(err, txp) { + }, function(err) { should.not.exist(err); - should.exist(txp.txid); - txp.isBroadcasted().should.be.false; - should.not.exist(txp.broadcastedOn); - txp.isAccepted().should.be.true; - done(); + server.getTx({ + txProposalId: txpid + }, function(err, txp) { + should.not.exist(err); + should.not.exist(txp.raw); + txp.txid.should.equal(txid); + txp.isBroadcasted().should.be.true; + txp.broadcastedOn.should.equal(1234); + clock.restore(); + done(); + }); }); }); + }); });