Browse Source

split sign & broadcast

activeAddress
Ivan Socolsky 10 years ago
parent
commit
b0b6de0d02
  1. 19
      lib/server.js
  2. 215
      test/integration/server.js

19
lib/server.js

@ -695,24 +695,9 @@ WalletService.prototype.signTx = function(opts, cb) {
self._notify('TxProposalFinallyAccepted', {
txProposalId: opts.txProposalId,
});
self._broadcastTx(txp, function(err, txid) {
if (err) return cb(err);
txp.setBroadcasted(txid);
self.storage.storeTx(self.walletId, txp, function(err) {
if (err) return cb(err);
self._notify('NewOutgoingTx', {
txProposalId: opts.txProposalId,
txid: txid
});
return cb(null, txp);
});
});
} else {
return cb(null, txp);
}
return cb(null, txp);
});
});
});

215
test/integration/server.js

@ -1085,85 +1085,6 @@ describe('Copay server', function() {
});
});
});
});
describe('#signTx and broadcast', function() {
var server, wallet;
beforeEach(function(done) {
helpers.createAndJoinWallet(1, 1, function(s, w) {
server = s;
wallet = w;
helpers.stubUtxos(server, wallet, _.range(1, 9), function() {
done();
});
});
});
it('should sign and broadcast a tx', function(done) {
helpers.stubBroadcast('1122334455');
var txOpts = helpers.createProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 10, null, TestData.copayers[0].privKey);
server.createTx(txOpts, function(err, txp) {
should.not.exist(err);
txp.should.exist;
var txpid = txp.id;
server.getPendingTxs({}, function(err, txps) {
var txp = txps[0];
txp.id.should.equal(txpid);
var signatures = helpers.clientSign(txp, TestData.copayers[0].xPrivKey);
server.signTx({
txProposalId: txpid,
signatures: signatures,
}, function(err, txp) {
should.not.exist(err);
txp.status.should.equal('broadcasted');
txp.txid.should.equal('1122334455');
server.getTx({
id: txp.id
}, function(err, txp) {
txp.actions.length.should.equal(1);
txp.actions[0].copayerId.should.equal(wallet.copayers[0].id);
txp.actions[0].copayerName.should.equal(wallet.copayers[0].name);
done();
});
});
});
});
});
it('should keep tx as *accepted* if unable to broadcast it', function(done) {
helpers.stubBroadcastFail();
var txOpts = helpers.createProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 10, null, TestData.copayers[0].privKey);
server.createTx(txOpts, function(err, txp) {
should.not.exist(err);
txp.should.exist;
var txpid = txp.id;
server.getPendingTxs({}, function(err, txps) {
var txp = txps[0];
txp.id.should.equal(txpid);
var signatures = helpers.clientSign(txp, TestData.copayers[0].xPrivKey);
server.signTx({
txProposalId: txpid,
signatures: signatures,
}, function(err, txp) {
err.should.contain('broadcast');
server.getPendingTxs({}, function(err, txps) {
should.not.exist(err);
txps.length.should.equal(1);
var txp = txps[0];
txp.status.should.equal('accepted');
should.not.exist(txp.txid);
done();
});
});
});
});
});
});
describe('Tx proposal workflow', function() {
@ -1196,7 +1117,7 @@ describe('Copay server', function() {
});
});
it('tx proposals should not be broadcast until quorum is reached', function(done) {
it('tx proposals should not be finally accepted until quorum is reached', function(done) {
var txpId;
async.waterfall([
@ -1234,12 +1155,18 @@ describe('Copay server', function() {
txps.length.should.equal(1);
var txp = txps[0];
txp.isPending().should.be.true;
txp.isRejected().should.be.false;
txp.isAccepted().should.be.false;
txp.isRejected().should.be.false;
txp.isBroadcasted().should.be.false;
txp.actions.length.should.equal(1);
var action = txp.getActionBy(wallet.copayers[0].id);
action.type.should.equal('accept');
next(null, txp);
server.getNotifications({}, function(err, notifications) {
should.not.exist(err);
var last = _.last(notifications);
last.type.should.not.equal('TxProposalFinallyAccepted');
next(null, txp);
});
});
},
function(txp, next) {
@ -1257,22 +1184,20 @@ describe('Copay server', function() {
function(next) {
server.getPendingTxs({}, function(err, txps) {
should.not.exist(err);
txps.length.should.equal(0);
next();
});
},
function(next) {
server.getTx({
id: txpId
}, function(err, txp) {
should.not.exist(err);
txp.isPending().should.be.false;
txp.isRejected().should.be.false;
txps.length.should.equal(1);
var txp = txps[0];
txp.isPending().should.be.true;
txp.isAccepted().should.be.true;
txp.isBroadcasted().should.be.true;
txp.txid.should.equal('999');
txp.isBroadcasted().should.be.false;
should.not.exist(txp.txid);
txp.actions.length.should.equal(2);
done();
server.getNotifications({}, function(err, notifications) {
should.not.exist(err);
var last = _.last(notifications);
last.type.should.equal('TxProposalFinallyAccepted');
last.data.txProposalId.should.equal(txp.id);
done();
});
});
},
]);
@ -1553,25 +1478,31 @@ describe('Copay server', function() {
server.getPendingTxs({}, function(err, txs) {
var tx = txs[2];
var signatures = helpers.clientSign(tx, TestData.copayers[0].xPrivKey);
helpers.stubBroadcast('1122334455');
sinon.spy(server, 'emit');
server.signTx({
txProposalId: tx.id,
signatures: signatures,
}, function(err) {
server.getNotifications({
limit: 3,
reverse: true,
}, function(err, notifications) {
should.not.exist(err);
helpers.stubBroadcast('1122334455');
server.broadcastTx({
txProposalId: tx.id
}, function(err, txid) {
should.not.exist(err);
var types = _.pluck(notifications, 'type');
types.should.deep.equal(['NewOutgoingTx', 'TxProposalFinallyAccepted', 'TxProposalAcceptedBy']);
// Check also events
server.emit.getCall(0).args[0].type.should.equal('TxProposalAcceptedBy');
server.emit.getCall(1).args[0].type.should.equal('TxProposalFinallyAccepted');;
server.emit.getCall(2).args[0].type.should.equal('NewOutgoingTx');
server.getNotifications({
limit: 3,
reverse: true,
}, function(err, notifications) {
should.not.exist(err);
var types = _.pluck(notifications, 'type');
types.should.deep.equal(['NewOutgoingTx', 'TxProposalFinallyAccepted', 'TxProposalAcceptedBy']);
// Check also events
server.emit.getCall(0).args[0].type.should.equal('TxProposalAcceptedBy');
server.emit.getCall(1).args[0].type.should.equal('TxProposalFinallyAccepted');;
server.emit.getCall(2).args[0].type.should.equal('NewOutgoingTx');
done();
done();
});
});
});
});
@ -1860,44 +1791,50 @@ describe('Copay server', function() {
should.not.exist(err);
should.exist(tx);
helpers.stubBroadcast('1122334455');
var signatures = helpers.clientSign(tx, TestData.copayers[0].xPrivKey);
server.signTx({
txProposalId: tx.id,
signatures: signatures,
}, function(err, tx) {
should.not.exist(err);
var txs = [{
txid: '1122334455',
confirmations: 1,
fees: 5460,
minedTs: 1,
inputs: [{
address: tx.inputs[0].address,
amount: utxos[0].satoshis,
}],
outputs: [{
address: 'external',
amount: helpers.toSatoshi(80) - 5460,
}, {
address: changeAddresses[0].address,
amount: helpers.toSatoshi(20) - 5460,
}],
}];
helpers.stubHistory(txs);
server.getTxHistory({}, function(err, txs) {
helpers.stubBroadcast('1122334455');
server.broadcastTx({
txProposalId: tx.id
}, function(err, txid) {
should.not.exist(err);
should.exist(txs);
txs.length.should.equal(1);
var tx = txs[0];
tx.action.should.equal('sent');
tx.amount.should.equal(helpers.toSatoshi(80));
tx.message.should.equal('some message');
tx.actions.length.should.equal(1);
tx.actions[0].type.should.equal('accept');
tx.actions[0].copayerName.should.equal('copayer 1');
done();
var txs = [{
txid: '1122334455',
confirmations: 1,
fees: 5460,
minedTs: 1,
inputs: [{
address: tx.inputs[0].address,
amount: utxos[0].satoshis,
}],
outputs: [{
address: 'external',
amount: helpers.toSatoshi(80) - 5460,
}, {
address: changeAddresses[0].address,
amount: helpers.toSatoshi(20) - 5460,
}],
}];
helpers.stubHistory(txs);
server.getTxHistory({}, function(err, txs) {
should.not.exist(err);
should.exist(txs);
txs.length.should.equal(1);
var tx = txs[0];
tx.action.should.equal('sent');
tx.amount.should.equal(helpers.toSatoshi(80));
tx.message.should.equal('some message');
tx.actions.length.should.equal(1);
tx.actions[0].type.should.equal('accept');
tx.actions[0].copayerName.should.equal('copayer 1');
done();
});
});
});
});

Loading…
Cancel
Save