-
Notifications
You must be signed in to change notification settings - Fork 96
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #3884 from LiskHQ/3736-add-use-max
Add "use maximum amount for voting" button to edit vote dialog- Closes #3736
- Loading branch information
Showing
21 changed files
with
321 additions
and
123 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
import { getTransactionFee } from '@api/transaction'; | ||
import { | ||
VOTE_AMOUNT_STEP, | ||
MIN_ACCOUNT_BALANCE, | ||
MODULE_ASSETS_NAME_ID_MAP, | ||
} from '@constants'; | ||
import { toRawLsk } from '@utils/lsk'; | ||
import { normalizeVotesForTx, getNumberOfSignatures } from '@shared/transactionPriority'; | ||
|
||
/** | ||
* Calculates the maximum vote amount possible. It | ||
* Takes the current votes, minimum account balance and | ||
* transaction fee into account. | ||
* | ||
* @param {object} account - Lisk account info from the Redux store | ||
* @param {object} network - Network info from the Redux store | ||
* @param {object} transaction - Raw transaction object | ||
* @param {object} voting - List of votes from the Redux store | ||
* @returns {Number} - Maximum possible vote amount | ||
*/ | ||
const getMaxAmount = async (account, network, voting, address) => { | ||
const balance = account.summary?.balance ?? 0; | ||
const totalUnconfirmedVotes = Object.values(voting) | ||
.filter(vote => vote.confirmed < vote.unconfirmed) | ||
.map(vote => vote.unconfirmed - vote.confirmed) | ||
.reduce((total, amount) => (total + amount), 0); | ||
|
||
const maxVoteAmount = Math.floor( | ||
(balance - totalUnconfirmedVotes - MIN_ACCOUNT_BALANCE) / 1e9, | ||
) * 1e9; | ||
|
||
const transaction = { | ||
fee: 1e6, | ||
votes: normalizeVotesForTx({ | ||
...voting, | ||
[address]: { | ||
confirmed: voting[address] ? voting[address].confirmed : 0, | ||
unconfirmed: maxVoteAmount, | ||
}, | ||
}), | ||
nonce: account.sequence?.nonce, | ||
senderPublicKey: account.summary?.publicKey, | ||
moduleAssetId: MODULE_ASSETS_NAME_ID_MAP.voteDelegate, | ||
}; | ||
|
||
const maxAmountFee = await getTransactionFee({ | ||
token: 'LSK', | ||
account, | ||
network, | ||
transaction, | ||
selectedPriority: { title: 'Normal', value: 0, selectedIndex: 0 }, // Always set to LOW | ||
numberOfSignatures: getNumberOfSignatures(account), | ||
}, 'LSK'); | ||
|
||
// If the "sum of vote amounts + fee + dust" exceeds balance | ||
// return 10 LSK less, since votes must be multiplications of 10 LSK. | ||
if ((maxVoteAmount + toRawLsk(maxAmountFee.value)) <= ( | ||
balance - totalUnconfirmedVotes - MIN_ACCOUNT_BALANCE)) { | ||
return maxVoteAmount; | ||
} | ||
return maxVoteAmount - VOTE_AMOUNT_STEP; | ||
}; | ||
|
||
export default getMaxAmount; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
import getMaxAmount from './getMaxAmount'; | ||
import accounts from '../../../../test/constants/accounts'; | ||
|
||
const account = { | ||
...accounts.genesis, | ||
summary: { | ||
...accounts.genesis.summary, | ||
balance: 100.106e8, | ||
}, | ||
}; | ||
const network = { | ||
network: { | ||
networks: { | ||
LSK: { | ||
networkIdentifier: '15f0dacc1060e91818224a94286b13aa04279c640bd5d6f193182031d133df7c', | ||
moduleAssets: [ | ||
{ | ||
id: '2:0', | ||
name: 'token:transfer', | ||
}, | ||
{ | ||
id: '4:0', | ||
name: 'keys:registerMultisignatureGroup', | ||
}, | ||
{ | ||
id: '5:0', | ||
name: 'dpos:registerDelegate', | ||
}, | ||
{ | ||
id: '5:1', | ||
name: 'dpos:voteDelegate', | ||
}, | ||
{ | ||
id: '5:2', | ||
name: 'dpos:unlockToken', | ||
}, | ||
{ | ||
id: '5:3', | ||
name: 'dpos:reportDelegateMisbehavior', | ||
}, | ||
{ | ||
id: '1000:0', | ||
name: 'legacyAccount:reclaimLSK', | ||
}, | ||
], | ||
serviceUrl: 'https://testnet-service.lisk.com', | ||
}, | ||
}, | ||
name: 'testnet', | ||
}, | ||
}; | ||
const voting = { | ||
voting: { | ||
[accounts.genesis.summary.address]: { | ||
confirmed: 20e8, | ||
unconfirmed: 20e8, | ||
username: 'genesis', | ||
}, | ||
}, | ||
}; | ||
|
||
jest.mock('@api/transaction', () => ({ | ||
getTransactionFee: jest.fn().mockImplementation(() => Promise.resolve({ value: '0.046' })), | ||
})); | ||
|
||
jest.mock('@actions/voting', () => ({ | ||
voteEdited: jest.fn(), | ||
})); | ||
|
||
describe('getMaxAmount', () => { | ||
it('Returns 10n LSK if: balance >= (10n LSK + fee + dust)', async () => { | ||
const result = await getMaxAmount(account, network, voting, accounts.genesis.summary.address); | ||
expect(result).toBe(1e10); | ||
}); | ||
|
||
it('Returns (n-1) * 10 LSK if: 10n LSK < balance < (10n LSK + fee + dust)', async () => { | ||
const acc = { | ||
...accounts.genesis, | ||
summary: { | ||
...accounts.genesis.summary, | ||
balance: 1e10, | ||
}, | ||
}; | ||
const result = await getMaxAmount(acc, network, voting, accounts.genesis.summary.address); | ||
expect(result).toBe(9e9); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.