From eec875f71bc67b194a3a88f0baa6eeebeeba006a Mon Sep 17 00:00:00 2001 From: Ruihuan Date: Thu, 26 Sep 2019 15:49:49 +0800 Subject: [PATCH 1/5] Sum validator operator's all voting power --- x/gov/keeper/tally.go | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/x/gov/keeper/tally.go b/x/gov/keeper/tally.go index 1bd9082031a6..bdece31cf018 100644 --- a/x/gov/keeper/tally.go +++ b/x/gov/keeper/tally.go @@ -40,25 +40,25 @@ func (keeper Keeper) Tally(ctx sdk.Context, proposal types.Proposal) (passes boo if val, ok := currValidators[valAddrStr]; ok { val.Vote = vote.Option currValidators[valAddrStr] = val - } else { - // iterate over all delegations from voter, deduct from any delegated-to validators - keeper.sk.IterateDelegations(ctx, vote.Voter, func(index int64, delegation exported.DelegationI) (stop bool) { - valAddrStr := delegation.GetValidatorAddr().String() + } - if val, ok := currValidators[valAddrStr]; ok { - val.DelegatorDeductions = val.DelegatorDeductions.Add(delegation.GetShares()) - currValidators[valAddrStr] = val + // iterate over all delegations from voter, deduct from any delegated-to validators + keeper.sk.IterateDelegations(ctx, vote.Voter, func(index int64, delegation exported.DelegationI) (stop bool) { + valAddrStr := delegation.GetValidatorAddr().String() - delegatorShare := delegation.GetShares().Quo(val.DelegatorShares) - votingPower := delegatorShare.MulInt(val.BondedTokens) + if val, ok := currValidators[valAddrStr]; ok { + val.DelegatorDeductions = val.DelegatorDeductions.Add(delegation.GetShares()) + currValidators[valAddrStr] = val - results[vote.Option] = results[vote.Option].Add(votingPower) - totalVotingPower = totalVotingPower.Add(votingPower) - } + delegatorShare := delegation.GetShares().Quo(val.DelegatorShares) + votingPower := delegatorShare.MulInt(val.BondedTokens) - return false - }) - } + results[vote.Option] = results[vote.Option].Add(votingPower) + totalVotingPower = totalVotingPower.Add(votingPower) + } + + return false + }) keeper.deleteVote(ctx, vote.ProposalID, vote.Voter) return false From ea73d420c4d2794c9093c9695845a6b9398ff1a4 Mon Sep 17 00:00:00 2001 From: Ruihuan Date: Wed, 9 Oct 2019 10:57:47 +0800 Subject: [PATCH 2/5] Add a test case for tally that validator had multiple delegations (#5107) --- x/gov/keeper/tally_test.go | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/x/gov/keeper/tally_test.go b/x/gov/keeper/tally_test.go index dcf370289565..ceaed4eb4437 100644 --- a/x/gov/keeper/tally_test.go +++ b/x/gov/keeper/tally_test.go @@ -396,3 +396,41 @@ func TestTallyJailedValidator(t *testing.T) { require.False(t, burnDeposits) require.False(t, tallyResults.Equals(types.EmptyTallyResult())) } + +func TestTallyValidatorMultipleDelegations(t *testing.T) { + ctx, _, keeper, sk, _ := createTestInput(t, false, 100) + createValidators(ctx, sk, []int64{10, 10, 10}) + + delTokens := sdk.TokensFromConsensusPower(10) + val2, found := sk.GetValidator(ctx, valOpAddr2) + require.True(t, found) + + _, err := sk.Delegate(ctx, valAccAddr1, delTokens, sdk.Unbonded, val2, true) + require.NoError(t, err) + + tp := TestProposal + proposal, err := keeper.SubmitProposal(ctx, tp) + require.NoError(t, err) + proposalID := proposal.ProposalID + proposal.Status = types.StatusVotingPeriod + keeper.SetProposal(ctx, proposal) + + require.NoError(t, keeper.AddVote(ctx, proposalID, valAccAddr1, types.OptionYes)) + require.NoError(t, keeper.AddVote(ctx, proposalID, valAccAddr2, types.OptionNo)) + require.NoError(t, keeper.AddVote(ctx, proposalID, valAccAddr3, types.OptionYes)) + + proposal, ok := keeper.GetProposal(ctx, proposalID) + require.True(t, ok) + passes, burnDeposits, tallyResults := keeper.Tally(ctx, proposal) + + require.True(t, passes) + require.False(t, burnDeposits) + + expectedYes := sdk.TokensFromConsensusPower(30) + expectedAbstain := sdk.TokensFromConsensusPower(0) + expectedNo := sdk.TokensFromConsensusPower(10) + expectedNoWithVeto := sdk.TokensFromConsensusPower(0) + expectedTallyResult := types.NewTallyResult(expectedYes, expectedAbstain, expectedNo, expectedNoWithVeto) + + require.True(t, tallyResults.Equals(expectedTallyResult)) +} From 02fdc1d96ba634403edee1c10bcf1ba4841243f0 Mon Sep 17 00:00:00 2001 From: Ruihuan Date: Sat, 12 Oct 2019 10:46:24 +0800 Subject: [PATCH 3/5] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1d91fa65022c..10fdb668277b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -178,6 +178,7 @@ to detail this new feature and how state transitions occur. * (cli) [\#4763](https://github.com/cosmos/cosmos-sdk/issues/4763) Fix flag `--min-self-delegation` for staking `EditValidator` * (keys) Fix ledger custom coin type support bug +* (x/gov) [\#5107](https://github.com/cosmos/cosmos-sdk/pull/5107) Sum validator operator's all voting power when tally votes ## [v0.37.2] - 2019-10-10 From 97da457dc67940956560f350d27c9a0364198816 Mon Sep 17 00:00:00 2001 From: Ruihuan Date: Tue, 15 Oct 2019 10:43:59 +0800 Subject: [PATCH 4/5] Handle self-delegations case when dueduct voter's voting power (#5107) --- x/gov/keeper/tally.go | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/x/gov/keeper/tally.go b/x/gov/keeper/tally.go index bdece31cf018..1a0368263e95 100644 --- a/x/gov/keeper/tally.go +++ b/x/gov/keeper/tally.go @@ -35,18 +35,19 @@ func (keeper Keeper) Tally(ctx sdk.Context, proposal types.Proposal) (passes boo keeper.IterateVotes(ctx, proposal.ProposalID, func(vote types.Vote) bool { // if validator, just record it in the map - // if delegator tally voting power - valAddrStr := sdk.ValAddress(vote.Voter).String() - if val, ok := currValidators[valAddrStr]; ok { + voteValAddrStr := sdk.ValAddress(vote.Voter).String() + if val, ok := currValidators[voteValAddrStr]; ok { val.Vote = vote.Option - currValidators[valAddrStr] = val + currValidators[voteValAddrStr] = val } // iterate over all delegations from voter, deduct from any delegated-to validators keeper.sk.IterateDelegations(ctx, vote.Voter, func(index int64, delegation exported.DelegationI) (stop bool) { valAddrStr := delegation.GetValidatorAddr().String() - if val, ok := currValidators[valAddrStr]; ok { + val, ok := currValidators[valAddrStr] + // there is no need to deduct amounts from their own validator + if ok && valAddrStr != voteValAddrStr { val.DelegatorDeductions = val.DelegatorDeductions.Add(delegation.GetShares()) currValidators[valAddrStr] = val From c68ad96820e2531b44a5a5fe1ca97e5f751af6ca Mon Sep 17 00:00:00 2001 From: Ruihuan Date: Fri, 18 Oct 2019 11:14:16 +0800 Subject: [PATCH 5/5] Remove the special case of validator's vote when deduct voter's voting power from validator. (#5107) --- x/gov/keeper/tally.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/x/gov/keeper/tally.go b/x/gov/keeper/tally.go index 1a0368263e95..f6b0008d4052 100644 --- a/x/gov/keeper/tally.go +++ b/x/gov/keeper/tally.go @@ -35,19 +35,19 @@ func (keeper Keeper) Tally(ctx sdk.Context, proposal types.Proposal) (passes boo keeper.IterateVotes(ctx, proposal.ProposalID, func(vote types.Vote) bool { // if validator, just record it in the map - voteValAddrStr := sdk.ValAddress(vote.Voter).String() - if val, ok := currValidators[voteValAddrStr]; ok { + valAddrStr := sdk.ValAddress(vote.Voter).String() + if val, ok := currValidators[valAddrStr]; ok { val.Vote = vote.Option - currValidators[voteValAddrStr] = val + currValidators[valAddrStr] = val } // iterate over all delegations from voter, deduct from any delegated-to validators keeper.sk.IterateDelegations(ctx, vote.Voter, func(index int64, delegation exported.DelegationI) (stop bool) { valAddrStr := delegation.GetValidatorAddr().String() - val, ok := currValidators[valAddrStr] - // there is no need to deduct amounts from their own validator - if ok && valAddrStr != voteValAddrStr { + if val, ok := currValidators[valAddrStr]; ok { + // There is no need to handle the special case that validator address equal to voter address. + // Because voter's voting power will tally again even if there will deduct voter's voting power from validator. val.DelegatorDeductions = val.DelegatorDeductions.Add(delegation.GetShares()) currValidators[valAddrStr] = val