Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Jordan/2267+2278 validator table bugs #2300

Merged
merged 17 commits into from
Mar 18, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions PENDING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
### Fixed

- [\#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
108 changes: 18 additions & 90 deletions app/src/renderer/components/staking/LiValidator.vue
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
name: 'validator',
params: { validator: validator.operator_address }
}"
:class="styles"
class="data-table__row__info__container__name"
>
{{ validator.description.moniker }}
Expand All @@ -41,35 +40,36 @@
</td>
<td class="li-validator__delegated-steak">
{{
yourVotes.isLessThan(0.01) && yourVotes.isGreaterThan(0)
? num.shortNumber(0.01)
: num.shortNumber(yourVotes)
validator.my_delegations
? num.shortNumber(num.atoms(validator.my_delegations))
: `--`
}}
</td>
<td class="li-validator__rewards data-table__row__cell__separator">
{{ rewards || "--" }}
<td class="li-validator__rewards">
{{
validator.rewards ? num.shortNumber(num.atoms(validator.rewards)) : `--`
}}
</td>
<td class="li-validator__voting-power">
{{ validator.percent_of_vote ? validator.percent_of_vote : `--` }}
</td>
<td class="li-validator__uptime">
{{ uptime }}
{{
validator.percent_of_vote
? num.percent(validator.percent_of_vote)
: `--`
}}
</td>
<td class="li-validator__commission">
{{ commission }}
{{ validator.commission ? num.percent(validator.commission) : `--` }}
</td>
<td class="li-validator__slashes">
--
<td class="li-validator__uptime">
{{ validator.uptime ? num.percent(validator.uptime) : `--` }}
</td>
</tr>
</template>

