Skip to content

Commit

Permalink
Merge PR #1914: tallyResults added to state
Browse files Browse the repository at this point in the history
* tallyResults added to state
* fixed bug with tallyresult equals
  • Loading branch information
sunnya97 authored and cwgoes committed Aug 8, 2018
1 parent f653bed commit 4582de4
Show file tree
Hide file tree
Showing 7 changed files with 93 additions and 33 deletions.
1 change: 1 addition & 0 deletions PENDING.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ FEATURES
* [gov] Add slashing for validators who do not vote on a proposal
* [cli] added `gov query-proposals` command to CLI. Can filter by `depositer`, `voter`, and `status`
* [core] added BaseApp.Seal - ability to seal baseapp parameters once they've been set
* [gov] added TallyResult type that gets added stored in Proposal after tallying is finished

IMPROVEMENTS
* [baseapp] Allow any alphanumeric character in route
Expand Down
4 changes: 4 additions & 0 deletions x/gov/endblocker_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ func TestTickPassedDepositPeriod(t *testing.T) {
require.False(t, shouldPopInactiveProposalQueue(ctx, keeper))
require.NotNil(t, keeper.ActiveProposalQueuePeek(ctx))
require.False(t, shouldPopActiveProposalQueue(ctx, keeper))

}

func TestTickPassedVotingPeriod(t *testing.T) {
Expand Down Expand Up @@ -166,6 +167,7 @@ func TestTickPassedVotingPeriod(t *testing.T) {
require.False(t, depositsIterator.Valid())
depositsIterator.Close()
require.Equal(t, StatusRejected, keeper.GetProposal(ctx, proposalID).GetStatus())
require.True(t, keeper.GetProposal(ctx, proposalID).GetTallyResult().Equals(EmptyTallyResult()))
}

func TestSlashing(t *testing.T) {
Expand Down Expand Up @@ -204,6 +206,8 @@ func TestSlashing(t *testing.T) {

EndBlocker(ctx, keeper)

require.False(t, keeper.GetProposal(ctx, proposalID).GetTallyResult().Equals(EmptyTallyResult()))

endTotalPower := keeper.ds.GetValidatorSet().TotalPower(ctx)
val0End := keeper.ds.GetValidatorSet().Validator(ctx, addrs[0]).GetPower().Quo(endTotalPower)
val1End := keeper.ds.GetValidatorSet().Validator(ctx, addrs[1]).GetPower().Quo(endTotalPower)
Expand Down
6 changes: 2 additions & 4 deletions x/gov/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,9 +111,6 @@ func EndBlocker(ctx sdk.Context, keeper Keeper) (resTags sdk.Tags) {
resTags.AppendTag(tags.ProposalID, proposalIDBytes)
}

var passes bool
var nonVotingVals []sdk.AccAddress

// Check if earliest Active Proposal ended voting period yet
for shouldPopActiveProposalQueue(ctx, keeper) {
activeProposal := keeper.ActiveProposalQueuePop(ctx)
Expand All @@ -124,7 +121,7 @@ func EndBlocker(ctx sdk.Context, keeper Keeper) (resTags sdk.Tags) {
continue
}

passes, nonVotingVals = tally(ctx, keeper, activeProposal)
passes, tallyResults, nonVotingVals := tally(ctx, keeper, activeProposal)
proposalIDBytes := keeper.cdc.MustMarshalBinaryBare(activeProposal.GetProposalID())
var action []byte
if passes {
Expand All @@ -136,6 +133,7 @@ func EndBlocker(ctx sdk.Context, keeper Keeper) (resTags sdk.Tags) {
activeProposal.SetStatus(StatusRejected)
action = tags.ActionProposalRejected
}
activeProposal.SetTallyResult(tallyResults)
keeper.SetProposal(ctx, activeProposal)

for _, valAddr := range nonVotingVals {
Expand Down
1 change: 1 addition & 0 deletions x/gov/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ func (keeper Keeper) NewTextProposal(ctx sdk.Context, title string, description
Description: description,
ProposalType: proposalType,
Status: StatusDepositPeriod,
TallyResult: EmptyTallyResult(),
TotalDeposit: sdk.Coins{},
SubmitBlock: ctx.BlockHeight(),
VotingStartBlock: -1, // TODO: Make Time
Expand Down
59 changes: 48 additions & 11 deletions x/gov/proposals.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ type Proposal interface {
GetStatus() ProposalStatus
SetStatus(ProposalStatus)

GetTallyResult() TallyResult
SetTallyResult(TallyResult)

GetSubmitBlock() int64
SetSubmitBlock(int64)

Expand All @@ -39,17 +42,18 @@ type Proposal interface {

// checks if two proposals are equal
func ProposalEqual(proposalA Proposal, proposalB Proposal) bool {
if proposalA.GetProposalID() != proposalB.GetProposalID() ||
proposalA.GetTitle() != proposalB.GetTitle() ||
proposalA.GetDescription() != proposalB.GetDescription() ||
proposalA.GetProposalType() != proposalB.GetProposalType() ||
proposalA.GetStatus() != proposalB.GetStatus() ||
proposalA.GetSubmitBlock() != proposalB.GetSubmitBlock() ||
!(proposalA.GetTotalDeposit().IsEqual(proposalB.GetTotalDeposit())) ||
proposalA.GetVotingStartBlock() != proposalB.GetVotingStartBlock() {
return false
if proposalA.GetProposalID() == proposalB.GetProposalID() &&
proposalA.GetTitle() == proposalB.GetTitle() &&
proposalA.GetDescription() == proposalB.GetDescription() &&
proposalA.GetProposalType() == proposalB.GetProposalType() &&
proposalA.GetStatus() == proposalB.GetStatus() &&
proposalA.GetTallyResult().Equals(proposalB.GetTallyResult()) &&
proposalA.GetSubmitBlock() == proposalB.GetSubmitBlock() &&
proposalA.GetTotalDeposit().IsEqual(proposalB.GetTotalDeposit()) &&
proposalA.GetVotingStartBlock() == proposalB.GetVotingStartBlock() {
return true
}
return true
return false
}

//-----------------------------------------------------------
Expand All @@ -60,7 +64,8 @@ type TextProposal struct {
Description string `json:"description"` // Description of the proposal
ProposalType ProposalKind `json:"proposal_type"` // Type of proposal. Initial set {PlainTextProposal, SoftwareUpgradeProposal}

Status ProposalStatus `json:"proposal_status"` // Status of the Proposal {Pending, Active, Passed, Rejected}
Status ProposalStatus `json:"proposal_status"` // Status of the Proposal {Pending, Active, Passed, Rejected}
TallyResult TallyResult `json:"tally_result"` // Result of Tallys

SubmitBlock int64 `json:"submit_block"` // Height of the block where TxGovSubmitProposal was included
TotalDeposit sdk.Coins `json:"total_deposit"` // Current deposit on this proposal. Initial value is set at InitialDeposit
Expand All @@ -82,6 +87,8 @@ func (tp TextProposal) GetProposalType() ProposalKind { return tp.P
func (tp *TextProposal) SetProposalType(proposalType ProposalKind) { tp.ProposalType = proposalType }
func (tp TextProposal) GetStatus() ProposalStatus { return tp.Status }
func (tp *TextProposal) SetStatus(status ProposalStatus) { tp.Status = status }
func (tp TextProposal) GetTallyResult() TallyResult { return tp.TallyResult }
func (tp *TextProposal) SetTallyResult(tallyResult TallyResult) { tp.TallyResult = tallyResult }
func (tp TextProposal) GetSubmitBlock() int64 { return tp.SubmitBlock }
func (tp *TextProposal) SetSubmitBlock(submitBlock int64) { tp.SubmitBlock = submitBlock }
func (tp TextProposal) GetTotalDeposit() sdk.Coins { return tp.TotalDeposit }
Expand Down Expand Up @@ -286,3 +293,33 @@ func (status ProposalStatus) Format(s fmt.State, verb rune) {
s.Write([]byte(fmt.Sprintf("%v", byte(status))))
}
}

//-----------------------------------------------------------
// Tally Results
type TallyResult struct {
Yes sdk.Rat `json:"yes"`
Abstain sdk.Rat `json:"abstain"`
No sdk.Rat `json:"no"`
NoWithVeto sdk.Rat `json:"no_with_veto"`
}

// checks if two proposals are equal
func EmptyTallyResult() TallyResult {
return TallyResult{
Yes: sdk.ZeroRat(),
Abstain: sdk.ZeroRat(),
No: sdk.ZeroRat(),
NoWithVeto: sdk.ZeroRat(),
}
}

// checks if two proposals are equal
func (resultA TallyResult) Equals(resultB TallyResult) bool {
if resultA.Yes.Equal(resultB.Yes) &&
resultA.Abstain.Equal(resultB.Abstain) &&
resultA.No.Equal(resultB.No) &&
resultA.NoWithVeto.Equal(resultB.NoWithVeto) {
return true
}
return false
}
17 changes: 12 additions & 5 deletions x/gov/tally.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ type validatorGovInfo struct {
Vote VoteOption // Vote of the validator
}

func tally(ctx sdk.Context, keeper Keeper, proposal Proposal) (passes bool, nonVoting []sdk.AccAddress) {
func tally(ctx sdk.Context, keeper Keeper, proposal Proposal) (passes bool, tallyResults TallyResult, nonVoting []sdk.AccAddress) {
results := make(map[VoteOption]sdk.Rat)
results[OptionYes] = sdk.ZeroRat()
results[OptionAbstain] = sdk.ZeroRat()
Expand Down Expand Up @@ -83,18 +83,25 @@ func tally(ctx sdk.Context, keeper Keeper, proposal Proposal) (passes bool, nonV

tallyingProcedure := keeper.GetTallyingProcedure(ctx)

tallyResults = TallyResult{
Yes: results[OptionYes],
Abstain: results[OptionAbstain],
No: results[OptionNo],
NoWithVeto: results[OptionNoWithVeto],
}

// If no one votes, proposal fails
if totalVotingPower.Sub(results[OptionAbstain]).Equal(sdk.ZeroRat()) {
return false, nonVoting
return false, tallyResults, nonVoting
}
// If more than 1/3 of voters veto, proposal fails
if results[OptionNoWithVeto].Quo(totalVotingPower).GT(tallyingProcedure.Veto) {
return false, nonVoting
return false, tallyResults, nonVoting
}
// If more than 1/2 of non-abstaining voters vote Yes, proposal passes
if results[OptionYes].Quo(totalVotingPower.Sub(results[OptionAbstain])).GT(tallyingProcedure.Threshold) {
return true, nonVoting
return true, tallyResults, nonVoting
}
// If more than 1/2 of non-abstaining voters vote No, proposal fails
return false, nonVoting
return false, tallyResults, nonVoting
}
38 changes: 25 additions & 13 deletions x/gov/tally_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,10 @@ func TestTallyNoOneVotes(t *testing.T) {
proposal.SetStatus(StatusVotingPeriod)
keeper.SetProposal(ctx, proposal)

passes, _ := tally(ctx, keeper, keeper.GetProposal(ctx, proposalID))
passes, tallyResults, _ := tally(ctx, keeper, keeper.GetProposal(ctx, proposalID))

require.False(t, passes)
require.True(t, tallyResults.Equals(EmptyTallyResult()))
}

func TestTallyOnlyValidatorsAllYes(t *testing.T) {
Expand All @@ -63,9 +64,10 @@ func TestTallyOnlyValidatorsAllYes(t *testing.T) {
err = keeper.AddVote(ctx, proposalID, addrs[1], OptionYes)
require.Nil(t, err)

passes, _ := tally(ctx, keeper, keeper.GetProposal(ctx, proposalID))
passes, tallyResults, _ := tally(ctx, keeper, keeper.GetProposal(ctx, proposalID))

require.True(t, passes)
require.False(t, tallyResults.Equals(EmptyTallyResult()))
}

func TestTallyOnlyValidators51No(t *testing.T) {
Expand All @@ -86,7 +88,7 @@ func TestTallyOnlyValidators51No(t *testing.T) {
err = keeper.AddVote(ctx, proposalID, addrs[1], OptionNo)
require.Nil(t, err)

passes, _ := tally(ctx, keeper, keeper.GetProposal(ctx, proposalID))
passes, _, _ := tally(ctx, keeper, keeper.GetProposal(ctx, proposalID))

require.False(t, passes)
}
Expand All @@ -111,9 +113,10 @@ func TestTallyOnlyValidators51Yes(t *testing.T) {
err = keeper.AddVote(ctx, proposalID, addrs[2], OptionNo)
require.Nil(t, err)

passes, _ := tally(ctx, keeper, keeper.GetProposal(ctx, proposalID))
passes, tallyResults, _ := tally(ctx, keeper, keeper.GetProposal(ctx, proposalID))

require.True(t, passes)
require.False(t, tallyResults.Equals(EmptyTallyResult()))
}

func TestTallyOnlyValidatorsVetoed(t *testing.T) {
Expand All @@ -136,9 +139,10 @@ func TestTallyOnlyValidatorsVetoed(t *testing.T) {
err = keeper.AddVote(ctx, proposalID, addrs[2], OptionNoWithVeto)
require.Nil(t, err)

passes, _ := tally(ctx, keeper, keeper.GetProposal(ctx, proposalID))
passes, tallyResults, _ := tally(ctx, keeper, keeper.GetProposal(ctx, proposalID))

require.False(t, passes)
require.False(t, tallyResults.Equals(EmptyTallyResult()))
}

func TestTallyOnlyValidatorsAbstainPasses(t *testing.T) {
Expand All @@ -161,9 +165,10 @@ func TestTallyOnlyValidatorsAbstainPasses(t *testing.T) {
err = keeper.AddVote(ctx, proposalID, addrs[2], OptionYes)
require.Nil(t, err)

passes, _ := tally(ctx, keeper, keeper.GetProposal(ctx, proposalID))
passes, tallyResults, _ := tally(ctx, keeper, keeper.GetProposal(ctx, proposalID))

require.True(t, passes)
require.False(t, tallyResults.Equals(EmptyTallyResult()))
}

func TestTallyOnlyValidatorsAbstainFails(t *testing.T) {
Expand All @@ -186,9 +191,10 @@ func TestTallyOnlyValidatorsAbstainFails(t *testing.T) {
err = keeper.AddVote(ctx, proposalID, addrs[2], OptionNo)
require.Nil(t, err)

passes, _ := tally(ctx, keeper, keeper.GetProposal(ctx, proposalID))
passes, tallyResults, _ := tally(ctx, keeper, keeper.GetProposal(ctx, proposalID))

require.False(t, passes)
require.False(t, tallyResults.Equals(EmptyTallyResult()))
}

func TestTallyOnlyValidatorsNonVoter(t *testing.T) {
Expand All @@ -209,11 +215,12 @@ func TestTallyOnlyValidatorsNonVoter(t *testing.T) {
err = keeper.AddVote(ctx, proposalID, addrs[2], OptionNo)
require.Nil(t, err)

passes, nonVoting := tally(ctx, keeper, keeper.GetProposal(ctx, proposalID))
passes, tallyResults, nonVoting := tally(ctx, keeper, keeper.GetProposal(ctx, proposalID))

require.False(t, passes)
require.Equal(t, 1, len(nonVoting))
require.Equal(t, addrs[0], nonVoting[0])
require.False(t, tallyResults.Equals(EmptyTallyResult()))
}

func TestTallyDelgatorOverride(t *testing.T) {
Expand Down Expand Up @@ -241,9 +248,10 @@ func TestTallyDelgatorOverride(t *testing.T) {
err = keeper.AddVote(ctx, proposalID, addrs[3], OptionNo)
require.Nil(t, err)

passes, _ := tally(ctx, keeper, keeper.GetProposal(ctx, proposalID))
passes, tallyResults, _ := tally(ctx, keeper, keeper.GetProposal(ctx, proposalID))

require.False(t, passes)
require.False(t, tallyResults.Equals(EmptyTallyResult()))
}

func TestTallyDelgatorInherit(t *testing.T) {
Expand All @@ -269,10 +277,11 @@ func TestTallyDelgatorInherit(t *testing.T) {
err = keeper.AddVote(ctx, proposalID, addrs[2], OptionYes)
require.Nil(t, err)

passes, nonVoting := tally(ctx, keeper, keeper.GetProposal(ctx, proposalID))
passes, tallyResults, nonVoting := tally(ctx, keeper, keeper.GetProposal(ctx, proposalID))

require.True(t, passes)
require.Equal(t, 0, len(nonVoting))
require.False(t, tallyResults.Equals(EmptyTallyResult()))
}

func TestTallyDelgatorMultipleOverride(t *testing.T) {
Expand Down Expand Up @@ -302,9 +311,10 @@ func TestTallyDelgatorMultipleOverride(t *testing.T) {
err = keeper.AddVote(ctx, proposalID, addrs[3], OptionNo)
require.Nil(t, err)

passes, _ := tally(ctx, keeper, keeper.GetProposal(ctx, proposalID))
passes, tallyResults, _ := tally(ctx, keeper, keeper.GetProposal(ctx, proposalID))

require.False(t, passes)
require.False(t, tallyResults.Equals(EmptyTallyResult()))
}

func TestTallyDelgatorMultipleInherit(t *testing.T) {
Expand Down Expand Up @@ -338,9 +348,10 @@ func TestTallyDelgatorMultipleInherit(t *testing.T) {
err = keeper.AddVote(ctx, proposalID, addrs[2], OptionNo)
require.Nil(t, err)

passes, _ := tally(ctx, keeper, keeper.GetProposal(ctx, proposalID))
passes, tallyResults, _ := tally(ctx, keeper, keeper.GetProposal(ctx, proposalID))

require.False(t, passes)
require.False(t, tallyResults.Equals(EmptyTallyResult()))
}

func TestTallyRevokedValidator(t *testing.T) {
Expand Down Expand Up @@ -371,7 +382,8 @@ func TestTallyRevokedValidator(t *testing.T) {
err = keeper.AddVote(ctx, proposalID, addrs[2], OptionNo)
require.Nil(t, err)

passes, _ := tally(ctx, keeper, keeper.GetProposal(ctx, proposalID))
passes, tallyResults, _ := tally(ctx, keeper, keeper.GetProposal(ctx, proposalID))

require.True(t, passes)
require.False(t, tallyResults.Equals(EmptyTallyResult()))
}

0 comments on commit 4582de4

Please sign in to comment.