From 60ceec2be832417119a8ca1362b9cc0539ca5eef Mon Sep 17 00:00:00 2001 From: Jordan Bibla Date: Fri, 15 Mar 2019 15:21:15 -0400 Subject: [PATCH 01/14] fixed sorting on validator table, cleaned up data on li validator --- .../components/staking/LiValidator.vue | 42 +++++-------------- .../components/staking/PageValidator.vue | 9 ++-- .../components/staking/TableValidators.vue | 39 +++++++---------- 3 files changed, 29 insertions(+), 61 deletions(-) diff --git a/app/src/renderer/components/staking/LiValidator.vue b/app/src/renderer/components/staking/LiValidator.vue index 11ae7ae6cb..61c1e37189 100644 --- a/app/src/renderer/components/staking/LiValidator.vue +++ b/app/src/renderer/components/staking/LiValidator.vue @@ -7,7 +7,7 @@ class="data-table__row__info__image" width="48" height="48" - > + /> + />
- {{ - yourVotes.isLessThan(0.01) && yourVotes.isGreaterThan(0) - ? num.shortNumber(0.01) - : num.shortNumber(yourVotes) - }} - - - {{ rewards || "--" }} + {{ yourVotes.isGreaterThan(0) ? num.shortNumber(yourVotes) : `--` }} - {{ validator.percent_of_vote ? validator.percent_of_vote : `--` }} - - - {{ uptime }} + {{ + validator.percent_of_vote + ? num.percent(validator.percent_of_vote) + : `--` + }} - {{ commission }} + {{ validator.commission ? num.percent(validator.commission) : `--` }} - - -- + + {{ validator.uptime ? num.percent(validator.uptime) : `--` }} @@ -95,20 +89,6 @@ export default { `session`, `lastHeader` ]), - commission() { - return `${this.num.pretty(this.validator.commission.rate)}%` - }, - uptime() { - const rollingWindow = 10000 // param of slashing period - const info = this.validator.signing_info - if (info) { - // uptime in the past 10k blocks - const uptimeRollingWindow = - (rollingWindow - info.missed_blocks_counter) / rollingWindow - return num.percent(uptimeRollingWindow) - } - return `--` - }, yourVotes() { return this.committedDelegations[this.validator.operator_address] ? BigNumber( diff --git a/app/src/renderer/components/staking/PageValidator.vue b/app/src/renderer/components/staking/PageValidator.vue index 696e813344..c404c5a6df 100644 --- a/app/src/renderer/components/staking/PageValidator.vue +++ b/app/src/renderer/components/staking/PageValidator.vue @@ -14,11 +14,11 @@ v-if="validator.keybase" :src="validator.keybase.avatarUrl" class="avatar" - > + />
@@ -87,10 +87,7 @@ {{ percent(validator.commission.rate) }} -
+
Slashes
--
diff --git a/app/src/renderer/components/staking/TableValidators.vue b/app/src/renderer/components/staking/TableValidators.vue index b365ad1d50..ec042e7bc7 100644 --- a/app/src/renderer/components/staking/TableValidators.vue +++ b/app/src/renderer/components/staking/TableValidators.vue @@ -39,9 +39,10 @@ export default { num: num, query: ``, sort: { - property: `percent_of_vote`, - order: `desc` - } + property: `commission`, + order: `asc` + }, + rollingWindow: 10000 // param of slashing period }), computed: { ...mapGetters([ @@ -68,19 +69,21 @@ export default { return this.validators.map(v => Object.assign({}, v, { small_moniker: v.description.moniker.toLowerCase(), - percent_of_vote: num.percent(v.voting_power / this.vpTotal), + percent_of_vote: v.voting_power / this.vpTotal, your_votes: this.num.full( calculateTokens(v, this.committedDelegations[v.id]) ), - keybase: this.keybase[v.description.identity] + commission: v.commission.rate, + keybase: this.keybase[v.description.identity], + uptime: v.signing_info ? (this.rollingWindow - v.signing_info.missed_blocks_counter) / this.rollingWindow : 0 }) ) }, sortedEnrichedDelegates() { return orderBy( this.enrichedDelegates.slice(0), - [this.sort.property, `small_moniker`], - [this.sort.order, `asc`] + [this.sort.property], + [this.sort.order] ) }, userCanDelegate() { @@ -102,24 +105,12 @@ export default { } you have delegated to this validator`, class: `your-votes` }, - { - title: `Rewards`, - value: `your_rewards`, // TODO: use real rewards - tooltip: `Rewards you have earned from this validator`, - class: `your-rewards` - }, { title: `Voting Power`, value: `percent_of_vote`, tooltip: `Percentage of voting shares`, class: `percent_of_vote` }, - { - title: `Uptime`, - value: `uptime`, - tooltip: `Ratio of blocks signed within the last 10k blocks`, - class: `uptime` - }, { title: `Commission`, value: `commission`, @@ -127,11 +118,11 @@ export default { class: `commission` }, { - title: `Slashes`, - value: `slashes`, // TODO: use real slashes - tooltip: `The validator's slashes`, - class: `slashes` - } + title: `Uptime`, + value: `uptime`, + tooltip: `Ratio of blocks signed within the last 10k blocks`, + class: `uptime` + }, ] } }, From e86fecaa20792c84540d246f8fb3f003ef667fca Mon Sep 17 00:00:00 2001 From: Jordan Bibla Date: Fri, 15 Mar 2019 15:21:27 -0400 Subject: [PATCH 02/14] fix tests --- .../components/staking/LiValidator.spec.js | 42 ++++---- .../__snapshots__/LiValidator.spec.js.snap | 99 ++++++++++++++----- .../TableValidators.spec.js.snap | 2 +- 3 files changed, 90 insertions(+), 53 deletions(-) diff --git a/test/unit/specs/components/staking/LiValidator.spec.js b/test/unit/specs/components/staking/LiValidator.spec.js index 1c82651c54..250ae235a2 100644 --- a/test/unit/specs/components/staking/LiValidator.spec.js +++ b/test/unit/specs/components/staking/LiValidator.spec.js @@ -23,21 +23,17 @@ describe(`LiValidator`, () => { bond_height: `0`, bond_intra_tx_counter: 6, proposer_reward_pool: null, - commission: { - rate: `0.05`, - max_rate: `0.1`, - max_change_rate: `0.005`, - update_time: `1970-01-01T00:00:00Z` - }, + commission: 5, prev_bonded_shares: `0`, - voting_power: `10`, - percent_of_vote: `22%`, + voting_power: 10, + percent_of_vote: 0.22, signing_info: { start_height: 0, index_offset: 465400, jailed_until: `1970-01-01T00:00:00Z`, missed_blocks_counter: 122 - } + }, + uptime: 0.98778883 } beforeEach(() => { @@ -82,7 +78,7 @@ describe(`LiValidator`, () => { }) it(`should show the voting power`, () => { - expect(wrapper.html()).toContain(`22%`) + expect(wrapper.html()).toContain(`22.00%`) }) it(`should show the validator status`, () => { @@ -127,21 +123,27 @@ describe(`LiValidator`, () => { expect(wrapper.vm.statusColor).toBe(`yellow`) }) - it(`should show the validator's uptime`, () => { - expect(wrapper.vm.uptime).toBe(`98.78%`) + it(`should include uptime as type:number`, () => { + expect(wrapper.vm.validator.uptime).toBe(0.98778883) + }) + + it(`should display uptime as a human readable percentage`, () => { expect(wrapper.html()).toContain(`98.78%`) + }) + it(`should display uptime as double-dash`, () => { wrapper.setProps({ validator: Object.assign({}, validator, { - signing_info: null + uptime: null }) }) - expect(wrapper.vm.uptime).toBe(`--`) + expect(wrapper.vm.validator.uptime).toBe(null) + expect(wrapper.vm.$el).toMatchSnapshot() }) it(`should show the validator's commission`, () => { - expect(wrapper.html()).toContain(wrapper.vm.validator.commission.rate) + expect(wrapper.html()).toContain(wrapper.vm.validator.commission) }) it(`should show the type of the candidate`, () => { @@ -175,16 +177,6 @@ describe(`LiValidator`, () => { expect(wrapper.vm.delegateType).toBe(`Revoked`) }) - it(`shows rewards`, () => { - $store.getters.distribution.rewards = { - [validator.operator_address]: { - stake: 1230000000 - } - } - - expect(wrapper.find(`.li-validator__rewards`).html()).toContain(`1,230.0000…`) - }) - it(`works if user is not signed in`, () => { $store.getters.session.signedIn = false diff --git a/test/unit/specs/components/staking/__snapshots__/LiValidator.spec.js.snap b/test/unit/specs/components/staking/__snapshots__/LiValidator.spec.js.snap index fae84bd85d..d5bb343e9c 100644 --- a/test/unit/specs/components/staking/__snapshots__/LiValidator.spec.js.snap +++ b/test/unit/specs/components/staking/__snapshots__/LiValidator.spec.js.snap @@ -47,23 +47,23 @@ exports[`LiValidator has the expected html structure 1`] = ` class="li-validator__delegated-steak" > - 0.0000… + -- - -- + 22.00% - 22% + 500.00% @@ -74,17 +74,78 @@ exports[`LiValidator has the expected html structure 1`] = ` 98.78% + +`; + +exports[`LiValidator should display uptime as double-dash 1`] = ` + + + + +
+ + + + + mr_mounty + + + +
+ +
+
+ + + + + -- + + + + + + 22.00% + + - 0.05% + 500.00% -- @@ -140,14 +201,6 @@ exports[`LiValidator works if user is not signed in 1`] = ` class="li-validator__delegated-steak" > - 0.0000… - - - - - -- @@ -156,15 +209,7 @@ exports[`LiValidator works if user is not signed in 1`] = ` class="li-validator__voting-power" > - 22% - - - - - - 98.78% + 22.00% @@ -172,15 +217,15 @@ exports[`LiValidator works if user is not signed in 1`] = ` class="li-validator__commission" > - 0.05% + 500.00% - -- + 98.78% diff --git a/test/unit/specs/components/staking/__snapshots__/TableValidators.spec.js.snap b/test/unit/specs/components/staking/__snapshots__/TableValidators.spec.js.snap index 3ee77a98f1..7c2ae8ff1c 100644 --- a/test/unit/specs/components/staking/__snapshots__/TableValidators.spec.js.snap +++ b/test/unit/specs/components/staking/__snapshots__/TableValidators.spec.js.snap @@ -7,7 +7,7 @@ exports[`TableValidators has the expected html structure 1`] = ` > From 7376c62945074b6c40e1bd8d3abfefb1f196e95e Mon Sep 17 00:00:00 2001 From: Jordan Bibla Date: Fri, 15 Mar 2019 15:32:57 -0400 Subject: [PATCH 03/14] pending update --- PENDING.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/PENDING.md b/PENDING.md index 9fa4faf27b..605f05b9a3 100644 --- a/PENDING.md +++ b/PENDING.md @@ -6,3 +6,5 @@ - [\#2257](https://github.com/cosmos/voyager/pull/2257) fixed console - [\#2273](https://github.com/cosmos/voyager/issues/2273) fixed atoms and uatoms conversion @fedekunze +- [\#2267](https://github.com/cosmos/voyager/issues/2267) fixed sorting on validator table @jbibla +- [\#2278](https://github.com/cosmos/voyager/issues/2278) fixed commission calculation on validator table @jbibla From 9a6c60c4fe712dc8db175ba576b21843a0e8b8db Mon Sep 17 00:00:00 2001 From: Jordan Bibla Date: Fri, 15 Mar 2019 15:58:03 -0400 Subject: [PATCH 04/14] lint --- app/src/renderer/components/staking/LiValidator.vue | 4 ++-- app/src/renderer/components/staking/PageValidator.vue | 4 ++-- app/src/renderer/components/staking/TableValidators.vue | 4 +++- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/app/src/renderer/components/staking/LiValidator.vue b/app/src/renderer/components/staking/LiValidator.vue index 61c1e37189..e70b1feb6d 100644 --- a/app/src/renderer/components/staking/LiValidator.vue +++ b/app/src/renderer/components/staking/LiValidator.vue @@ -7,7 +7,7 @@ class="data-table__row__info__image" width="48" height="48" - /> + > + >
+ >
diff --git a/app/src/renderer/components/staking/TableValidators.vue b/app/src/renderer/components/staking/TableValidators.vue index ec042e7bc7..5aad515cf7 100644 --- a/app/src/renderer/components/staking/TableValidators.vue +++ b/app/src/renderer/components/staking/TableValidators.vue @@ -75,7 +75,9 @@ export default { ), commission: v.commission.rate, keybase: this.keybase[v.description.identity], - uptime: v.signing_info ? (this.rollingWindow - v.signing_info.missed_blocks_counter) / this.rollingWindow : 0 + uptime: v.signing_info + ? (this.rollingWindow - v.signing_info.missed_blocks_counter) + / this.rollingWindow : 0 }) ) }, From 5f29fdad2b45240dcbd6a257d56525000d5add17 Mon Sep 17 00:00:00 2001 From: Jordan Bibla Date: Sat, 16 Mar 2019 17:00:16 -0400 Subject: [PATCH 05/14] removed isValidator property --- app/src/renderer/vuex/modules/delegates.js | 7 ------- 1 file changed, 7 deletions(-) diff --git a/app/src/renderer/vuex/modules/delegates.js b/app/src/renderer/vuex/modules/delegates.js index 65680d5ca6..be5dc7222b 100644 --- a/app/src/renderer/vuex/modules/delegates.js +++ b/app/src/renderer/vuex/modules/delegates.js @@ -76,17 +76,10 @@ export default ({ node }) => { try { let validators = await node.getValidators() - const { validators: validatorSet } = await node.getValidatorSet() state.error = null state.loading = false state.loaded = true - for (const validator of validators) { - validator.isValidator = false - if (validatorSet.find(v => v.pub_key === validator.pub_key)) { - validator.isValidator = true - } - } // the tokens and shares are currently served in a weird format that is a amino representation of a float value validators = validators.map(validator => { return Object.assign(JSON.parse(JSON.stringify(validator)), { From 40fb05fd3e1a9a5633bb9fd64d16342fe28780e4 Mon Sep 17 00:00:00 2001 From: Jordan Bibla Date: Sun, 17 Mar 2019 10:16:17 -0400 Subject: [PATCH 06/14] fixed sorting again, simplified data for validator table, added rewards and delegations with correct calulations --- .../components/staking/LiValidator.vue | 93 ++++++------------- .../components/staking/TableValidators.vue | 86 ++++++++--------- 2 files changed, 69 insertions(+), 110 deletions(-) diff --git a/app/src/renderer/components/staking/LiValidator.vue b/app/src/renderer/components/staking/LiValidator.vue index e70b1feb6d..4fe1ff78ab 100644 --- a/app/src/renderer/components/staking/LiValidator.vue +++ b/app/src/renderer/components/staking/LiValidator.vue @@ -29,7 +29,6 @@ name: 'validator', params: { validator: validator.operator_address } }" - :class="styles" class="data-table__row__info__container__name" > {{ validator.description.moniker }} @@ -40,7 +39,18 @@
- {{ yourVotes.isGreaterThan(0) ? num.shortNumber(yourVotes) : `--` }} + {{ + validator.my_delegations + ? num.shortNumber(num.atoms(validator.my_delegations)) + : `--` + }} + + + {{ + validator.rewards + ? num.shortNumber(num.atoms(validator.rewards.uatom)) + : `--` + }} {{ @@ -61,9 +71,7 @@ diff --git a/app/src/renderer/components/staking/TableValidators.vue b/app/src/renderer/components/staking/TableValidators.vue index 5aad515cf7..b97c47b5c6 100644 --- a/app/src/renderer/components/staking/TableValidators.vue +++ b/app/src/renderer/components/staking/TableValidators.vue @@ -6,10 +6,9 @@ @@ -19,9 +18,8 @@ From c1c5a77d6b45357487e549beb4703d524d90fa09 Mon Sep 17 00:00:00 2001 From: Jordan Bibla Date: Sun, 17 Mar 2019 16:18:52 -0400 Subject: [PATCH 07/14] fixed tests, bumped coverage --- .../components/staking/TableValidators.vue | 12 +- .../components/staking/LiValidator.spec.js | 48 +---- .../staking/TabMyDelegations.spec.js | 3 +- .../staking/TableValidators.spec.js | 167 +++++------------- .../__snapshots__/LiValidator.spec.js.snap | 24 +++ .../TableValidators.spec.js.snap | 2 +- test/unit/specs/store/delegates.spec.js | 12 -- 7 files changed, 87 insertions(+), 181 deletions(-) diff --git a/app/src/renderer/components/staking/TableValidators.vue b/app/src/renderer/components/staking/TableValidators.vue index b97c47b5c6..0fb8d8b44d 100644 --- a/app/src/renderer/components/staking/TableValidators.vue +++ b/app/src/renderer/components/staking/TableValidators.vue @@ -116,12 +116,17 @@ export default { tooltip: `Ratio of blocks signed within the last 10k blocks` }, ] + }, + yourValidators() { + return this.validators.filter( + ({ operator_address }) => operator_address in this.committedDelegations + ) } }, watch: { - // address: function() { - // this.session.address && this.$store.dispatch(`updateDelegates`) - // }, + address: function() { + this.session.address && this.$store.dispatch(`updateDelegates`) + }, validators: function(validators) { if (!validators || validators.length === 0 || !this.session.signedIn) { return @@ -135,6 +140,7 @@ export default { }, mounted() { this.$store.dispatch(`getPool`) + this.$store.dispatch(`updateDelegates`) } } diff --git a/test/unit/specs/components/staking/LiValidator.spec.js b/test/unit/specs/components/staking/LiValidator.spec.js index 250ae235a2..40abae1c57 100644 --- a/test/unit/specs/components/staking/LiValidator.spec.js +++ b/test/unit/specs/components/staking/LiValidator.spec.js @@ -10,7 +10,7 @@ describe(`LiValidator`, () => { const validator = { operator_address: `cosmosvaladdr15ky9du8a2wlstz6fpx3p4mqpjyrm5ctplpn3au`, pub_key: `cosmosvalpub1234`, - revoked: false, + jailed: false, tokens: `14`, delegator_shares: `14`, description: { @@ -72,11 +72,6 @@ describe(`LiValidator`, () => { expect(wrapper.vm.$el).toMatchSnapshot() }) - it(`should calculate the validator's power ratio`, () => { - const ratio = wrapper.vm.validator.tokens / wrapper.vm.delegates.globalPower - expect(wrapper.vm.powerRatio).toBe(ratio) - }) - it(`should show the voting power`, () => { expect(wrapper.html()).toContain(`22.00%`) }) @@ -86,7 +81,7 @@ describe(`LiValidator`, () => { // Jailed wrapper.setProps({ validator: Object.assign({}, validator, { - revoked: true + jailed: true }) }) expect(wrapper.vm.status).toBe( @@ -95,12 +90,12 @@ describe(`LiValidator`, () => { // Is not a validator wrapper.setProps({ validator: Object.assign({}, validator, { - revoked: false, + jailed: false, voting_power: 0 }) }) expect(wrapper.vm.status).toBe( - `This validator does not have enough voting power yet and is inactive` + `This validator does not have enough voting power and is inactive` ) }) @@ -109,14 +104,14 @@ describe(`LiValidator`, () => { // Jailed wrapper.setProps({ validator: Object.assign({}, validator, { - revoked: true + jailed: true }) }) expect(wrapper.vm.statusColor).toBe(`red`) // Is not a validator wrapper.setProps({ validator: Object.assign({}, validator, { - revoked: false, + jailed: false, voting_power: 0 }) }) @@ -146,37 +141,6 @@ describe(`LiValidator`, () => { expect(wrapper.html()).toContain(wrapper.vm.validator.commission) }) - it(`should show the type of the candidate`, () => { - wrapper.setProps({ - validator: Object.assign({}, validator, { - revoked: false, - isValidator: false - }) - }) - expect(wrapper.vm.delegateType).toBe(`Candidate`) - wrapper.setProps({ - validator: Object.assign({}, validator, { - revoked: false, - isValidator: true - }) - }) - expect(wrapper.vm.delegateType).toBe(`Validator`) - wrapper.setProps({ - validator: Object.assign({}, validator, { - revoked: true, - isValidator: false - }) - }) - expect(wrapper.vm.delegateType).toBe(`Revoked`) - wrapper.setProps({ - validator: Object.assign({}, validator, { - revoked: true, - isValidator: true - }) - }) - expect(wrapper.vm.delegateType).toBe(`Revoked`) - }) - it(`works if user is not signed in`, () => { $store.getters.session.signedIn = false diff --git a/test/unit/specs/components/staking/TabMyDelegations.spec.js b/test/unit/specs/components/staking/TabMyDelegations.spec.js index a87ef29146..a017da58e9 100644 --- a/test/unit/specs/components/staking/TabMyDelegations.spec.js +++ b/test/unit/specs/components/staking/TabMyDelegations.spec.js @@ -15,8 +15,7 @@ const getters = { }, loaded: true }, - committedDelegations: { - }, + committedDelegations: {}, connected: true, bondDenom: `uatom`, session: { signedIn: true } diff --git a/test/unit/specs/components/staking/TableValidators.spec.js b/test/unit/specs/components/staking/TableValidators.spec.js index b6e7e194eb..23bad88100 100644 --- a/test/unit/specs/components/staking/TableValidators.spec.js +++ b/test/unit/specs/components/staking/TableValidators.spec.js @@ -10,7 +10,7 @@ describe(`TableValidators`, () => { loaded: true }, committedDelegations: { - [validators[0].operator_address]: 0 + [validators[2].operator_address]: 10 }, session: { address: `address1234` @@ -22,6 +22,11 @@ describe(`TableValidators`, () => { [validators[0].description.identity]: { // TODO } + }, + pool: { + pool: { + bonded_tokens: 500001, + } } } @@ -49,43 +54,17 @@ describe(`TableValidators`, () => { wrapper.vm.sort.order = `desc` expect( - wrapper.vm.sortedEnrichedDelegates.map(x => x.operator_address) + wrapper.vm.sortedEnrichedValidators.map(x => x.operator_address) ).toEqual(validators.map(x => x.operator_address)) wrapper.vm.sort.property = `operator_address` wrapper.vm.sort.order = `asc` expect( - wrapper.vm.sortedEnrichedDelegates.map(x => x.operator_address) + wrapper.vm.sortedEnrichedValidators.map(x => x.operator_address) ).toEqual(validators.map(x => x.operator_address).reverse()) }) - it(`should disallow delegation if user can't delegate`, () => { - let res = TableValidators.computed.userCanDelegate.call({ - liquidAtoms: 0, - delegation: { - loaded: true - } - }) - expect(res).toBe(false) - - res = TableValidators.computed.userCanDelegate.call({ - liquidAtoms: 1, - delegation: { - loaded: true - } - }) - expect(res).toBe(true) - - res = TableValidators.computed.userCanDelegate.call({ - liquidAtoms: 1, - delegation: { - loaded: false - } - }) - expect(res).toBe(false) - }) - it(`queries delegations on signin`, () => { const session = { address: `cosmos1address` } const $store = { dispatch: jest.fn() } @@ -100,101 +79,47 @@ describe(`TableValidators`, () => { expect($store.dispatch).not.toHaveBeenCalledWith(`updateDelegates`) }) - describe(`update validators rewards every block`, () => { - it(`updates if there are existing validators`, () => { - const validators = [ - { - operator_address: `cosmosvaloper1address`, - pub_key: `cosmosvalpub1234`, - revoked: false, - tokens: `14`, - delegator_shares: `14`, - description: { - website: `www.fede.cl`, - details: `Fede's validator`, - moniker: `fedekunze`, - country: `Chile` - }, - status: 2, - bond_height: `0`, - bond_intra_tx_counter: 6, - proposer_reward_pool: null, - commission: { - rate: `0`, - max_rate: `0`, - max_change_rate: `0`, - update_time: `1970-01-01T00:00:00Z` - }, - prev_bonded_shares: `0` + xit(`updates if there are existing validators`, () => { + const session = { signedIn: true } + $store = { + dispatch: jest.fn(), + getters: { + committedDelegations: { + [validators[2].operator_address]: 10 } - ] - const session = { signedIn: true } - const $store = { dispatch: jest.fn() } - TableValidators.watch.validators.call({ $store, session }, validators) - expect($store.dispatch).toHaveBeenCalledWith( - `getRewardsFromAllValidators`, - validators - ) - }) + } + } + TableValidators.watch.validators.call({ $store, session }, validators) + expect($store.dispatch).toHaveBeenCalledWith( + `getRewardsFromAllValidators`, + validators[2] + ) + }) - describe(`doesn't update rewards`, () => { - it(`if user hasn't signed in`, () => { - const validators = [ - { - operator_address: `cosmosvaloper1address`, - pub_key: `cosmosvalpub1234`, - revoked: false, - tokens: `14`, - delegator_shares: `14`, - description: { - website: `www.fede.cl`, - details: `Fede's validator`, - moniker: `fedekunze`, - country: `Chile` - }, - status: 2, - bond_height: `0`, - bond_intra_tx_counter: 6, - proposer_reward_pool: null, - commission: { - rate: `0`, - max_rate: `0`, - max_change_rate: `0`, - update_time: `1970-01-01T00:00:00Z` - }, - prev_bonded_shares: `0` - } - ] - const session = { signedIn: false } - const $store = { dispatch: jest.fn() } - TableValidators.watch.validators.call({ $store, session }, validators) - expect($store.dispatch).not.toHaveBeenCalledWith( - `getRewardsFromAllValidators`, - validators - ) - }) + it(`doesn't update rewards if user hasn't signed in`, () => { + const validators = [] + const session = { signedIn: false } + TableValidators.watch.validators.call({ $store, session }, validators) + expect($store.dispatch).not.toHaveBeenCalledWith( + `getRewardsFromAllValidators` + ) + }) - it(`if validator set is empty`, () => { - const validators = [] - const session = { signedIn: true } - const $store = { dispatch: jest.fn() } - TableValidators.watch.validators.call({ $store, session }, validators) - expect($store.dispatch).not.toHaveBeenCalledWith( - `getRewardsFromAllValidators`, - validators - ) - }) + it(`doesn't update rewards if validator set is empty`, () => { + const validators = [] + const session = { signedIn: true } + TableValidators.watch.validators.call({ $store, session }, validators) + expect($store.dispatch).not.toHaveBeenCalledWith( + `getRewardsFromAllValidators` + ) + }) - it(`if validator set is undefined`, () => { - const validators = undefined - const session = { signedIn: true } - const $store = { dispatch: jest.fn() } - TableValidators.watch.validators.call({ $store, session }, validators) - expect($store.dispatch).not.toHaveBeenCalledWith( - `getRewardsFromAllValidators`, - validators - ) - }) - }) + it(`doesn't update rewards if validator set is undefined`, () => { + const validators = undefined + const session = { signedIn: true } + TableValidators.watch.validators.call({ $store, session }, validators) + expect($store.dispatch).not.toHaveBeenCalledWith( + `getRewardsFromAllValidators` + ) }) }) diff --git a/test/unit/specs/components/staking/__snapshots__/LiValidator.spec.js.snap b/test/unit/specs/components/staking/__snapshots__/LiValidator.spec.js.snap index d5bb343e9c..50efdc9eb7 100644 --- a/test/unit/specs/components/staking/__snapshots__/LiValidator.spec.js.snap +++ b/test/unit/specs/components/staking/__snapshots__/LiValidator.spec.js.snap @@ -51,6 +51,14 @@ exports[`LiValidator has the expected html structure 1`] = ` + + + -- + + + @@ -128,6 +136,14 @@ exports[`LiValidator should display uptime as double-dash 1`] = ` + + + -- + + + @@ -205,6 +221,14 @@ exports[`LiValidator works if user is not signed in 1`] = ` + + + -- + + + diff --git a/test/unit/specs/components/staking/__snapshots__/TableValidators.spec.js.snap b/test/unit/specs/components/staking/__snapshots__/TableValidators.spec.js.snap index 7c2ae8ff1c..2cd3e23d9c 100644 --- a/test/unit/specs/components/staking/__snapshots__/TableValidators.spec.js.snap +++ b/test/unit/specs/components/staking/__snapshots__/TableValidators.spec.js.snap @@ -7,7 +7,7 @@ exports[`TableValidators has the expected html structure 1`] = ` > diff --git a/test/unit/specs/store/delegates.spec.js b/test/unit/specs/store/delegates.spec.js index 8ae0e1c22d..4192c0437e 100644 --- a/test/unit/specs/store/delegates.spec.js +++ b/test/unit/specs/store/delegates.spec.js @@ -243,16 +243,4 @@ describe(`Module: Delegates`, () => { }) expect(state.error).toBe(`Error`) }) - - it(`should store an error if failed to load validator set`, async () => { - const { actions, state } = instance - node.getValidatorSet = async () => Promise.reject(`Error`) - await actions.getDelegates({ - commit: jest.fn(), - dispatch: jest.fn(), - state, - rootState: mockRootState - }) - expect(state.error).toBe(`Error`) - }) }) From 02c8911fdd6865ccb13f5ae322d0fa5c52bf7f5c Mon Sep 17 00:00:00 2001 From: Jordan Bibla Date: Sun, 17 Mar 2019 19:54:12 -0400 Subject: [PATCH 08/14] more tests! --- .../components/staking/TableValidators.vue | 15 ++++---- .../staking/TableValidators.spec.js | 34 +++++++++++++------ 2 files changed, 32 insertions(+), 17 deletions(-) diff --git a/app/src/renderer/components/staking/TableValidators.vue b/app/src/renderer/components/staking/TableValidators.vue index 0fb8d8b44d..12e1114c05 100644 --- a/app/src/renderer/components/staking/TableValidators.vue +++ b/app/src/renderer/components/staking/TableValidators.vue @@ -117,9 +117,13 @@ export default { }, ] }, - yourValidators() { - return this.validators.filter( - ({ operator_address }) => operator_address in this.committedDelegations + yourValidators({ committedDelegations, validators, session } = this) { + if (!session.signedIn) { + return + } + + return validators.filter( + ({ operator_address }) => operator_address in committedDelegations ) } }, @@ -131,11 +135,8 @@ export default { if (!validators || validators.length === 0 || !this.session.signedIn) { return } - const yourValidators = validators.filter( - ({ operator_address }) => operator_address in this.committedDelegations - ) - this.$store.dispatch(`getRewardsFromAllValidators`, yourValidators) + this.$store.dispatch(`getRewardsFromAllValidators`, this.yourValidators) } }, mounted() { diff --git a/test/unit/specs/components/staking/TableValidators.spec.js b/test/unit/specs/components/staking/TableValidators.spec.js index 23bad88100..1342c74266 100644 --- a/test/unit/specs/components/staking/TableValidators.spec.js +++ b/test/unit/specs/components/staking/TableValidators.spec.js @@ -81,16 +81,16 @@ describe(`TableValidators`, () => { xit(`updates if there are existing validators`, () => { const session = { signedIn: true } - $store = { - dispatch: jest.fn(), - getters: { - committedDelegations: { - [validators[2].operator_address]: 10 - } - } - } - TableValidators.watch.validators.call({ $store, session }, validators) - expect($store.dispatch).toHaveBeenCalledWith( + TableValidators.computed.yourValidators({ + committedDelegations: { + [validators[0].operator_address]: 1, + [validators[2].operator_address]: 2 + }, + validators, + session + }) + TableValidators.watch.validators.call({ $store, session, validators }) + expect($store.dispatch.mock.calls[2]).toEqual( `getRewardsFromAllValidators`, validators[2] ) @@ -122,4 +122,18 @@ describe(`TableValidators`, () => { `getRewardsFromAllValidators` ) }) + + it(`should filter the validators for your delegations`, () => { + const session = { signedIn: true } + expect( + TableValidators.computed.yourValidators({ + committedDelegations: { + [validators[0].operator_address]: 1, + [validators[2].operator_address]: 2 + }, + validators, + session + }) + ).toEqual([validators[0], validators[2]]) + }) }) From a9dce526a7bf08bd33013ee5ee6b6f7923b69c07 Mon Sep 17 00:00:00 2001 From: Jordan Bibla Date: Sun, 17 Mar 2019 23:10:24 -0400 Subject: [PATCH 09/14] added more tests --- .../components/staking/TableValidators.vue | 34 +++++--- .../staking/TableValidators.spec.js | 81 +++++++++++++------ test/unit/specs/store/json/validators.js | 28 +++++-- 3 files changed, 100 insertions(+), 43 deletions(-) diff --git a/app/src/renderer/components/staking/TableValidators.vue b/app/src/renderer/components/staking/TableValidators.vue index 12e1114c05..8ef2236b68 100644 --- a/app/src/renderer/components/staking/TableValidators.vue +++ b/app/src/renderer/components/staking/TableValidators.vue @@ -44,32 +44,40 @@ export default { }), computed: { ...mapGetters([ - `delegation`, `committedDelegations`, `session`, `distribution`, - `liquidAtoms`, `bondDenom`, `keybase`, `pool` ]), - enrichedValidators() { - return this.validators.map(v => + enrichedValidators({ + validators, + pool, + committedDelegations, + keybase, + session, + distribution, + rollingWindow + } = this) { + return validators.map(v => Object.assign({}, v, { small_moniker: v.description.moniker.toLowerCase(), - percent_of_vote: v.voting_power / this.pool.pool.bonded_tokens, - my_delegations: this.committedDelegations[v.id] > 0 - ? this.committedDelegations[v.id] + percent_of_vote: v.voting_power / pool.pool.bonded_tokens, + my_delegations: session.signedIn + && committedDelegations[v.id] > 0 + ? committedDelegations[v.id] : 0, commission: v.commission.rate, - keybase: this.keybase[v.description.identity], - rewards: this.session.signedIn - && this.distribution.loaded && !isEmpty(this.distribution.rewards) - ? this.distribution.rewards[v.operator_address] + keybase: keybase[v.description.identity], + rewards: session.signedIn + && distribution.loaded + && !isEmpty(distribution.rewards) + ? distribution.rewards[v.operator_address] : 0, uptime: v.signing_info - ? (this.rollingWindow - v.signing_info.missed_blocks_counter) - / this.rollingWindow + ? (rollingWindow - v.signing_info.missed_blocks_counter) + / rollingWindow : 0 }) ) diff --git a/test/unit/specs/components/staking/TableValidators.spec.js b/test/unit/specs/components/staking/TableValidators.spec.js index 1342c74266..119e3ffb18 100644 --- a/test/unit/specs/components/staking/TableValidators.spec.js +++ b/test/unit/specs/components/staking/TableValidators.spec.js @@ -6,28 +6,26 @@ describe(`TableValidators`, () => { let wrapper, $store const getters = { - delegation: { - loaded: true - }, committedDelegations: { - [validators[2].operator_address]: 10 + [validators[0].operator_address]: 10 }, session: { - address: `address1234` + address: `address1234`, + signedIn: true }, - liquidAtoms: 42, - connected: true, - bondDenom: `stake`, - keybase: { - [validators[0].description.identity]: { - // TODO + distribution: { + loaded: true, + rewards: { + cosmosvaladdr15ky9du8a2wlstz6fpx3p4mqpjyrm5ctqzh8yqw: 1000 } }, + bondDenom: `stake`, + keybase: { [validators[0].description.identity]: `keybase` }, pool: { pool: { bonded_tokens: 500001, } - } + }, } beforeEach(() => { @@ -43,12 +41,34 @@ describe(`TableValidators`, () => { }, propsData: { validators } }) + wrapper.setData({ rollingWindow: 10000 }) }) it(`has the expected html structure`, async () => { expect(wrapper.vm.$el).toMatchSnapshot() }) + it(`should create an enriched validator object for a signed in user`, () => { + expect(wrapper.vm.enrichedValidators[0].small_moniker).toBe(`mr_mounty`) + expect(wrapper.vm.enrichedValidators[0].percent_of_vote) + .toBe(0.27999944000112) + expect(wrapper.vm.enrichedValidators[0].my_delegations).toBe(10) + expect(wrapper.vm.enrichedValidators[0].commission).toBe(0) + expect(wrapper.vm.enrichedValidators[0].keybase).toBe(`keybase`) + expect(wrapper.vm.enrichedValidators[0].rewards).toBe(1000) + expect(wrapper.vm.enrichedValidators[0].uptime).toBe(0.9998) + }) + + it(`should create an enriched validator object for a user who is not signed in`, () => { + wrapper.vm.session.signedIn = false + expect(wrapper.vm.enrichedValidators[1].my_delegations).toBe(0) + expect(wrapper.vm.enrichedValidators[1].rewards).toBe(0) + }) + + it(`should have an uptime of 0 if no signing_info`, () => { + expect(wrapper.vm.enrichedValidators[1].uptime).toBe(0) + }) + it(`should sort the delegates by selected property`, () => { wrapper.vm.sort.property = `operator_address` wrapper.vm.sort.order = `desc` @@ -79,20 +99,19 @@ describe(`TableValidators`, () => { expect($store.dispatch).not.toHaveBeenCalledWith(`updateDelegates`) }) - xit(`updates if there are existing validators`, () => { + it(`updates if there are existing validators`, () => { const session = { signedIn: true } - TableValidators.computed.yourValidators({ - committedDelegations: { - [validators[0].operator_address]: 1, - [validators[2].operator_address]: 2 - }, - validators, - session - }) - TableValidators.watch.validators.call({ $store, session, validators }) + const yourValidators = { + cosmosvaladdr15ky9du8a2wlstz6fpx3p4mqpjyrm5ctgurrg7n: 2 + } + TableValidators.watch.validators.call({ + session, $store, yourValidators + }, validators) expect($store.dispatch.mock.calls[2]).toEqual( - `getRewardsFromAllValidators`, - validators[2] + [ + `getRewardsFromAllValidators`, + { cosmosvaladdr15ky9du8a2wlstz6fpx3p4mqpjyrm5ctgurrg7n: 2 } + ] ) }) @@ -136,4 +155,18 @@ describe(`TableValidators`, () => { }) ).toEqual([validators[0], validators[2]]) }) + + it(`should not filter the validators if you're not signed in`, () => { + const session = { signedIn: false } + expect( + TableValidators.computed.yourValidators({ + committedDelegations: { + [validators[0].operator_address]: 1, + [validators[2].operator_address]: 2 + }, + validators, + session + }) + ).not.toBeDefined() + }) }) diff --git a/test/unit/specs/store/json/validators.js b/test/unit/specs/store/json/validators.js index 9a6da65fab..548bfc97d1 100644 --- a/test/unit/specs/store/json/validators.js +++ b/test/unit/specs/store/json/validators.js @@ -1,5 +1,6 @@ export default [ { + id: `cosmosvaladdr15ky9du8a2wlstz6fpx3p4mqpjyrm5ctqzh8yqw`, operator_address: `cosmosvaladdr15ky9du8a2wlstz6fpx3p4mqpjyrm5ctqzh8yqw`, pub_key: `cosmosvalpub1234`, revoked: false, @@ -9,14 +10,19 @@ export default [ website: `www.monty.ca`, details: `Mr Mounty`, moniker: `mr_mounty`, - country: `Canada` + country: `Canada`, + identity: `keybase` + }, + voting_power: 140000, + signing_info: { + missed_blocks_counter: 2 }, status: 2, bond_height: `0`, bond_intra_tx_counter: 6, proposer_reward_pool: null, commission: { - rate: `0`, + rate: 0, max_rate: `0`, max_change_rate: `0`, update_time: `1970-01-01T00:00:00Z` @@ -24,6 +30,7 @@ export default [ prev_bonded_shares: `0` }, { + id: `cosmosvaladdr15ky9du8a2wlstz6fpx3p4mqpjyrm5ctplpn3au`, operator_address: `cosmosvaladdr15ky9du8a2wlstz6fpx3p4mqpjyrm5ctplpn3au`, pub_key: `cosmosvalpub5678`, revoked: false, @@ -33,14 +40,17 @@ export default [ website: `www.greg.com`, details: `Good Guy Greg`, moniker: `good_greg`, - country: `USA` + country: `USA`, + identity: `keybase` }, + voting_power: 180000, + signing_info: null, status: 2, bond_height: `0`, bond_intra_tx_counter: 6, proposer_reward_pool: null, commission: { - rate: `0`, + rate: 0, max_rate: `0`, max_change_rate: `0`, update_time: new Date(Date.now()).toISOString() @@ -48,6 +58,7 @@ export default [ prev_bonded_shares: `0` }, { + id: `cosmosvaladdr15ky9du8a2wlstz6fpx3p4mqpjyrm5ctgurrg7n`, operator_address: `cosmosvaladdr15ky9du8a2wlstz6fpx3p4mqpjyrm5ctgurrg7n`, pub_key: `cosmosvalpub8910`, tokens: `19`, @@ -56,15 +67,20 @@ export default [ details: `Herr Schmidt`, website: `www.schmidt.de`, moniker: `herr_schmidt_revoked`, - country: `DE` + country: `DE`, + identity: `keybase` }, revoked: true, + voting_power: 220000, + signing_info: { + missed_blocks_counter: 2000 + }, status: 2, bond_height: `0`, bond_intra_tx_counter: 6, proposer_reward_pool: null, commission: { - rate: `0`, + rate: 0, max_rate: `0`, max_change_rate: `0`, update_time: new Date(Date.now()).toISOString() From 651304eab6d52425d21047d9073d4d3bc53c4df8 Mon Sep 17 00:00:00 2001 From: Jordan Bibla Date: Sun, 17 Mar 2019 23:30:13 -0400 Subject: [PATCH 10/14] removed comment, fixed filtering bug --- .../components/staking/LiValidator.vue | 19 ++----------------- .../components/staking/TableValidators.vue | 7 +++---- .../staking/TableValidators.spec.js | 4 +++- 3 files changed, 8 insertions(+), 22 deletions(-) diff --git a/app/src/renderer/components/staking/LiValidator.vue b/app/src/renderer/components/staking/LiValidator.vue index 4fe1ff78ab..9d1edc424c 100644 --- a/app/src/renderer/components/staking/LiValidator.vue +++ b/app/src/renderer/components/staking/LiValidator.vue @@ -47,9 +47,7 @@ {{ - validator.rewards - ? num.shortNumber(num.atoms(validator.rewards.uatom)) - : `--` + validator.rewards ? num.shortNumber(num.atoms(validator.rewards)) : `--` }} @@ -114,19 +112,6 @@ export default { // status: active return `green` }, - }, - // watch: { - // lastHeader: { - // immediate: true, - // handler() { - // if (this.validator.my_delegations > 0) { - // this.$store.dispatch( - // `getRewardsFromValidator`, - // this.validator.operator_address - // ) - // } - // } - // } - // } + } } diff --git a/app/src/renderer/components/staking/TableValidators.vue b/app/src/renderer/components/staking/TableValidators.vue index 8ef2236b68..4e611f3527 100644 --- a/app/src/renderer/components/staking/TableValidators.vue +++ b/app/src/renderer/components/staking/TableValidators.vue @@ -18,7 +18,7 @@