<script>
import { mapGetters } from "vuex"
import num from "scripts/num"
import { calculateTokens, ratToBigNumber } from "scripts/common"
import ShortBech32 from "common/ShortBech32"
import BigNumber from "bignumber.js"
export default {
name: `li-validator`,
components: {
Expand All @@ -80,110 +80,38 @@ export default {
type: Object,
required: true
},
disabled: {
type: Boolean,
required: true
}
},
data: () => ({ num }),
computed: {
...mapGetters([
`delegates`,
`committedDelegations`,
`distribution`,
`bondDenom`,
`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(
num
.atoms(
calculateTokens(
this.validator,
this.committedDelegations[this.validator.operator_address]
)
)
.toString()
)
: BigNumber(0)
},
styles() {
let value = ``
if (this.validator.isValidator) value += `li-validator-validator `
return value
},
delegateType() {
return this.validator.revoked
? `Revoked`
: this.validator.isValidator
? `Validator`
: `Candidate`
},
powerRatio() {
return ratToBigNumber(this.validator.tokens)
.div(this.delegates.globalPower)
.toNumber()
},
status() {
// status: jailed
if (this.validator.revoked)
if (this.validator.jailed)
return `This validator has been jailed and is not currently validating`

// status: inactive
if (parseFloat(this.validator.voting_power) === 0)
return `This validator does not have enough voting power yet and is inactive`
return `This validator does not have enough voting power and is inactive`

// status: active
return `This validator is actively validating`
},
statusColor() {
// status: jailed
if (this.validator.revoked) return `red`
if (this.validator.jailed) return `red`

// status: inactive
if (parseFloat(this.validator.voting_power) === 0) return `yellow`

// status: active
return `green`
},
rewards() {
if (!this.session.signedIn) return null
const validatorRewards = this.distribution.rewards[
this.validator.operator_address
]
return validatorRewards
? num.shortNumber(num.atoms(validatorRewards[this.bondDenom]) || 0)
: null
}
},
watch: {
lastHeader: {
immediate: true,
handler() {
if (this.yourVotes > 0) {
this.$store.dispatch(
`getRewardsFromValidator`,
this.validator.operator_address
)
}
}
}
}
}
</script>
5 changes: 1 addition & 4 deletions app/src/renderer/components/staking/PageValidator.vue
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,7 @@
{{ percent(validator.commission.rate) }}
</dd>
</dl>
<dl
v-if="session.experimentalMode"
class="info_dl colored_dl"
>
<dl v-if="session.experimentalMode" class="info_dl colored_dl">
<dt>Slashes</dt>
<dd>--</dd>
</dl>
Expand Down
125 changes: 65 additions & 60 deletions app/src/renderer/components/staking/TableValidators.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,9 @@
</thead>
<tbody>
<li-validator
v-for="i in sortedEnrichedDelegates"
:key="i.operator_address"
:disabled="!userCanDelegate"
:validator="i"
v-for="validator in sortedEnrichedValidators"
:key="validator.operator_address"
:validator="validator"
/>
</tbody>
</table>
Expand All @@ -21,7 +20,6 @@ import { mapGetters } from "vuex"
import num from "scripts/num"
import { orderBy } from "lodash"
import LiValidator from "staking/LiValidator"
import { calculateTokens } from "scripts/common"
import PanelSort from "staking/PanelSort"
export default {
name: `table-validators`,
Expand All @@ -39,100 +37,103 @@ export default {
num: num,
query: ``,
sort: {
property: `percent_of_vote`,
order: `desc`
}
property: `commission`,
order: `asc`
},
rollingWindow: 10000 // param of slashing period
}),
computed: {
...mapGetters([
`delegation`,
`committedDelegations`,
`session`,
`liquidAtoms`,
`connected`,
`distribution`,
`bondDenom`,
`keybase`
`keybase`,
`pool`
]),
vpTotal() {
return this.validators
.slice(0)
.map(v => {
v.voting_power = v.voting_power ? Number(v.voting_power) : 0
return v
})
.sort((a, b) => b.voting_power - a.voting_power)
.slice(0, 100)
.reduce((sum, v) => sum + v.voting_power, 0)
},
enrichedDelegates() {
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: num.percent(v.voting_power / this.vpTotal),
your_votes: this.num.full(
calculateTokens(v, this.committedDelegations[v.id])
),
keybase: this.keybase[v.description.identity]
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: keybase[v.description.identity],
rewards:
session.signedIn && distribution.rewards[v.operator_address]
? distribution.rewards[v.operator_address][this.bondDenom]
: 0,
uptime: v.signing_info
? (rollingWindow - v.signing_info.missed_blocks_counter) /
rollingWindow
: 0
})
)
},
sortedEnrichedDelegates() {
sortedEnrichedValidators() {
return orderBy(
this.enrichedDelegates.slice(0),
[this.sort.property, `small_moniker`],
[this.sort.order, `asc`]
this.enrichedValidators.slice(0),
[this.sort.property],
[this.sort.order]
)
},
userCanDelegate() {
return this.liquidAtoms > 0 && this.delegation.loaded
},
properties() {
return [
{
title: `Moniker`,
value: `small_moniker`,
tooltip: `The validator's moniker`,
class: `name`
tooltip: `The validator's moniker`
},
{
title: `My Delegations`,
value: `your_votes`,
value: `my_delegations`,
tooltip: `Number of ${
this.bondDenom
} you have delegated to this validator`,
class: `your-votes`
} you have delegated to this validator`
},
{
title: `Rewards`,
value: `your_rewards`, // TODO: use real rewards
tooltip: `Rewards you have earned from this validator`,
class: `your-rewards`
value: `rewards`,
tooltip: `Rewards you have earned from this validator`
},
{
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`
tooltip: `Percentage of voting shares`
},
{
title: `Commission`,
value: `commission`,
tooltip: `The validator's commission`,
class: `commission`
tooltip: `The validator's 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`
}
]
},
yourValidators({ committedDelegations, validators, session } = this) {
if (!session.signedIn) {
return
}

return validators.filter(
({ operator_address }) => operator_address in committedDelegations
)
}
},
watch: {
Expand All @@ -144,8 +145,12 @@ export default {
return
}

this.$store.dispatch(`getRewardsFromAllValidators`, validators)
this.$store.dispatch(`getRewardsFromAllValidators`, this.yourValidators)
}
},
mounted() {
this.$store.dispatch(`getPool`)
this.$store.dispatch(`updateDelegates`)
}
}
</script>
Loading