Merge PR #1914: tallyResults added to state
* tallyResults added to state * fixed bug with tallyresult equals
This commit is contained in:
parent
f653bed8c9
commit
4582de4902
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -27,6 +27,9 @@ type Proposal interface {
|
|||
GetStatus() ProposalStatus
|
||||
SetStatus(ProposalStatus)
|
||||
|
||||
GetTallyResult() TallyResult
|
||||
SetTallyResult(TallyResult)
|
||||
|
||||
GetSubmitBlock() int64
|
||||
SetSubmitBlock(int64)
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------
|
||||
|
@ -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
|
||||
|
@ -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 }
|
||||
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -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()))
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue