Skip to content
This repository has been archived by the owner on Dec 1, 2021. It is now read-only.

Displayed validators who have not voted for proposal yet #550

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## [UNRELEASED]
* [#523] Implemented readable messages for IBC messages
* [#355] Displayed validators who have not voted for proposal yet

## [v0.41.x-14.2]
* Fixes Ledger WebUSB + Chrome 91.x issue (https://github.com/LedgerHQ/ledgerjs/issues/607)
Expand Down
2 changes: 2 additions & 0 deletions both/i18n/en-us.i18n.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ common:
channel: 'Channel'
proofClient: 'Proof Client'
counterparty: 'Counterparty'
didNotVote: 'Did not vote'

navbar:
siteName: 'BIG DIPPER'
Expand Down Expand Up @@ -213,6 +214,7 @@ proposals:
recipient: 'Recipient'
changes: 'Changes'
subspace: 'Subspace'
validators: '<span>{$number}</span> validators'
votingPower:
distribution: 'Voting Power Distribution'
pareto: 'Pareto Principle (20/80 rule)'
Expand Down
29 changes: 29 additions & 0 deletions imports/api/proposals/server/methods.js
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,35 @@ Meteor.methods({
}
}
return true
},
'proposals.getValidatorsDidNotVote': function () {
this.unblock();
let proposals = Proposals.find({ "status": { $in: ["PROPOSAL_STATUS_VOTING_PERIOD"] } }).fetch();
let validators = Validators.find({}).fetch();
if (proposals && (proposals.length > 0)) {
for (let i in proposals) {
let validatorsWithoutVote = [];
let counter = 0;
if (parseInt(proposals[i].proposalId) > 0) {
for (let o in validators) {
let finder = (proposals[i].votes).some((voter) => voter.voter === validators[o].delegator_address);
if(!finder){
validatorsWithoutVote[counter] = validators[o];
counter++;
}
};
try {
let list = validatorsWithoutVote.sort(function (a, b) {
return ('' + a.description.moniker).localeCompare(b.description.moniker);
});
Proposals.update({ proposalId: proposals[i].proposalId }, { $set: { validatorsDidNotVote: { list: list, lastUpdated: new Date() } } });
}
catch (e) {
console.log(e);
}
}
}
}
}
})

Expand Down
26 changes: 25 additions & 1 deletion imports/ui/proposals/Proposal.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -270,13 +270,29 @@ export default class Proposal extends Component{
</Result>
}

renderValidatorsWithoutVote() {
let validatorsDidNotVoteList = this.props?.proposal?.validatorsDidNotVote?.list ?? [];
return <Result className="tally-result-detail" pose={this.state.open ? 'open' : 'closed'}>
<Card className='tally-result-table'>
{validatorsDidNotVoteList.map((vote, i) =>
(vote?.operator_address ?
<Card body key={i}><Row className='voter-info'>
<Col className="d-none d-md-block counter data" md={1}>{i + 1}</Col>
<Col className="moniker data" md={4}>
<Account address={vote?.operator_address} />
</Col>
</Row></Card> : null)
)}
</Card>
</Result>
}

render(){
if (this.props.loading){
return <Spinner type="grow" color="primary" />
}
else{
if (this.props.proposalExist && this.state.proposal != ''){
// console.log(this.state.proposal);
const proposalId = Number(this.props.proposal.proposalId), maxProposalId = Number(this.props.proposalCount);
const powerReduction = Meteor.settings.public.powerReduction || Coin.StakingCoin.fraction;
let totalVotingPower = (this.props.activeVotingPower || this.props.chain.activeVotingPower) * powerReduction;
Expand Down Expand Up @@ -405,6 +421,14 @@ export default class Proposal extends Component{
{this.renderTallyResultDetail(4, 'VOTE_OPTION_NO_WITH_VETO')}
</Col>
</Row>
<Row>
<Col xs={6} sm={5} md={4}><i className="fas fa-question-circle text-danger"></i> <T>common.didNotVote</T></Col>
<Col xs={5} sm={6} md={7} className="tally-result-value">{this.props?.proposal?.validatorsDidNotVote?.list.length > 0 ? <T _purify={false} number={this.props?.proposal?.validatorsDidNotVote?.list.length}>proposals.validators</T> : <T _purify={false} number={0}>proposals.validators</T> }</Col>
<Col xs={1} onClick={(e) => this.handleClick(6, e)}><i className="material-icons">{this.state.open === 6 ? 'arrow_drop_down' : 'arrow_left'}</i></Col>
<Col xs={12}>
{this.renderValidatorsWithoutVote()}
</Col>
</Row>
{this.state.voteStarted?<Row>
<Col xs={12}><Card>
<CardHeader>
Expand Down
16 changes: 16 additions & 0 deletions server/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ timerMissedBlock = 0;
timerDelegation = 0;
timerAggregate = 0;
timerFetchKeybase = 0;
timerValidatorsDidNotVote = 0;

const DEFAULTSETTINGS = '/default_settings.json';

Expand Down Expand Up @@ -121,6 +122,17 @@ getDelegations = () => {
});
}

getValidatorsDidNotVote = () => {
Meteor.call('proposals.getValidatorsDidNotVote', (error, result) => {
if (error) {
console.log("get validators did not vote error: %o", error)
}
else {
console.log("get validators did not vote ok: %o", result)
}
});
}

aggregateMinutely = () =>{
// doing something every min
Meteor.call('Analytics.aggregateBlockTimeAndVotingPower', "m", (error, result) => {
Expand Down Expand Up @@ -220,6 +232,10 @@ Meteor.startup(async function(){
timerProposalsResults = Meteor.setInterval(function (){
getProposalsResults();
}, Meteor.settings.params.proposalInterval);

timerValidatorsDidNotVote = Meteor.setInterval(function () {
getValidatorsDidNotVote()
}, Meteor.settings.params.proposalInterval)
}

timerMissedBlock = Meteor.setInterval(function(){
Expand Down