From 74c8b341884a846fd97b5948eeebcc3c4dd6a68e Mon Sep 17 00:00:00 2001 From: Matias Alejo Garcia Date: Thu, 11 Jun 2015 16:39:21 -0300 Subject: [PATCH] allow delete proposals after 24hrs --- lib/server.js | 17 +++++++------ test/integration/server.js | 51 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 59 insertions(+), 9 deletions(-) diff --git a/lib/server.js b/lib/server.js index a0a3a0d..13f7831 100644 --- a/lib/server.js +++ b/lib/server.js @@ -32,6 +32,7 @@ var blockchainExplorerOpts; var messageBroker; + /** * Creates an instance of the Bitcore Wallet Service. * @constructor @@ -865,14 +866,15 @@ WalletService.prototype.removePendingTx = function(opts, cb) { if (!txp.isPending()) return cb(new ClientError('TXNOTPENDING', 'Transaction proposal not pending')); + var now = Math.floor(Date.now() / 1000); + if (now - txp.createdOn < WalletService.lockTimeoutHours * 3600) { + var actors = txp.getActors(); + if (txp.creatorId !== self.copayerId) + return cb(new ClientError('Only creators can remove pending proposals during locktime')); - if (txp.creatorId !== self.copayerId) - return cb(new ClientError('Only creators can remove pending proposals')); - - var actors = txp.getActors(); - - if (actors.length > 1 || (actors.length == 1 && actors[0] !== self.copayerId)) - return cb(new ClientError('TXACTIONED', 'Cannot remove a proposal signed/rejected by other copayers')); + if (actors.length > 1 || (actors.length == 1 && actors[0] !== self.copayerId)) + return cb(new ClientError('TXACTIONED', 'Cannot remove a proposal signed/rejected by other copayers during locktime')); + } self._notify('TxProposalRemoved', {}, function() { self.storage.removeTx(self.walletId, txp.id, cb); @@ -1318,6 +1320,7 @@ WalletService.prototype.getTxHistory = function(opts, cb) { }); }; +WalletService.lockTimeoutHours = 24; WalletService.scanConfig = { SCAN_WINDOW: 20, diff --git a/test/integration/server.js b/test/integration/server.js index 78b759e..2d82fe8 100644 --- a/test/integration/server.js +++ b/test/integration/server.js @@ -2656,6 +2656,7 @@ describe('Wallet service', function() { }); }); }); + it('should allow creator to remove an unsigned TX', function(done) { server.removePendingTx({ @@ -2669,7 +2670,7 @@ describe('Wallet service', function() { }); }); - it('should allow creator to remove an signed TX by himself', function(done) { + it('should allow creator to remove a signed TX by himself', function(done) { var signatures = helpers.clientSign(txp, TestData.copayers[0].xPrivKey); server.signTx({ txProposalId: txp.id, @@ -2754,7 +2755,7 @@ describe('Wallet service', function() { }); }); - it('should not allow creator copayer to remove an TX signed by other copayer', function(done) { + it('should not allow creator copayer to remove a TX signed by other copayer, in less than 24hrs', function(done) { helpers.getAuthServer(wallet.copayers[1].id, function(server2) { var signatures = helpers.clientSign(txp, TestData.copayers[1].xPrivKey); server2.signTx({ @@ -2772,6 +2773,52 @@ describe('Wallet service', function() { }); }); }); + + + it('should allow creator copayer to remove a TX signed by other copayer, after 24hrs', function(done) { + helpers.getAuthServer(wallet.copayers[1].id, function(server2) { + var signatures = helpers.clientSign(txp, TestData.copayers[1].xPrivKey); + server2.signTx({ + txProposalId: txp.id, + signatures: signatures, + }, function(err) { + should.not.exist(err); + + var clock = sinon.useFakeTimers(Date.now()+1+24*3600*1000); + server.removePendingTx({ + txProposalId: txp.id + }, function(err) { + should.not.exist(err); + clock.restore(); + done(); + }); + }); + }); + }); + + + it('should allow other copayer to remove a TX signed, after 24hrs', function(done) { + helpers.getAuthServer(wallet.copayers[1].id, function(server2) { + var signatures = helpers.clientSign(txp, TestData.copayers[1].xPrivKey); + server2.signTx({ + txProposalId: txp.id, + signatures: signatures, + }, function(err) { + should.not.exist(err); + + var clock = sinon.useFakeTimers(Date.now()+1+24*3600*1000); + server2.removePendingTx({ + txProposalId: txp.id + }, function(err) { + should.not.exist(err); + clock.restore(); + done(); + }); + }); + }); + }); + + }); describe('#getTxHistory', function() {