Skip to content
This repository has been archived by the owner on Apr 15, 2019. It is now read-only.

Commit

Permalink
Merge pull request #743 from LiskHQ/720-fix-voting-status-update
Browse files Browse the repository at this point in the history
Fix voting status update race condition - Closes #720
  • Loading branch information
slaweet authored Sep 14, 2017
2 parents e47b779 + 51c4d52 commit 6129374
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 18 deletions.
6 changes: 0 additions & 6 deletions src/actions/voting.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { vote } from '../utils/api/delegate';
import { transactionAdded } from './transactions';
import { errorAlertDialogDisplayed } from './dialog';
import Fees from '../constants/fees';
import { SYNC_ACTIVE_INTERVAL } from '../constants/api';

/**
* Add pending variable to the list of voted delegates and list of unvoted delegates
Expand Down Expand Up @@ -46,11 +45,6 @@ export const votePlaced = ({ activePeer, account, votedList, unvotedList, second
fee: Fees.vote,
type: 3,
}));

// fire second action
setTimeout(() => {
dispatch(clearVoteLists());
}, SYNC_ACTIVE_INTERVAL);
})
.catch((error) => {
const text = error && error.message ? `${error.message}.` : 'An error occurred while placing your vote.';
Expand Down
10 changes: 0 additions & 10 deletions src/actions/voting.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,16 +104,6 @@ describe('actions: voting', () => {
expect(dispatch).to.have.been.calledWith(transactionAdded(expectedAction));
});

it('should dispatch clearVoteLists action if resolved', () => {
delegateApiMock.returnsPromise().resolves({ transactionId: '15626650747375562521' });
const clock = sinon.useFakeTimers();

actionFunction(dispatch);
clock.tick(10000);
expect(dispatch).to.have.property('callCount', 3);
clock.restore();
});

it('should dispatch errorAlertDialogDisplayed action if caught', () => {
delegateApiMock.returnsPromise().rejects({ message: 'sample message' });

Expand Down
23 changes: 21 additions & 2 deletions src/store/middlewares/account.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { getAccountStatus, getAccount, transactions } from '../../utils/api/acco
import { accountUpdated, accountLoggedIn } from '../../actions/account';
import { transactionsUpdated } from '../../actions/transactions';
import { activePeerUpdate } from '../../actions/peers';
import { clearVoteLists } from '../../actions/voting';
import actionTypes from '../../constants/actions';
import { fetchAndUpdateForgedBlocks } from '../../actions/forging';
import { getDelegate } from '../../utils/api/delegate';
Expand Down Expand Up @@ -37,9 +38,17 @@ const updateAccountData = (store) => { // eslint-disable-line
});
};

const getRecentTransactionOfType = (transactionsList, type) => (
transactionsList.filter(transaction => (
transaction.type === type &&
// limit the number of confirmations to 5 to not fire each time there is another new transaction
// theoretically even less then 5, but just to be on the safe side
transaction.confirmations < 5))[0]
);

const delegateRegistration = (store, action) => {
const delegateRegistrationTx = action.data.confirmed.filter(
transaction => transaction.type === transactionTypes.registerDelegate)[0];
const delegateRegistrationTx = getRecentTransactionOfType(
action.data.confirmed, transactionTypes.registerDelegate);
const state = store.getState();

if (delegateRegistrationTx) {
Expand All @@ -51,6 +60,15 @@ const delegateRegistration = (store, action) => {
}
};

const votePlaced = (store, action) => {
const voteTransaction = getRecentTransactionOfType(
action.data.confirmed, transactionTypes.vote);

if (voteTransaction) {
store.dispatch(clearVoteLists());
}
};

const accountMiddleware = store => next => (action) => {
next(action);
switch (action.type) {
Expand All @@ -59,6 +77,7 @@ const accountMiddleware = store => next => (action) => {
break;
case actionTypes.transactionsUpdated:
delegateRegistration(store, action);
votePlaced(store, action);
break;
default: break;
}
Expand Down
8 changes: 8 additions & 0 deletions src/store/middlewares/account.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import * as accountApi from '../../utils/api/account';
import * as delegateApi from '../../utils/api/delegate';
import actionTypes from '../../constants/actions';
import transactionTypes from '../../constants/transactionTypes';
import { clearVoteLists } from '../../actions/voting';

describe('Account middleware', () => {
let store;
Expand All @@ -15,6 +16,7 @@ describe('Account middleware', () => {
data: {
confirmed: [{
type: transactionTypes.registerDelegate,
confirmations: 1,
}],
},
};
Expand Down Expand Up @@ -104,5 +106,11 @@ describe('Account middleware', () => {

delegateApiMock.restore();
});

it(`should dispatch clearVoteLists action on ${actionTypes.transactionsUpdated} action if action.data.confirmed contains delegateRegistration transactions`, () => {
transactionsUpdatedAction.data.confirmed[0].type = transactionTypes.vote;
middleware(store)(next)(transactionsUpdatedAction);
expect(store.dispatch).to.have.been.calledWith(clearVoteLists());
});
});

0 comments on commit 6129374

Please sign in to comment.