Skip to content
This repository has been archived by the owner on Jun 11, 2024. It is now read-only.

Commit

Permalink
Merge pull request #625 from LiskHQ/duplicate-vote-fix
Browse files Browse the repository at this point in the history
Duplicate vote fix
  • Loading branch information
Isabella Dell authored Jun 23, 2017
2 parents 5e84693 + b804daa commit 60b5b6e
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 15 deletions.
8 changes: 8 additions & 0 deletions logic/transactionPool.js
Original file line number Diff line number Diff line change
Expand Up @@ -723,6 +723,14 @@ __private.processVerifyTransaction = function (transaction, broadcast, cb) {
}
});
},
function normalizeTransaction (sender, waterCb) {
try {
transaction = library.logic.transaction.objectNormalize(transaction);
return setImmediate(waterCb, null, sender);
} catch (err) {
return setImmediate(waterCb, err);
}
},
function verifyTransaction (sender, waterCb) {
library.logic.transaction.verify(transaction, sender, function (err) {
if (err) {
Expand Down
6 changes: 6 additions & 0 deletions logic/vote.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ var async = require('async');
var constants = require('../helpers/constants.js');
var exceptions = require('../helpers/exceptions.js');
var Diff = require('../helpers/diff.js');
var _ = require('lodash');

// Private fields
var modules, library, self;
Expand Down Expand Up @@ -107,6 +108,11 @@ Vote.prototype.verify = function (trs, sender, cb) {
if (err) {
return setImmediate(cb, err);
} else {

if (trs.asset.votes.length > _.uniqBy(trs.asset.votes, function (v) { return v.slice(1); }).length) {
return setImmediate(cb, 'Multiple votes for same delegate are not allowed');
}

return self.checkConfirmedDelegates(trs, cb);
}
});
Expand Down
27 changes: 14 additions & 13 deletions test/api/delegates.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,40 +102,41 @@ describe('PUT /api/accounts/delegates with funds', function () {
});

it('when upvoting same delegate multiple times should fail', function (done) {
var votedDelegate = '"+' + node.eAccount.publicKey + '","+' + node.eAccount.publicKey + '"';
var votedDelegate = Array(2).fill('+' + node.eAccount.publicKey);

putAccountsDelegates({
secret: account.password,
delegates: [votedDelegate]
delegates: votedDelegate
}, function (err, res) {
node.expect(res.body).to.have.property('success').to.be.not.ok;
node.expect(res.body).to.have.property('error');
node.expect(res.body).to.have.property('error').to.include('Failed to validate vote schema:');
done();
});
});

it('when downvoting same delegate multiple times should fail', function (done) {
var votedDelegate = '"+' + node.eAccount.publicKey + '","+' + node.eAccount.publicKey + '"';
var votedDelegate = Array(2).fill('-' + node.eAccount.publicKey);

putAccountsDelegates({
secret: account.password,
delegates: [votedDelegate]
delegates: votedDelegate
}, function (err, res) {
node.expect(res.body).to.have.property('success').to.be.not.ok;
node.expect(res.body).to.have.property('error');
node.expect(res.body).to.have.property('error').to.include('Failed to validate vote schema:');
done();
});
});

it('when upvoting and downvoting within same request should fail', function (done) {
var votedDelegate = '"+' + node.eAccount.publicKey + '","-' + node.eAccount.publicKey + '"';
var votedDelegate = ['-' + node.eAccount.publicKey, '+' + node.eAccount.publicKey];

putAccountsDelegates({
secret: account.password,
delegates: [votedDelegate]
delegates: votedDelegate
}, function (err, res) {
node.expect(res.body).to.have.property('success').to.be.not.ok;
node.expect(res.body).to.have.property('error');
node.expect(res.body).to.have.property('error').to.equal('Multiple votes for same delegate are not allowed');
done();
});
});
Expand Down Expand Up @@ -200,7 +201,7 @@ describe('PUT /api/accounts/delegates with funds', function () {
delegates: ['+' + node.eAccount.publicKey]
}, function (err, res) {
node.expect(res.body).to.have.property('success').to.be.not.ok;
node.expect(res.body).to.have.property('error');
node.expect(res.body).to.have.property('error').to.include('String is too short ');
done();
});
});
Expand All @@ -211,7 +212,7 @@ describe('PUT /api/accounts/delegates with funds', function () {
delegates: ['-' + node.eAccount.publicKey]
}, function (err, res) {
node.expect(res.body).to.have.property('success').to.be.not.ok;
node.expect(res.body).to.have.property('error');
node.expect(res.body).to.have.property('error').to.include('String is too short ');
done();
});
});
Expand All @@ -222,7 +223,7 @@ describe('PUT /api/accounts/delegates with funds', function () {
delegates: ['+']
}, function (err, res) {
node.expect(res.body).to.have.property('success').to.be.not.ok;
node.expect(res.body).to.have.property('error');
node.expect(res.body).to.have.property('error').to.include('Invalid vote format');
done();
});
});
Expand All @@ -233,7 +234,7 @@ describe('PUT /api/accounts/delegates with funds', function () {
delegates: ['-']
}, function (err, res) {
node.expect(res.body).to.have.property('success').to.be.not.ok;
node.expect(res.body).to.have.property('error');
node.expect(res.body).to.have.property('error').to.include('Invalid vote format');
done();
});
});
Expand All @@ -244,7 +245,7 @@ describe('PUT /api/accounts/delegates with funds', function () {
delegates: ''
}, function (err, res) {
node.expect(res.body).to.have.property('success').to.be.not.ok;
node.expect(res.body).to.have.property('error');
node.expect(res.body).to.have.property('error').to.equal('Failed to validate vote schema: Expected type array but found type string');
done();
});
});
Expand Down
2 changes: 0 additions & 2 deletions test/api/multisignatures.js
Original file line number Diff line number Diff line change
Expand Up @@ -357,14 +357,12 @@ describe('GET /api/multisignatures/pending', function () {
node.expect(pending.transaction).to.have.property('type').that.is.equal(node.txTypes.MULTI);
node.expect(pending.transaction).to.have.property('amount').that.is.equal(0);
node.expect(pending.transaction).to.have.property('senderPublicKey').that.is.equal(multisigAccount.publicKey);
node.expect(pending.transaction).to.have.property('requesterPublicKey').that.is.null;
node.expect(pending.transaction).to.have.property('timestamp').that.is.a('number');
node.expect(pending.transaction).to.have.property('asset').that.is.an('object');
node.expect(pending.transaction.asset).to.have.property('multisignature').that.is.an('object');
node.expect(pending.transaction.asset.multisignature).to.have.property('min').that.is.a('number');
node.expect(pending.transaction.asset.multisignature).to.have.property('keysgroup').that.is.an('array');
node.expect(pending.transaction.asset.multisignature).to.have.property('lifetime').that.is.a('number');
node.expect(pending.transaction).to.have.property('recipientId').that.is.null;
node.expect(pending.transaction).to.have.property('signature').that.is.a('string');
node.expect(pending.transaction).to.have.property('id').that.is.equal(multiSigTx.txId);
node.expect(pending.transaction).to.have.property('fee').that.is.equal(node.fees.multisignatureRegistrationFee * (Keys.length + 1));
Expand Down

0 comments on commit 60b5b6e

Please sign in to comment.