Merge PR #3779: Split Proposal Interface
This commit is contained in:
parent
8d6d8adb5f
commit
465bb02d6a
|
@ -680,7 +680,7 @@ func TestDeposit(t *testing.T) {
|
||||||
// query proposal
|
// query proposal
|
||||||
totalCoins := sdk.Coins{sdk.NewCoin(sdk.DefaultBondDenom, sdk.TokensFromTendermintPower(10))}
|
totalCoins := sdk.Coins{sdk.NewCoin(sdk.DefaultBondDenom, sdk.TokensFromTendermintPower(10))}
|
||||||
proposal = getProposal(t, port, proposalID)
|
proposal = getProposal(t, port, proposalID)
|
||||||
require.True(t, proposal.GetTotalDeposit().IsEqual(totalCoins))
|
require.True(t, proposal.TotalDeposit.IsEqual(totalCoins))
|
||||||
|
|
||||||
// query deposit
|
// query deposit
|
||||||
deposit := getDeposit(t, port, proposalID, addr)
|
deposit := getDeposit(t, port, proposalID, addr)
|
||||||
|
@ -718,7 +718,7 @@ func TestVote(t *testing.T) {
|
||||||
// query proposal
|
// query proposal
|
||||||
proposal := getProposal(t, port, proposalID)
|
proposal := getProposal(t, port, proposalID)
|
||||||
require.Equal(t, "Test", proposal.GetTitle())
|
require.Equal(t, "Test", proposal.GetTitle())
|
||||||
require.Equal(t, gov.StatusVotingPeriod, proposal.GetStatus())
|
require.Equal(t, gov.StatusVotingPeriod, proposal.Status)
|
||||||
|
|
||||||
// vote
|
// vote
|
||||||
resultTx = doVote(t, port, seed, name1, pw, addr, proposalID, "Yes", fees)
|
resultTx = doVote(t, port, seed, name1, pw, addr, proposalID, "Yes", fees)
|
||||||
|
@ -855,13 +855,13 @@ func TestProposalsQuery(t *testing.T) {
|
||||||
// Only proposals #1 should be in Deposit Period
|
// Only proposals #1 should be in Deposit Period
|
||||||
proposals := getProposalsFilterStatus(t, port, gov.StatusDepositPeriod)
|
proposals := getProposalsFilterStatus(t, port, gov.StatusDepositPeriod)
|
||||||
require.Len(t, proposals, 1)
|
require.Len(t, proposals, 1)
|
||||||
require.Equal(t, proposalID1, proposals[0].GetProposalID())
|
require.Equal(t, proposalID1, proposals[0].ProposalID)
|
||||||
|
|
||||||
// Only proposals #2 and #3 should be in Voting Period
|
// Only proposals #2 and #3 should be in Voting Period
|
||||||
proposals = getProposalsFilterStatus(t, port, gov.StatusVotingPeriod)
|
proposals = getProposalsFilterStatus(t, port, gov.StatusVotingPeriod)
|
||||||
require.Len(t, proposals, 2)
|
require.Len(t, proposals, 2)
|
||||||
require.Equal(t, proposalID2, proposals[0].GetProposalID())
|
require.Equal(t, proposalID2, proposals[0].ProposalID)
|
||||||
require.Equal(t, proposalID3, proposals[1].GetProposalID())
|
require.Equal(t, proposalID3, proposals[1].ProposalID)
|
||||||
|
|
||||||
// Addr1 votes on proposals #2 & #3
|
// Addr1 votes on proposals #2 & #3
|
||||||
resultTx = doVote(t, port, seeds[0], names[0], passwords[0], addrs[0], proposalID2, "Yes", fees)
|
resultTx = doVote(t, port, seeds[0], names[0], passwords[0], addrs[0], proposalID2, "Yes", fees)
|
||||||
|
@ -875,31 +875,31 @@ func TestProposalsQuery(t *testing.T) {
|
||||||
|
|
||||||
// Test query all proposals
|
// Test query all proposals
|
||||||
proposals = getProposalsAll(t, port)
|
proposals = getProposalsAll(t, port)
|
||||||
require.Equal(t, proposalID1, (proposals[0]).GetProposalID())
|
require.Equal(t, proposalID1, (proposals[0]).ProposalID)
|
||||||
require.Equal(t, proposalID2, (proposals[1]).GetProposalID())
|
require.Equal(t, proposalID2, (proposals[1]).ProposalID)
|
||||||
require.Equal(t, proposalID3, (proposals[2]).GetProposalID())
|
require.Equal(t, proposalID3, (proposals[2]).ProposalID)
|
||||||
|
|
||||||
// Test query deposited by addr1
|
// Test query deposited by addr1
|
||||||
proposals = getProposalsFilterDepositor(t, port, addrs[0])
|
proposals = getProposalsFilterDepositor(t, port, addrs[0])
|
||||||
require.Equal(t, proposalID1, (proposals[0]).GetProposalID())
|
require.Equal(t, proposalID1, (proposals[0]).ProposalID)
|
||||||
|
|
||||||
// Test query deposited by addr2
|
// Test query deposited by addr2
|
||||||
proposals = getProposalsFilterDepositor(t, port, addrs[1])
|
proposals = getProposalsFilterDepositor(t, port, addrs[1])
|
||||||
require.Equal(t, proposalID2, (proposals[0]).GetProposalID())
|
require.Equal(t, proposalID2, (proposals[0]).ProposalID)
|
||||||
require.Equal(t, proposalID3, (proposals[1]).GetProposalID())
|
require.Equal(t, proposalID3, (proposals[1]).ProposalID)
|
||||||
|
|
||||||
// Test query voted by addr1
|
// Test query voted by addr1
|
||||||
proposals = getProposalsFilterVoter(t, port, addrs[0])
|
proposals = getProposalsFilterVoter(t, port, addrs[0])
|
||||||
require.Equal(t, proposalID2, (proposals[0]).GetProposalID())
|
require.Equal(t, proposalID2, (proposals[0]).ProposalID)
|
||||||
require.Equal(t, proposalID3, (proposals[1]).GetProposalID())
|
require.Equal(t, proposalID3, (proposals[1]).ProposalID)
|
||||||
|
|
||||||
// Test query voted by addr2
|
// Test query voted by addr2
|
||||||
proposals = getProposalsFilterVoter(t, port, addrs[1])
|
proposals = getProposalsFilterVoter(t, port, addrs[1])
|
||||||
require.Equal(t, proposalID3, (proposals[0]).GetProposalID())
|
require.Equal(t, proposalID3, (proposals[0]).ProposalID)
|
||||||
|
|
||||||
// Test query voted and deposited by addr1
|
// Test query voted and deposited by addr1
|
||||||
proposals = getProposalsFilterVoterDepositor(t, port, addrs[0], addrs[0])
|
proposals = getProposalsFilterVoterDepositor(t, port, addrs[0], addrs[0])
|
||||||
require.Equal(t, proposalID2, (proposals[0]).GetProposalID())
|
require.Equal(t, proposalID2, (proposals[0]).ProposalID)
|
||||||
|
|
||||||
// Test query votes on Proposal 2
|
// Test query votes on Proposal 2
|
||||||
votes := getVotes(t, port, proposalID2)
|
votes := getVotes(t, port, proposalID2)
|
||||||
|
|
|
@ -463,12 +463,12 @@ func TestGaiaCLISubmitProposal(t *testing.T) {
|
||||||
|
|
||||||
// Ensure propsal is directly queryable
|
// Ensure propsal is directly queryable
|
||||||
proposal1 := f.QueryGovProposal(1)
|
proposal1 := f.QueryGovProposal(1)
|
||||||
require.Equal(t, uint64(1), proposal1.GetProposalID())
|
require.Equal(t, uint64(1), proposal1.ProposalID)
|
||||||
require.Equal(t, gov.StatusDepositPeriod, proposal1.GetStatus())
|
require.Equal(t, gov.StatusDepositPeriod, proposal1.Status)
|
||||||
|
|
||||||
// Ensure query proposals returns properly
|
// Ensure query proposals returns properly
|
||||||
proposalsQuery = f.QueryGovProposals()
|
proposalsQuery = f.QueryGovProposals()
|
||||||
require.Equal(t, uint64(1), proposalsQuery[0].GetProposalID())
|
require.Equal(t, uint64(1), proposalsQuery[0].ProposalID)
|
||||||
|
|
||||||
// Query the deposits on the proposal
|
// Query the deposits on the proposal
|
||||||
deposit := f.QueryGovDeposit(1, fooAddr)
|
deposit := f.QueryGovDeposit(1, fooAddr)
|
||||||
|
@ -507,8 +507,8 @@ func TestGaiaCLISubmitProposal(t *testing.T) {
|
||||||
|
|
||||||
// Fetch the proposal and ensure it is now in the voting period
|
// Fetch the proposal and ensure it is now in the voting period
|
||||||
proposal1 = f.QueryGovProposal(1)
|
proposal1 = f.QueryGovProposal(1)
|
||||||
require.Equal(t, uint64(1), proposal1.GetProposalID())
|
require.Equal(t, uint64(1), proposal1.ProposalID)
|
||||||
require.Equal(t, gov.StatusVotingPeriod, proposal1.GetStatus())
|
require.Equal(t, gov.StatusVotingPeriod, proposal1.Status)
|
||||||
|
|
||||||
// Test vote generate only
|
// Test vote generate only
|
||||||
success, stdout, stderr = f.TxGovVote(1, gov.OptionYes, keyFoo, "--generate-only")
|
success, stdout, stderr = f.TxGovVote(1, gov.OptionYes, keyFoo, "--generate-only")
|
||||||
|
@ -544,7 +544,7 @@ func TestGaiaCLISubmitProposal(t *testing.T) {
|
||||||
|
|
||||||
// Ensure the proposal returns as in the voting period
|
// Ensure the proposal returns as in the voting period
|
||||||
proposalsQuery = f.QueryGovProposals("--status=VotingPeriod")
|
proposalsQuery = f.QueryGovProposals("--status=VotingPeriod")
|
||||||
require.Equal(t, uint64(1), proposalsQuery[0].GetProposalID())
|
require.Equal(t, uint64(1), proposalsQuery[0].ProposalID)
|
||||||
|
|
||||||
// submit a second test proposal
|
// submit a second test proposal
|
||||||
f.TxGovSubmitProposal(keyFoo, "Text", "Apples", "test", sdk.NewCoin(denom, proposalTokens), "-y")
|
f.TxGovSubmitProposal(keyFoo, "Text", "Apples", "test", sdk.NewCoin(denom, proposalTokens), "-y")
|
||||||
|
@ -552,7 +552,7 @@ func TestGaiaCLISubmitProposal(t *testing.T) {
|
||||||
|
|
||||||
// Test limit on proposals query
|
// Test limit on proposals query
|
||||||
proposalsQuery = f.QueryGovProposals("--limit=1")
|
proposalsQuery = f.QueryGovProposals("--limit=1")
|
||||||
require.Equal(t, uint64(2), proposalsQuery[0].GetProposalID())
|
require.Equal(t, uint64(2), proposalsQuery[0].ProposalID)
|
||||||
|
|
||||||
f.Cleanup()
|
f.Cleanup()
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,13 +84,11 @@ This type is used in a temp map when tallying
|
||||||
|
|
||||||
## Proposals
|
## Proposals
|
||||||
|
|
||||||
`Proposals` are an item to be voted on.
|
`Proposals` are an item to be voted on. It contains the `ProposalContent` which denotes what this proposal is about, and the other fields, which are the mutable state of the governance process.
|
||||||
|
|
||||||
```go
|
```go
|
||||||
type Proposal struct {
|
type Proposal struct {
|
||||||
Title string // Title of the proposal
|
ProposalContent // Proposal content interface
|
||||||
Description string // Description of the proposal
|
|
||||||
Type ProposalType // Type of proposal. Initial set {PlainTextProposal, SoftwareUpgradeProposal}
|
|
||||||
TotalDeposit sdk.Coins // Current deposit on this proposal. Initial value is set at InitialDeposit
|
TotalDeposit sdk.Coins // Current deposit on this proposal. Initial value is set at InitialDeposit
|
||||||
Deposits []Deposit // List of deposits on the proposal
|
Deposits []Deposit // List of deposits on the proposal
|
||||||
SubmitTime time.Time // Time of the block where TxGovSubmitProposal was included
|
SubmitTime time.Time // Time of the block where TxGovSubmitProposal was included
|
||||||
|
@ -108,6 +106,17 @@ type Proposal struct {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
`ProposalContent`s are an interface which contains the information about the `Proposal` where it is provided from an external source, including the proposer. Governance process itself does not evaluate about the internal content.
|
||||||
|
|
||||||
|
```go
|
||||||
|
type ProposalContent interface {
|
||||||
|
GetTitle() string
|
||||||
|
GetDescription() string
|
||||||
|
ProposalType() ProposalKind
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
We also mention a method to update the tally for a given proposal:
|
We also mention a method to update the tally for a given proposal:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
|
|
|
@ -226,7 +226,7 @@ $ gaiacli query gov votes 1
|
||||||
var proposal gov.Proposal
|
var proposal gov.Proposal
|
||||||
cdc.MustUnmarshalJSON(res, &proposal)
|
cdc.MustUnmarshalJSON(res, &proposal)
|
||||||
|
|
||||||
propStatus := proposal.GetStatus()
|
propStatus := proposal.Status
|
||||||
if !(propStatus == gov.StatusVotingPeriod || propStatus == gov.StatusDepositPeriod) {
|
if !(propStatus == gov.StatusVotingPeriod || propStatus == gov.StatusDepositPeriod) {
|
||||||
res, err = gcutils.QueryVotesByTxQuery(cdc, cliCtx, params)
|
res, err = gcutils.QueryVotesByTxQuery(cdc, cliCtx, params)
|
||||||
} else {
|
} else {
|
||||||
|
@ -339,7 +339,7 @@ $ gaiacli query gov deposits 1
|
||||||
var proposal gov.Proposal
|
var proposal gov.Proposal
|
||||||
cdc.MustUnmarshalJSON(res, &proposal)
|
cdc.MustUnmarshalJSON(res, &proposal)
|
||||||
|
|
||||||
propStatus := proposal.GetStatus()
|
propStatus := proposal.Status
|
||||||
if !(propStatus == gov.StatusVotingPeriod || propStatus == gov.StatusDepositPeriod) {
|
if !(propStatus == gov.StatusVotingPeriod || propStatus == gov.StatusDepositPeriod) {
|
||||||
res, err = gcutils.QueryDepositsByTxQuery(cdc, cliCtx, params)
|
res, err = gcutils.QueryDepositsByTxQuery(cdc, cliCtx, params)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -266,7 +266,7 @@ func queryDepositsHandlerFn(cdc *codec.Codec, cliCtx context.CLIContext) http.Ha
|
||||||
|
|
||||||
// For inactive proposals we must query the txs directly to get the deposits
|
// For inactive proposals we must query the txs directly to get the deposits
|
||||||
// as they're no longer in state.
|
// as they're no longer in state.
|
||||||
propStatus := proposal.GetStatus()
|
propStatus := proposal.Status
|
||||||
if !(propStatus == gov.StatusVotingPeriod || propStatus == gov.StatusDepositPeriod) {
|
if !(propStatus == gov.StatusVotingPeriod || propStatus == gov.StatusDepositPeriod) {
|
||||||
res, err = gcutils.QueryDepositsByTxQuery(cdc, cliCtx, params)
|
res, err = gcutils.QueryDepositsByTxQuery(cdc, cliCtx, params)
|
||||||
} else {
|
} else {
|
||||||
|
@ -489,7 +489,7 @@ func queryVotesOnProposalHandlerFn(cdc *codec.Codec, cliCtx context.CLIContext)
|
||||||
|
|
||||||
// For inactive proposals we must query the txs directly to get the votes
|
// For inactive proposals we must query the txs directly to get the votes
|
||||||
// as they're no longer in state.
|
// as they're no longer in state.
|
||||||
propStatus := proposal.GetStatus()
|
propStatus := proposal.Status
|
||||||
if !(propStatus == gov.StatusVotingPeriod || propStatus == gov.StatusDepositPeriod) {
|
if !(propStatus == gov.StatusVotingPeriod || propStatus == gov.StatusDepositPeriod) {
|
||||||
res, err = gcutils.QueryVotesByTxQuery(cdc, cliCtx, params)
|
res, err = gcutils.QueryVotesByTxQuery(cdc, cliCtx, params)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -12,8 +12,9 @@ func RegisterCodec(cdc *codec.Codec) {
|
||||||
cdc.RegisterConcrete(MsgDeposit{}, "cosmos-sdk/MsgDeposit", nil)
|
cdc.RegisterConcrete(MsgDeposit{}, "cosmos-sdk/MsgDeposit", nil)
|
||||||
cdc.RegisterConcrete(MsgVote{}, "cosmos-sdk/MsgVote", nil)
|
cdc.RegisterConcrete(MsgVote{}, "cosmos-sdk/MsgVote", nil)
|
||||||
|
|
||||||
cdc.RegisterInterface((*Proposal)(nil), nil)
|
cdc.RegisterInterface((*ProposalContent)(nil), nil)
|
||||||
cdc.RegisterConcrete(&TextProposal{}, "gov/TextProposal", nil)
|
cdc.RegisterConcrete(TextProposal{}, "gov/TextProposal", nil)
|
||||||
|
cdc.RegisterConcrete(SoftwareUpgradeProposal{}, "gov/SoftwareUpgradeProposal", nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
|
|
@ -18,7 +18,10 @@ func EndBlocker(ctx sdk.Context, keeper Keeper) sdk.Tags {
|
||||||
var proposalID uint64
|
var proposalID uint64
|
||||||
|
|
||||||
keeper.cdc.MustUnmarshalBinaryLengthPrefixed(inactiveIterator.Value(), &proposalID)
|
keeper.cdc.MustUnmarshalBinaryLengthPrefixed(inactiveIterator.Value(), &proposalID)
|
||||||
inactiveProposal := keeper.GetProposal(ctx, proposalID)
|
inactiveProposal, ok := keeper.GetProposal(ctx, proposalID)
|
||||||
|
if !ok {
|
||||||
|
panic(fmt.Sprintf("proposal %d does not exist", proposalID))
|
||||||
|
}
|
||||||
|
|
||||||
keeper.DeleteProposal(ctx, proposalID)
|
keeper.DeleteProposal(ctx, proposalID)
|
||||||
keeper.DeleteDeposits(ctx, proposalID) // delete any associated deposits (burned)
|
keeper.DeleteDeposits(ctx, proposalID) // delete any associated deposits (burned)
|
||||||
|
@ -28,10 +31,10 @@ func EndBlocker(ctx sdk.Context, keeper Keeper) sdk.Tags {
|
||||||
|
|
||||||
logger.Info(
|
logger.Info(
|
||||||
fmt.Sprintf("proposal %d (%s) didn't meet minimum deposit of %s (had only %s); deleted",
|
fmt.Sprintf("proposal %d (%s) didn't meet minimum deposit of %s (had only %s); deleted",
|
||||||
inactiveProposal.GetProposalID(),
|
inactiveProposal.ProposalID,
|
||||||
inactiveProposal.GetTitle(),
|
inactiveProposal.GetTitle(),
|
||||||
keeper.GetDepositParams(ctx).MinDeposit,
|
keeper.GetDepositParams(ctx).MinDeposit,
|
||||||
inactiveProposal.GetTotalDeposit(),
|
inactiveProposal.TotalDeposit,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -43,28 +46,31 @@ func EndBlocker(ctx sdk.Context, keeper Keeper) sdk.Tags {
|
||||||
var proposalID uint64
|
var proposalID uint64
|
||||||
|
|
||||||
keeper.cdc.MustUnmarshalBinaryLengthPrefixed(activeIterator.Value(), &proposalID)
|
keeper.cdc.MustUnmarshalBinaryLengthPrefixed(activeIterator.Value(), &proposalID)
|
||||||
activeProposal := keeper.GetProposal(ctx, proposalID)
|
activeProposal, ok := keeper.GetProposal(ctx, proposalID)
|
||||||
|
if !ok {
|
||||||
|
panic(fmt.Sprintf("proposal %d does not exist", proposalID))
|
||||||
|
}
|
||||||
passes, tallyResults := tally(ctx, keeper, activeProposal)
|
passes, tallyResults := tally(ctx, keeper, activeProposal)
|
||||||
|
|
||||||
var tagValue string
|
var tagValue string
|
||||||
if passes {
|
if passes {
|
||||||
keeper.RefundDeposits(ctx, activeProposal.GetProposalID())
|
keeper.RefundDeposits(ctx, activeProposal.ProposalID)
|
||||||
activeProposal.SetStatus(StatusPassed)
|
activeProposal.Status = StatusPassed
|
||||||
tagValue = tags.ActionProposalPassed
|
tagValue = tags.ActionProposalPassed
|
||||||
} else {
|
} else {
|
||||||
keeper.DeleteDeposits(ctx, activeProposal.GetProposalID())
|
keeper.DeleteDeposits(ctx, activeProposal.ProposalID)
|
||||||
activeProposal.SetStatus(StatusRejected)
|
activeProposal.Status = StatusRejected
|
||||||
tagValue = tags.ActionProposalRejected
|
tagValue = tags.ActionProposalRejected
|
||||||
}
|
}
|
||||||
|
|
||||||
activeProposal.SetFinalTallyResult(tallyResults)
|
activeProposal.FinalTallyResult = tallyResults
|
||||||
keeper.SetProposal(ctx, activeProposal)
|
keeper.SetProposal(ctx, activeProposal)
|
||||||
keeper.RemoveFromActiveProposalQueue(ctx, activeProposal.GetVotingEndTime(), activeProposal.GetProposalID())
|
keeper.RemoveFromActiveProposalQueue(ctx, activeProposal.VotingEndTime, activeProposal.ProposalID)
|
||||||
|
|
||||||
logger.Info(
|
logger.Info(
|
||||||
fmt.Sprintf(
|
fmt.Sprintf(
|
||||||
"proposal %d (%s) tallied; passed: %v",
|
"proposal %d (%s) tallied; passed: %v",
|
||||||
activeProposal.GetProposalID(), activeProposal.GetTitle(), passes,
|
activeProposal.ProposalID, activeProposal.GetTitle(), passes,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -208,7 +208,9 @@ func TestTickPassedVotingPeriod(t *testing.T) {
|
||||||
require.True(t, activeQueue.Valid())
|
require.True(t, activeQueue.Valid())
|
||||||
var activeProposalID uint64
|
var activeProposalID uint64
|
||||||
keeper.cdc.UnmarshalBinaryLengthPrefixed(activeQueue.Value(), &activeProposalID)
|
keeper.cdc.UnmarshalBinaryLengthPrefixed(activeQueue.Value(), &activeProposalID)
|
||||||
require.Equal(t, StatusVotingPeriod, keeper.GetProposal(ctx, activeProposalID).GetStatus())
|
proposal, ok := keeper.GetProposal(ctx, activeProposalID)
|
||||||
|
require.True(t, ok)
|
||||||
|
require.Equal(t, StatusVotingPeriod, proposal.Status)
|
||||||
depositsIterator := keeper.GetDeposits(ctx, proposalID)
|
depositsIterator := keeper.GetDeposits(ctx, proposalID)
|
||||||
require.True(t, depositsIterator.Valid())
|
require.True(t, depositsIterator.Valid())
|
||||||
depositsIterator.Close()
|
depositsIterator.Close()
|
||||||
|
|
|
@ -122,11 +122,11 @@ func InitGenesis(ctx sdk.Context, k Keeper, data GenesisState) {
|
||||||
k.setVote(ctx, vote.ProposalID, vote.Vote.Voter, vote.Vote)
|
k.setVote(ctx, vote.ProposalID, vote.Vote.Voter, vote.Vote)
|
||||||
}
|
}
|
||||||
for _, proposal := range data.Proposals {
|
for _, proposal := range data.Proposals {
|
||||||
switch proposal.GetStatus() {
|
switch proposal.Status {
|
||||||
case StatusDepositPeriod:
|
case StatusDepositPeriod:
|
||||||
k.InsertInactiveProposalQueue(ctx, proposal.GetDepositEndTime(), proposal.GetProposalID())
|
k.InsertInactiveProposalQueue(ctx, proposal.DepositEndTime, proposal.ProposalID)
|
||||||
case StatusVotingPeriod:
|
case StatusVotingPeriod:
|
||||||
k.InsertActiveProposalQueue(ctx, proposal.GetVotingEndTime(), proposal.GetProposalID())
|
k.InsertActiveProposalQueue(ctx, proposal.VotingEndTime, proposal.ProposalID)
|
||||||
}
|
}
|
||||||
k.SetProposal(ctx, proposal)
|
k.SetProposal(ctx, proposal)
|
||||||
}
|
}
|
||||||
|
@ -142,7 +142,7 @@ func ExportGenesis(ctx sdk.Context, k Keeper) GenesisState {
|
||||||
var votes []VoteWithMetadata
|
var votes []VoteWithMetadata
|
||||||
proposals := k.GetProposalsFiltered(ctx, nil, nil, StatusNil, 0)
|
proposals := k.GetProposalsFiltered(ctx, nil, nil, StatusNil, 0)
|
||||||
for _, proposal := range proposals {
|
for _, proposal := range proposals {
|
||||||
proposalID := proposal.GetProposalID()
|
proposalID := proposal.ProposalID
|
||||||
depositsIterator := k.GetDeposits(ctx, proposalID)
|
depositsIterator := k.GetDeposits(ctx, proposalID)
|
||||||
defer depositsIterator.Close()
|
defer depositsIterator.Close()
|
||||||
for ; depositsIterator.Valid(); depositsIterator.Next() {
|
for ; depositsIterator.Valid(); depositsIterator.Next() {
|
||||||
|
|
|
@ -33,9 +33,12 @@ func TestEqualProposals(t *testing.T) {
|
||||||
|
|
||||||
ctx := mapp.BaseApp.NewContext(false, abci.Header{})
|
ctx := mapp.BaseApp.NewContext(false, abci.Header{})
|
||||||
|
|
||||||
// Create two proposals
|
// Submit two proposals
|
||||||
proposal1 := keeper.NewTextProposal(ctx, "Test", "description", ProposalTypeText)
|
proposal := testProposal()
|
||||||
proposal2 := keeper.NewTextProposal(ctx, "Test", "description", ProposalTypeText)
|
proposal1, err := keeper.SubmitProposal(ctx, proposal)
|
||||||
|
require.NoError(t, err)
|
||||||
|
proposal2, err := keeper.SubmitProposal(ctx, proposal)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
// They are similar but their IDs should be different
|
// They are similar but their IDs should be different
|
||||||
require.NotEqual(t, proposal1, proposal2)
|
require.NotEqual(t, proposal1, proposal2)
|
||||||
|
@ -48,11 +51,15 @@ func TestEqualProposals(t *testing.T) {
|
||||||
require.False(t, state1.Equal(state2))
|
require.False(t, state1.Equal(state2))
|
||||||
|
|
||||||
// Now make proposals identical by setting both IDs to 55
|
// Now make proposals identical by setting both IDs to 55
|
||||||
proposal1.SetProposalID(55)
|
proposal1.ProposalID = 55
|
||||||
proposal2.SetProposalID(55)
|
proposal2.ProposalID = 55
|
||||||
require.Equal(t, proposal1, proposal1)
|
require.Equal(t, proposal1, proposal1)
|
||||||
require.True(t, ProposalEqual(proposal1, proposal2))
|
require.True(t, ProposalEqual(proposal1, proposal2))
|
||||||
|
|
||||||
|
// Reassign proposals into state
|
||||||
|
state1.Proposals[0] = proposal1
|
||||||
|
state2.Proposals[0] = proposal2
|
||||||
|
|
||||||
// State should be identical now..
|
// State should be identical now..
|
||||||
require.Equal(t, state1, state2)
|
require.Equal(t, state1, state2)
|
||||||
require.True(t, state1.Equal(state2))
|
require.True(t, state1.Equal(state2))
|
||||||
|
@ -69,17 +76,24 @@ func TestImportExportQueues(t *testing.T) {
|
||||||
ctx := mapp.BaseApp.NewContext(false, abci.Header{})
|
ctx := mapp.BaseApp.NewContext(false, abci.Header{})
|
||||||
|
|
||||||
// Create two proposals, put the second into the voting period
|
// Create two proposals, put the second into the voting period
|
||||||
proposal1 := keeper.NewTextProposal(ctx, "Test", "description", ProposalTypeText)
|
proposal := testProposal()
|
||||||
proposalID1 := proposal1.GetProposalID()
|
proposal1, err := keeper.SubmitProposal(ctx, proposal)
|
||||||
|
require.NoError(t, err)
|
||||||
|
proposalID1 := proposal1.ProposalID
|
||||||
|
|
||||||
proposal2 := keeper.NewTextProposal(ctx, "Test", "description", ProposalTypeText)
|
proposal2, err := keeper.SubmitProposal(ctx, proposal)
|
||||||
proposalID2 := proposal2.GetProposalID()
|
require.NoError(t, err)
|
||||||
|
proposalID2 := proposal2.ProposalID
|
||||||
|
|
||||||
_, votingStarted := keeper.AddDeposit(ctx, proposalID2, addrs[0], keeper.GetDepositParams(ctx).MinDeposit)
|
_, votingStarted := keeper.AddDeposit(ctx, proposalID2, addrs[0], keeper.GetDepositParams(ctx).MinDeposit)
|
||||||
require.True(t, votingStarted)
|
require.True(t, votingStarted)
|
||||||
|
|
||||||
require.True(t, keeper.GetProposal(ctx, proposalID1).GetStatus() == StatusDepositPeriod)
|
proposal1, ok := keeper.GetProposal(ctx, proposalID1)
|
||||||
require.True(t, keeper.GetProposal(ctx, proposalID2).GetStatus() == StatusVotingPeriod)
|
require.True(t, ok)
|
||||||
|
proposal2, ok = keeper.GetProposal(ctx, proposalID2)
|
||||||
|
require.True(t, ok)
|
||||||
|
require.True(t, proposal1.Status == StatusDepositPeriod)
|
||||||
|
require.True(t, proposal2.Status == StatusVotingPeriod)
|
||||||
|
|
||||||
genAccs := mapp.AccountKeeper.GetAllAccounts(ctx)
|
genAccs := mapp.AccountKeeper.GetAllAccounts(ctx)
|
||||||
|
|
||||||
|
@ -96,12 +110,19 @@ func TestImportExportQueues(t *testing.T) {
|
||||||
ctx2 = ctx2.WithBlockTime(ctx2.BlockHeader().Time.Add(keeper2.GetDepositParams(ctx2).MaxDepositPeriod).Add(keeper2.GetVotingParams(ctx2).VotingPeriod))
|
ctx2 = ctx2.WithBlockTime(ctx2.BlockHeader().Time.Add(keeper2.GetDepositParams(ctx2).MaxDepositPeriod).Add(keeper2.GetVotingParams(ctx2).VotingPeriod))
|
||||||
|
|
||||||
// Make sure that they are still in the DepositPeriod and VotingPeriod respectively
|
// Make sure that they are still in the DepositPeriod and VotingPeriod respectively
|
||||||
require.True(t, keeper2.GetProposal(ctx2, proposalID1).GetStatus() == StatusDepositPeriod)
|
proposal1, ok = keeper2.GetProposal(ctx2, proposalID1)
|
||||||
require.True(t, keeper2.GetProposal(ctx2, proposalID2).GetStatus() == StatusVotingPeriod)
|
require.True(t, ok)
|
||||||
|
proposal2, ok = keeper2.GetProposal(ctx2, proposalID2)
|
||||||
|
require.True(t, ok)
|
||||||
|
require.True(t, proposal1.Status == StatusDepositPeriod)
|
||||||
|
require.True(t, proposal2.Status == StatusVotingPeriod)
|
||||||
|
|
||||||
// Run the endblocker. Check to make sure that proposal1 is removed from state, and proposal2 is finished VotingPeriod.
|
// Run the endblocker. Check to make sure that proposal1 is removed from state, and proposal2 is finished VotingPeriod.
|
||||||
EndBlocker(ctx2, keeper2)
|
EndBlocker(ctx2, keeper2)
|
||||||
|
|
||||||
require.Nil(t, keeper2.GetProposal(ctx2, proposalID1))
|
proposal1, ok = keeper2.GetProposal(ctx2, proposalID1)
|
||||||
require.True(t, keeper2.GetProposal(ctx2, proposalID2).GetStatus() == StatusRejected)
|
require.False(t, ok)
|
||||||
|
proposal2, ok = keeper2.GetProposal(ctx2, proposalID2)
|
||||||
|
require.True(t, ok)
|
||||||
|
require.True(t, proposal2.Status == StatusRejected)
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,8 +25,20 @@ func NewHandler(keeper Keeper) sdk.Handler {
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleMsgSubmitProposal(ctx sdk.Context, keeper Keeper, msg MsgSubmitProposal) sdk.Result {
|
func handleMsgSubmitProposal(ctx sdk.Context, keeper Keeper, msg MsgSubmitProposal) sdk.Result {
|
||||||
proposal := keeper.NewTextProposal(ctx, msg.Title, msg.Description, msg.ProposalType)
|
var content ProposalContent
|
||||||
proposalID := proposal.GetProposalID()
|
switch msg.ProposalType {
|
||||||
|
case ProposalTypeText:
|
||||||
|
content = NewTextProposal(msg.Title, msg.Description)
|
||||||
|
case ProposalTypeSoftwareUpgrade:
|
||||||
|
content = NewSoftwareUpgradeProposal(msg.Title, msg.Description)
|
||||||
|
default:
|
||||||
|
return ErrInvalidProposalType(keeper.codespace, msg.ProposalType).Result()
|
||||||
|
}
|
||||||
|
proposal, err := keeper.SubmitProposal(ctx, content)
|
||||||
|
if err != nil {
|
||||||
|
return err.Result()
|
||||||
|
}
|
||||||
|
proposalID := proposal.ProposalID
|
||||||
proposalIDStr := fmt.Sprintf("%d", proposalID)
|
proposalIDStr := fmt.Sprintf("%d", proposalID)
|
||||||
|
|
||||||
err, votingStarted := keeper.AddDeposit(ctx, proposalID, msg.Proposer, msg.InitialDeposit)
|
err, votingStarted := keeper.AddDeposit(ctx, proposalID, msg.Proposer, msg.InitialDeposit)
|
||||||
|
|
|
@ -95,57 +95,58 @@ func NewKeeper(cdc *codec.Codec, key sdk.StoreKey, paramsKeeper params.Keeper,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Proposals
|
// Proposals
|
||||||
|
func (keeper Keeper) SubmitProposal(ctx sdk.Context, content ProposalContent) (proposal Proposal, err sdk.Error) {
|
||||||
// Creates a NewProposal
|
|
||||||
func (keeper Keeper) NewTextProposal(ctx sdk.Context, title string, description string, proposalType ProposalKind) Proposal {
|
|
||||||
proposalID, err := keeper.getNewProposalID(ctx)
|
proposalID, err := keeper.getNewProposalID(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil
|
return
|
||||||
}
|
}
|
||||||
var proposal Proposal = &TextProposal{
|
|
||||||
ProposalID: proposalID,
|
submitTime := ctx.BlockHeader().Time
|
||||||
Title: title,
|
depositPeriod := keeper.GetDepositParams(ctx).MaxDepositPeriod
|
||||||
Description: description,
|
|
||||||
ProposalType: proposalType,
|
proposal = Proposal{
|
||||||
|
ProposalContent: content,
|
||||||
|
ProposalID: proposalID,
|
||||||
|
|
||||||
Status: StatusDepositPeriod,
|
Status: StatusDepositPeriod,
|
||||||
FinalTallyResult: EmptyTallyResult(),
|
FinalTallyResult: EmptyTallyResult(),
|
||||||
TotalDeposit: sdk.NewCoins(),
|
TotalDeposit: sdk.NewCoins(),
|
||||||
SubmitTime: ctx.BlockHeader().Time,
|
SubmitTime: submitTime,
|
||||||
|
DepositEndTime: submitTime.Add(depositPeriod),
|
||||||
}
|
}
|
||||||
|
|
||||||
depositPeriod := keeper.GetDepositParams(ctx).MaxDepositPeriod
|
|
||||||
proposal.SetDepositEndTime(proposal.GetSubmitTime().Add(depositPeriod))
|
|
||||||
|
|
||||||
keeper.SetProposal(ctx, proposal)
|
keeper.SetProposal(ctx, proposal)
|
||||||
keeper.InsertInactiveProposalQueue(ctx, proposal.GetDepositEndTime(), proposalID)
|
keeper.InsertInactiveProposalQueue(ctx, proposal.DepositEndTime, proposalID)
|
||||||
return proposal
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get Proposal from store by ProposalID
|
// Get Proposal from store by ProposalID
|
||||||
func (keeper Keeper) GetProposal(ctx sdk.Context, proposalID uint64) Proposal {
|
func (keeper Keeper) GetProposal(ctx sdk.Context, proposalID uint64) (proposal Proposal, ok bool) {
|
||||||
store := ctx.KVStore(keeper.storeKey)
|
store := ctx.KVStore(keeper.storeKey)
|
||||||
bz := store.Get(KeyProposal(proposalID))
|
bz := store.Get(KeyProposal(proposalID))
|
||||||
if bz == nil {
|
if bz == nil {
|
||||||
return nil
|
return
|
||||||
}
|
}
|
||||||
var proposal Proposal
|
|
||||||
keeper.cdc.MustUnmarshalBinaryLengthPrefixed(bz, &proposal)
|
keeper.cdc.MustUnmarshalBinaryLengthPrefixed(bz, &proposal)
|
||||||
return proposal
|
return proposal, true
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implements sdk.AccountKeeper.
|
// Implements sdk.AccountKeeper.
|
||||||
func (keeper Keeper) SetProposal(ctx sdk.Context, proposal Proposal) {
|
func (keeper Keeper) SetProposal(ctx sdk.Context, proposal Proposal) {
|
||||||
store := ctx.KVStore(keeper.storeKey)
|
store := ctx.KVStore(keeper.storeKey)
|
||||||
bz := keeper.cdc.MustMarshalBinaryLengthPrefixed(proposal)
|
bz := keeper.cdc.MustMarshalBinaryLengthPrefixed(proposal)
|
||||||
store.Set(KeyProposal(proposal.GetProposalID()), bz)
|
store.Set(KeyProposal(proposal.ProposalID), bz)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implements sdk.AccountKeeper.
|
// Implements sdk.AccountKeeper.
|
||||||
func (keeper Keeper) DeleteProposal(ctx sdk.Context, proposalID uint64) {
|
func (keeper Keeper) DeleteProposal(ctx sdk.Context, proposalID uint64) {
|
||||||
store := ctx.KVStore(keeper.storeKey)
|
store := ctx.KVStore(keeper.storeKey)
|
||||||
proposal := keeper.GetProposal(ctx, proposalID)
|
proposal, ok := keeper.GetProposal(ctx, proposalID)
|
||||||
keeper.RemoveFromInactiveProposalQueue(ctx, proposal.GetDepositEndTime(), proposalID)
|
if !ok {
|
||||||
keeper.RemoveFromActiveProposalQueue(ctx, proposal.GetVotingEndTime(), proposalID)
|
panic("DeleteProposal cannot fail to GetProposal")
|
||||||
|
}
|
||||||
|
keeper.RemoveFromInactiveProposalQueue(ctx, proposal.DepositEndTime, proposalID)
|
||||||
|
keeper.RemoveFromActiveProposalQueue(ctx, proposal.VotingEndTime, proposalID)
|
||||||
store.Delete(KeyProposal(proposalID))
|
store.Delete(KeyProposal(proposalID))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -182,13 +183,13 @@ func (keeper Keeper) GetProposalsFiltered(ctx sdk.Context, voterAddr sdk.AccAddr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
proposal := keeper.GetProposal(ctx, proposalID)
|
proposal, ok := keeper.GetProposal(ctx, proposalID)
|
||||||
if proposal == nil {
|
if !ok {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if validProposalStatus(status) {
|
if validProposalStatus(status) {
|
||||||
if proposal.GetStatus() != status {
|
if proposal.Status != status {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -245,14 +246,14 @@ func (keeper Keeper) peekCurrentProposalID(ctx sdk.Context) (proposalID uint64,
|
||||||
}
|
}
|
||||||
|
|
||||||
func (keeper Keeper) activateVotingPeriod(ctx sdk.Context, proposal Proposal) {
|
func (keeper Keeper) activateVotingPeriod(ctx sdk.Context, proposal Proposal) {
|
||||||
proposal.SetVotingStartTime(ctx.BlockHeader().Time)
|
proposal.VotingStartTime = ctx.BlockHeader().Time
|
||||||
votingPeriod := keeper.GetVotingParams(ctx).VotingPeriod
|
votingPeriod := keeper.GetVotingParams(ctx).VotingPeriod
|
||||||
proposal.SetVotingEndTime(proposal.GetVotingStartTime().Add(votingPeriod))
|
proposal.VotingEndTime = proposal.VotingStartTime.Add(votingPeriod)
|
||||||
proposal.SetStatus(StatusVotingPeriod)
|
proposal.Status = StatusVotingPeriod
|
||||||
keeper.SetProposal(ctx, proposal)
|
keeper.SetProposal(ctx, proposal)
|
||||||
|
|
||||||
keeper.RemoveFromInactiveProposalQueue(ctx, proposal.GetDepositEndTime(), proposal.GetProposalID())
|
keeper.RemoveFromInactiveProposalQueue(ctx, proposal.DepositEndTime, proposal.ProposalID)
|
||||||
keeper.InsertActiveProposalQueue(ctx, proposal.GetVotingEndTime(), proposal.GetProposalID())
|
keeper.InsertActiveProposalQueue(ctx, proposal.VotingEndTime, proposal.ProposalID)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Params
|
// Params
|
||||||
|
@ -294,11 +295,11 @@ func (keeper Keeper) setTallyParams(ctx sdk.Context, tallyParams TallyParams) {
|
||||||
|
|
||||||
// Adds a vote on a specific proposal
|
// Adds a vote on a specific proposal
|
||||||
func (keeper Keeper) AddVote(ctx sdk.Context, proposalID uint64, voterAddr sdk.AccAddress, option VoteOption) sdk.Error {
|
func (keeper Keeper) AddVote(ctx sdk.Context, proposalID uint64, voterAddr sdk.AccAddress, option VoteOption) sdk.Error {
|
||||||
proposal := keeper.GetProposal(ctx, proposalID)
|
proposal, ok := keeper.GetProposal(ctx, proposalID)
|
||||||
if proposal == nil {
|
if !ok {
|
||||||
return ErrUnknownProposal(keeper.codespace, proposalID)
|
return ErrUnknownProposal(keeper.codespace, proposalID)
|
||||||
}
|
}
|
||||||
if proposal.GetStatus() != StatusVotingPeriod {
|
if proposal.Status != StatusVotingPeriod {
|
||||||
return ErrInactiveProposal(keeper.codespace, proposalID)
|
return ErrInactiveProposal(keeper.codespace, proposalID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -369,13 +370,13 @@ func (keeper Keeper) setDeposit(ctx sdk.Context, proposalID uint64, depositorAdd
|
||||||
// Activates voting period when appropriate
|
// Activates voting period when appropriate
|
||||||
func (keeper Keeper) AddDeposit(ctx sdk.Context, proposalID uint64, depositorAddr sdk.AccAddress, depositAmount sdk.Coins) (sdk.Error, bool) {
|
func (keeper Keeper) AddDeposit(ctx sdk.Context, proposalID uint64, depositorAddr sdk.AccAddress, depositAmount sdk.Coins) (sdk.Error, bool) {
|
||||||
// Checks to see if proposal exists
|
// Checks to see if proposal exists
|
||||||
proposal := keeper.GetProposal(ctx, proposalID)
|
proposal, ok := keeper.GetProposal(ctx, proposalID)
|
||||||
if proposal == nil {
|
if !ok {
|
||||||
return ErrUnknownProposal(keeper.codespace, proposalID), false
|
return ErrUnknownProposal(keeper.codespace, proposalID), false
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if proposal is still depositable
|
// Check if proposal is still depositable
|
||||||
if (proposal.GetStatus() != StatusDepositPeriod) && (proposal.GetStatus() != StatusVotingPeriod) {
|
if (proposal.Status != StatusDepositPeriod) && (proposal.Status != StatusVotingPeriod) {
|
||||||
return ErrAlreadyFinishedProposal(keeper.codespace, proposalID), false
|
return ErrAlreadyFinishedProposal(keeper.codespace, proposalID), false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -387,12 +388,12 @@ func (keeper Keeper) AddDeposit(ctx sdk.Context, proposalID uint64, depositorAdd
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update proposal
|
// Update proposal
|
||||||
proposal.SetTotalDeposit(proposal.GetTotalDeposit().Add(depositAmount))
|
proposal.TotalDeposit = proposal.TotalDeposit.Add(depositAmount)
|
||||||
keeper.SetProposal(ctx, proposal)
|
keeper.SetProposal(ctx, proposal)
|
||||||
|
|
||||||
// Check if deposit has provided sufficient total funds to transition the proposal into the voting period
|
// Check if deposit has provided sufficient total funds to transition the proposal into the voting period
|
||||||
activatedVotingPeriod := false
|
activatedVotingPeriod := false
|
||||||
if proposal.GetStatus() == StatusDepositPeriod && proposal.GetTotalDeposit().IsAllGTE(keeper.GetDepositParams(ctx).MinDeposit) {
|
if proposal.Status == StatusDepositPeriod && proposal.TotalDeposit.IsAllGTE(keeper.GetDepositParams(ctx).MinDeposit) {
|
||||||
keeper.activateVotingPeriod(ctx, proposal)
|
keeper.activateVotingPeriod(ctx, proposal)
|
||||||
activatedVotingPeriod = true
|
activatedVotingPeriod = true
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,11 +19,14 @@ func TestGetSetProposal(t *testing.T) {
|
||||||
|
|
||||||
ctx := mapp.BaseApp.NewContext(false, abci.Header{})
|
ctx := mapp.BaseApp.NewContext(false, abci.Header{})
|
||||||
|
|
||||||
proposal := keeper.NewTextProposal(ctx, "Test", "description", ProposalTypeText)
|
tp := testProposal()
|
||||||
proposalID := proposal.GetProposalID()
|
proposal, err := keeper.SubmitProposal(ctx, tp)
|
||||||
|
require.NoError(t, err)
|
||||||
|
proposalID := proposal.ProposalID
|
||||||
keeper.SetProposal(ctx, proposal)
|
keeper.SetProposal(ctx, proposal)
|
||||||
|
|
||||||
gotProposal := keeper.GetProposal(ctx, proposalID)
|
gotProposal, ok := keeper.GetProposal(ctx, proposalID)
|
||||||
|
require.True(t, ok)
|
||||||
require.True(t, ProposalEqual(proposal, gotProposal))
|
require.True(t, ProposalEqual(proposal, gotProposal))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,14 +38,16 @@ func TestIncrementProposalNumber(t *testing.T) {
|
||||||
|
|
||||||
ctx := mapp.BaseApp.NewContext(false, abci.Header{})
|
ctx := mapp.BaseApp.NewContext(false, abci.Header{})
|
||||||
|
|
||||||
keeper.NewTextProposal(ctx, "Test", "description", ProposalTypeText)
|
tp := testProposal()
|
||||||
keeper.NewTextProposal(ctx, "Test", "description", ProposalTypeText)
|
keeper.SubmitProposal(ctx, tp)
|
||||||
keeper.NewTextProposal(ctx, "Test", "description", ProposalTypeText)
|
keeper.SubmitProposal(ctx, tp)
|
||||||
keeper.NewTextProposal(ctx, "Test", "description", ProposalTypeText)
|
keeper.SubmitProposal(ctx, tp)
|
||||||
keeper.NewTextProposal(ctx, "Test", "description", ProposalTypeText)
|
keeper.SubmitProposal(ctx, tp)
|
||||||
proposal6 := keeper.NewTextProposal(ctx, "Test", "description", ProposalTypeText)
|
keeper.SubmitProposal(ctx, tp)
|
||||||
|
proposal6, err := keeper.SubmitProposal(ctx, tp)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
require.Equal(t, uint64(6), proposal6.GetProposalID())
|
require.Equal(t, uint64(6), proposal6.ProposalID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestActivateVotingPeriod(t *testing.T) {
|
func TestActivateVotingPeriod(t *testing.T) {
|
||||||
|
@ -52,19 +57,25 @@ func TestActivateVotingPeriod(t *testing.T) {
|
||||||
mapp.BeginBlock(abci.RequestBeginBlock{Header: header})
|
mapp.BeginBlock(abci.RequestBeginBlock{Header: header})
|
||||||
|
|
||||||
ctx := mapp.BaseApp.NewContext(false, abci.Header{})
|
ctx := mapp.BaseApp.NewContext(false, abci.Header{})
|
||||||
proposal := keeper.NewTextProposal(ctx, "Test", "description", ProposalTypeText)
|
|
||||||
|
|
||||||
require.True(t, proposal.GetVotingStartTime().Equal(time.Time{}))
|
tp := testProposal()
|
||||||
|
proposal, err := keeper.SubmitProposal(ctx, tp)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
require.True(t, proposal.VotingStartTime.Equal(time.Time{}))
|
||||||
|
|
||||||
keeper.activateVotingPeriod(ctx, proposal)
|
keeper.activateVotingPeriod(ctx, proposal)
|
||||||
|
|
||||||
require.True(t, proposal.GetVotingStartTime().Equal(ctx.BlockHeader().Time))
|
require.True(t, proposal.VotingStartTime.Equal(ctx.BlockHeader().Time))
|
||||||
|
|
||||||
activeIterator := keeper.ActiveProposalQueueIterator(ctx, proposal.GetVotingEndTime())
|
proposal, ok := keeper.GetProposal(ctx, proposal.ProposalID)
|
||||||
|
require.True(t, ok)
|
||||||
|
|
||||||
|
activeIterator := keeper.ActiveProposalQueueIterator(ctx, proposal.VotingEndTime)
|
||||||
require.True(t, activeIterator.Valid())
|
require.True(t, activeIterator.Valid())
|
||||||
var proposalID uint64
|
var proposalID uint64
|
||||||
keeper.cdc.UnmarshalBinaryLengthPrefixed(activeIterator.Value(), &proposalID)
|
keeper.cdc.UnmarshalBinaryLengthPrefixed(activeIterator.Value(), &proposalID)
|
||||||
require.Equal(t, proposalID, proposal.GetProposalID())
|
require.Equal(t, proposalID, proposal.ProposalID)
|
||||||
activeIterator.Close()
|
activeIterator.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,8 +87,11 @@ func TestDeposits(t *testing.T) {
|
||||||
mapp.BeginBlock(abci.RequestBeginBlock{Header: header})
|
mapp.BeginBlock(abci.RequestBeginBlock{Header: header})
|
||||||
|
|
||||||
ctx := mapp.BaseApp.NewContext(false, abci.Header{})
|
ctx := mapp.BaseApp.NewContext(false, abci.Header{})
|
||||||
proposal := keeper.NewTextProposal(ctx, "Test", "description", ProposalTypeText)
|
|
||||||
proposalID := proposal.GetProposalID()
|
tp := testProposal()
|
||||||
|
proposal, err := keeper.SubmitProposal(ctx, tp)
|
||||||
|
require.NoError(t, err)
|
||||||
|
proposalID := proposal.ProposalID
|
||||||
|
|
||||||
fourStake := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.TokensFromTendermintPower(4)))
|
fourStake := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.TokensFromTendermintPower(4)))
|
||||||
fiveStake := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.TokensFromTendermintPower(5)))
|
fiveStake := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.TokensFromTendermintPower(5)))
|
||||||
|
@ -87,12 +101,14 @@ func TestDeposits(t *testing.T) {
|
||||||
|
|
||||||
expTokens := sdk.TokensFromTendermintPower(42)
|
expTokens := sdk.TokensFromTendermintPower(42)
|
||||||
require.Equal(t, sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, expTokens)), addr0Initial)
|
require.Equal(t, sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, expTokens)), addr0Initial)
|
||||||
require.True(t, proposal.GetTotalDeposit().IsEqual(sdk.NewCoins()))
|
require.True(t, proposal.TotalDeposit.IsEqual(sdk.NewCoins()))
|
||||||
|
|
||||||
// Check no deposits at beginning
|
// Check no deposits at beginning
|
||||||
deposit, found := keeper.GetDeposit(ctx, proposalID, addrs[1])
|
deposit, found := keeper.GetDeposit(ctx, proposalID, addrs[1])
|
||||||
require.False(t, found)
|
require.False(t, found)
|
||||||
require.True(t, keeper.GetProposal(ctx, proposalID).GetVotingStartTime().Equal(time.Time{}))
|
proposal, ok := keeper.GetProposal(ctx, proposalID)
|
||||||
|
require.True(t, ok)
|
||||||
|
require.True(t, proposal.VotingStartTime.Equal(time.Time{}))
|
||||||
|
|
||||||
// Check first deposit
|
// Check first deposit
|
||||||
err, votingStarted := keeper.AddDeposit(ctx, proposalID, addrs[0], fourStake)
|
err, votingStarted := keeper.AddDeposit(ctx, proposalID, addrs[0], fourStake)
|
||||||
|
@ -102,7 +118,9 @@ func TestDeposits(t *testing.T) {
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
require.Equal(t, fourStake, deposit.Amount)
|
require.Equal(t, fourStake, deposit.Amount)
|
||||||
require.Equal(t, addrs[0], deposit.Depositor)
|
require.Equal(t, addrs[0], deposit.Depositor)
|
||||||
require.Equal(t, fourStake, keeper.GetProposal(ctx, proposalID).GetTotalDeposit())
|
proposal, ok = keeper.GetProposal(ctx, proposalID)
|
||||||
|
require.True(t, ok)
|
||||||
|
require.Equal(t, fourStake, proposal.TotalDeposit)
|
||||||
require.Equal(t, addr0Initial.Sub(fourStake), keeper.ck.GetCoins(ctx, addrs[0]))
|
require.Equal(t, addr0Initial.Sub(fourStake), keeper.ck.GetCoins(ctx, addrs[0]))
|
||||||
|
|
||||||
// Check a second deposit from same address
|
// Check a second deposit from same address
|
||||||
|
@ -113,7 +131,9 @@ func TestDeposits(t *testing.T) {
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
require.Equal(t, fourStake.Add(fiveStake), deposit.Amount)
|
require.Equal(t, fourStake.Add(fiveStake), deposit.Amount)
|
||||||
require.Equal(t, addrs[0], deposit.Depositor)
|
require.Equal(t, addrs[0], deposit.Depositor)
|
||||||
require.Equal(t, fourStake.Add(fiveStake), keeper.GetProposal(ctx, proposalID).GetTotalDeposit())
|
proposal, ok = keeper.GetProposal(ctx, proposalID)
|
||||||
|
require.True(t, ok)
|
||||||
|
require.Equal(t, fourStake.Add(fiveStake), proposal.TotalDeposit)
|
||||||
require.Equal(t, addr0Initial.Sub(fourStake).Sub(fiveStake), keeper.ck.GetCoins(ctx, addrs[0]))
|
require.Equal(t, addr0Initial.Sub(fourStake).Sub(fiveStake), keeper.ck.GetCoins(ctx, addrs[0]))
|
||||||
|
|
||||||
// Check third deposit from a new address
|
// Check third deposit from a new address
|
||||||
|
@ -124,11 +144,15 @@ func TestDeposits(t *testing.T) {
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
require.Equal(t, addrs[1], deposit.Depositor)
|
require.Equal(t, addrs[1], deposit.Depositor)
|
||||||
require.Equal(t, fourStake, deposit.Amount)
|
require.Equal(t, fourStake, deposit.Amount)
|
||||||
require.Equal(t, fourStake.Add(fiveStake).Add(fourStake), keeper.GetProposal(ctx, proposalID).GetTotalDeposit())
|
proposal, ok = keeper.GetProposal(ctx, proposalID)
|
||||||
|
require.True(t, ok)
|
||||||
|
require.Equal(t, fourStake.Add(fiveStake).Add(fourStake), proposal.TotalDeposit)
|
||||||
require.Equal(t, addr1Initial.Sub(fourStake), keeper.ck.GetCoins(ctx, addrs[1]))
|
require.Equal(t, addr1Initial.Sub(fourStake), keeper.ck.GetCoins(ctx, addrs[1]))
|
||||||
|
|
||||||
// Check that proposal moved to voting period
|
// Check that proposal moved to voting period
|
||||||
require.True(t, keeper.GetProposal(ctx, proposalID).GetVotingStartTime().Equal(ctx.BlockHeader().Time))
|
proposal, ok = keeper.GetProposal(ctx, proposalID)
|
||||||
|
require.True(t, ok)
|
||||||
|
require.True(t, proposal.VotingStartTime.Equal(ctx.BlockHeader().Time))
|
||||||
|
|
||||||
// Test deposit iterator
|
// Test deposit iterator
|
||||||
depositsIterator := keeper.GetDeposits(ctx, proposalID)
|
depositsIterator := keeper.GetDeposits(ctx, proposalID)
|
||||||
|
@ -164,10 +188,13 @@ func TestVotes(t *testing.T) {
|
||||||
mapp.BeginBlock(abci.RequestBeginBlock{Header: header})
|
mapp.BeginBlock(abci.RequestBeginBlock{Header: header})
|
||||||
|
|
||||||
ctx := mapp.BaseApp.NewContext(false, abci.Header{})
|
ctx := mapp.BaseApp.NewContext(false, abci.Header{})
|
||||||
proposal := keeper.NewTextProposal(ctx, "Test", "description", ProposalTypeText)
|
|
||||||
proposalID := proposal.GetProposalID()
|
|
||||||
|
|
||||||
proposal.SetStatus(StatusVotingPeriod)
|
tp := testProposal()
|
||||||
|
proposal, err := keeper.SubmitProposal(ctx, tp)
|
||||||
|
require.NoError(t, err)
|
||||||
|
proposalID := proposal.ProposalID
|
||||||
|
|
||||||
|
proposal.Status = StatusVotingPeriod
|
||||||
keeper.SetProposal(ctx, proposal)
|
keeper.SetProposal(ctx, proposal)
|
||||||
|
|
||||||
// Test first vote
|
// Test first vote
|
||||||
|
@ -224,20 +251,25 @@ func TestProposalQueues(t *testing.T) {
|
||||||
mapp.InitChainer(ctx, abci.RequestInitChain{})
|
mapp.InitChainer(ctx, abci.RequestInitChain{})
|
||||||
|
|
||||||
// create test proposals
|
// create test proposals
|
||||||
proposal := keeper.NewTextProposal(ctx, "Test", "description", ProposalTypeText)
|
tp := testProposal()
|
||||||
|
proposal, err := keeper.SubmitProposal(ctx, tp)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
inactiveIterator := keeper.InactiveProposalQueueIterator(ctx, proposal.GetDepositEndTime())
|
inactiveIterator := keeper.InactiveProposalQueueIterator(ctx, proposal.DepositEndTime)
|
||||||
require.True(t, inactiveIterator.Valid())
|
require.True(t, inactiveIterator.Valid())
|
||||||
var proposalID uint64
|
var proposalID uint64
|
||||||
keeper.cdc.UnmarshalBinaryLengthPrefixed(inactiveIterator.Value(), &proposalID)
|
keeper.cdc.UnmarshalBinaryLengthPrefixed(inactiveIterator.Value(), &proposalID)
|
||||||
require.Equal(t, proposalID, proposal.GetProposalID())
|
require.Equal(t, proposalID, proposal.ProposalID)
|
||||||
inactiveIterator.Close()
|
inactiveIterator.Close()
|
||||||
|
|
||||||
keeper.activateVotingPeriod(ctx, proposal)
|
keeper.activateVotingPeriod(ctx, proposal)
|
||||||
|
|
||||||
activeIterator := keeper.ActiveProposalQueueIterator(ctx, proposal.GetVotingEndTime())
|
proposal, ok := keeper.GetProposal(ctx, proposal.ProposalID)
|
||||||
|
require.True(t, ok)
|
||||||
|
|
||||||
|
activeIterator := keeper.ActiveProposalQueueIterator(ctx, proposal.VotingEndTime)
|
||||||
require.True(t, activeIterator.Valid())
|
require.True(t, activeIterator.Valid())
|
||||||
keeper.cdc.UnmarshalBinaryLengthPrefixed(activeIterator.Value(), &proposalID)
|
keeper.cdc.UnmarshalBinaryLengthPrefixed(activeIterator.Value(), &proposalID)
|
||||||
require.Equal(t, proposalID, proposal.GetProposalID())
|
require.Equal(t, proposalID, proposal.ProposalID)
|
||||||
activeIterator.Close()
|
activeIterator.Close()
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,81 +9,12 @@ import (
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Proposal interface
|
// Proposal is a struct used by gov module internally
|
||||||
type Proposal interface {
|
// embedds ProposalContent with additional fields to record the status of the proposal process
|
||||||
GetProposalID() uint64
|
type Proposal struct {
|
||||||
SetProposalID(uint64)
|
ProposalContent `json:"proposal_content"` // Proposal content interface
|
||||||
|
|
||||||
GetTitle() string
|
ProposalID uint64 `json:"proposal_id"` // ID of the proposal
|
||||||
SetTitle(string)
|
|
||||||
|
|
||||||
GetDescription() string
|
|
||||||
SetDescription(string)
|
|
||||||
|
|
||||||
GetProposalType() ProposalKind
|
|
||||||
SetProposalType(ProposalKind)
|
|
||||||
|
|
||||||
GetStatus() ProposalStatus
|
|
||||||
SetStatus(ProposalStatus)
|
|
||||||
|
|
||||||
GetFinalTallyResult() TallyResult
|
|
||||||
SetFinalTallyResult(TallyResult)
|
|
||||||
|
|
||||||
GetSubmitTime() time.Time
|
|
||||||
SetSubmitTime(time.Time)
|
|
||||||
|
|
||||||
GetDepositEndTime() time.Time
|
|
||||||
SetDepositEndTime(time.Time)
|
|
||||||
|
|
||||||
GetTotalDeposit() sdk.Coins
|
|
||||||
SetTotalDeposit(sdk.Coins)
|
|
||||||
|
|
||||||
GetVotingStartTime() time.Time
|
|
||||||
SetVotingStartTime(time.Time)
|
|
||||||
|
|
||||||
GetVotingEndTime() time.Time
|
|
||||||
SetVotingEndTime(time.Time)
|
|
||||||
|
|
||||||
String() string
|
|
||||||
}
|
|
||||||
|
|
||||||
// Proposals is an array of proposal
|
|
||||||
type Proposals []Proposal
|
|
||||||
|
|
||||||
func (p Proposals) String() string {
|
|
||||||
out := "ID - (Status) [Type] Title\n"
|
|
||||||
for _, prop := range p {
|
|
||||||
out += fmt.Sprintf("%d - (%s) [%s] %s\n",
|
|
||||||
prop.GetProposalID(), prop.GetStatus(),
|
|
||||||
prop.GetProposalType(), prop.GetTitle())
|
|
||||||
}
|
|
||||||
return strings.TrimSpace(out)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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.GetFinalTallyResult().Equals(proposalB.GetFinalTallyResult()) &&
|
|
||||||
proposalA.GetSubmitTime().Equal(proposalB.GetSubmitTime()) &&
|
|
||||||
proposalA.GetDepositEndTime().Equal(proposalB.GetDepositEndTime()) &&
|
|
||||||
proposalA.GetTotalDeposit().IsEqual(proposalB.GetTotalDeposit()) &&
|
|
||||||
proposalA.GetVotingStartTime().Equal(proposalB.GetVotingStartTime()) &&
|
|
||||||
proposalA.GetVotingEndTime().Equal(proposalB.GetVotingEndTime()) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// Text Proposals
|
|
||||||
type TextProposal struct {
|
|
||||||
ProposalID uint64 `json:"proposal_id"` // ID of the proposal
|
|
||||||
Title string `json:"title"` // Title of the proposal
|
|
||||||
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}
|
||||||
FinalTallyResult TallyResult `json:"final_tally_result"` // Result of Tallys
|
FinalTallyResult TallyResult `json:"final_tally_result"` // Result of Tallys
|
||||||
|
@ -96,55 +27,83 @@ type TextProposal struct {
|
||||||
VotingEndTime time.Time `json:"voting_end_time"` // Time that the VotingPeriod for this proposal will end and votes will be tallied
|
VotingEndTime time.Time `json:"voting_end_time"` // Time that the VotingPeriod for this proposal will end and votes will be tallied
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implements Proposal Interface
|
// nolint
|
||||||
var _ Proposal = (*TextProposal)(nil)
|
func (p Proposal) String() string {
|
||||||
|
return fmt.Sprintf(`Proposal %d:
|
||||||
|
Title: %s
|
||||||
|
Type: %s
|
||||||
|
Status: %s
|
||||||
|
Submit Time: %s
|
||||||
|
Deposit End Time: %s
|
||||||
|
Total Deposit: %s
|
||||||
|
Voting Start Time: %s
|
||||||
|
Voting End Time: %s`, p.ProposalID, p.GetTitle(), p.ProposalType(),
|
||||||
|
p.Status, p.SubmitTime, p.DepositEndTime,
|
||||||
|
p.TotalDeposit, p.VotingStartTime, p.VotingEndTime)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ProposalContent is an interface that has title, description, and proposaltype
|
||||||
|
// that the governance module can use to identify them and generate human readable messages
|
||||||
|
// ProposalContent can have additional fields, which will handled by ProposalHandlers
|
||||||
|
// via type assertion, e.g. parameter change amount in ParameterChangeProposal
|
||||||
|
type ProposalContent interface {
|
||||||
|
GetTitle() string
|
||||||
|
GetDescription() string
|
||||||
|
ProposalType() ProposalKind
|
||||||
|
}
|
||||||
|
|
||||||
|
// Proposals is an array of proposal
|
||||||
|
type Proposals []Proposal
|
||||||
|
|
||||||
// nolint
|
// nolint
|
||||||
func (tp TextProposal) GetProposalID() uint64 { return tp.ProposalID }
|
func (p Proposals) String() string {
|
||||||
func (tp *TextProposal) SetProposalID(proposalID uint64) { tp.ProposalID = proposalID }
|
out := "ID - (Status) [Type] Title\n"
|
||||||
func (tp TextProposal) GetTitle() string { return tp.Title }
|
for _, prop := range p {
|
||||||
func (tp *TextProposal) SetTitle(title string) { tp.Title = title }
|
out += fmt.Sprintf("%d - (%s) [%s] %s\n",
|
||||||
func (tp TextProposal) GetDescription() string { return tp.Description }
|
prop.ProposalID, prop.Status,
|
||||||
func (tp *TextProposal) SetDescription(description string) { tp.Description = description }
|
prop.ProposalType(), prop.GetTitle())
|
||||||
func (tp TextProposal) GetProposalType() ProposalKind { return tp.ProposalType }
|
}
|
||||||
func (tp *TextProposal) SetProposalType(proposalType ProposalKind) { tp.ProposalType = proposalType }
|
return strings.TrimSpace(out)
|
||||||
func (tp TextProposal) GetStatus() ProposalStatus { return tp.Status }
|
|
||||||
func (tp *TextProposal) SetStatus(status ProposalStatus) { tp.Status = status }
|
|
||||||
func (tp TextProposal) GetFinalTallyResult() TallyResult { return tp.FinalTallyResult }
|
|
||||||
func (tp *TextProposal) SetFinalTallyResult(tallyResult TallyResult) {
|
|
||||||
tp.FinalTallyResult = tallyResult
|
|
||||||
}
|
|
||||||
func (tp TextProposal) GetSubmitTime() time.Time { return tp.SubmitTime }
|
|
||||||
func (tp *TextProposal) SetSubmitTime(submitTime time.Time) { tp.SubmitTime = submitTime }
|
|
||||||
func (tp TextProposal) GetDepositEndTime() time.Time { return tp.DepositEndTime }
|
|
||||||
func (tp *TextProposal) SetDepositEndTime(depositEndTime time.Time) {
|
|
||||||
tp.DepositEndTime = depositEndTime
|
|
||||||
}
|
|
||||||
func (tp TextProposal) GetTotalDeposit() sdk.Coins { return tp.TotalDeposit }
|
|
||||||
func (tp *TextProposal) SetTotalDeposit(totalDeposit sdk.Coins) { tp.TotalDeposit = totalDeposit }
|
|
||||||
func (tp TextProposal) GetVotingStartTime() time.Time { return tp.VotingStartTime }
|
|
||||||
func (tp *TextProposal) SetVotingStartTime(votingStartTime time.Time) {
|
|
||||||
tp.VotingStartTime = votingStartTime
|
|
||||||
}
|
|
||||||
func (tp TextProposal) GetVotingEndTime() time.Time { return tp.VotingEndTime }
|
|
||||||
func (tp *TextProposal) SetVotingEndTime(votingEndTime time.Time) {
|
|
||||||
tp.VotingEndTime = votingEndTime
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tp TextProposal) String() string {
|
// Text Proposals
|
||||||
return fmt.Sprintf(`Proposal %d:
|
type TextProposal struct {
|
||||||
Title: %s
|
Title string `json:"title"` // Title of the proposal
|
||||||
Type: %s
|
Description string `json:"description"` // Description of the proposal
|
||||||
Status: %s
|
|
||||||
Submit Time: %s
|
|
||||||
Deposit End Time: %s
|
|
||||||
Total Deposit: %s
|
|
||||||
Voting Start Time: %s
|
|
||||||
Voting End Time: %s`, tp.ProposalID, tp.Title, tp.ProposalType,
|
|
||||||
tp.Status, tp.SubmitTime, tp.DepositEndTime,
|
|
||||||
tp.TotalDeposit, tp.VotingStartTime, tp.VotingEndTime)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewTextProposal(title, description string) TextProposal {
|
||||||
|
return TextProposal{
|
||||||
|
Title: title,
|
||||||
|
Description: description,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Implements Proposal Interface
|
||||||
|
var _ ProposalContent = TextProposal{}
|
||||||
|
|
||||||
|
// nolint
|
||||||
|
func (tp TextProposal) GetTitle() string { return tp.Title }
|
||||||
|
func (tp TextProposal) GetDescription() string { return tp.Description }
|
||||||
|
func (tp TextProposal) ProposalType() ProposalKind { return ProposalTypeText }
|
||||||
|
|
||||||
|
// Software Upgrade Proposals
|
||||||
|
type SoftwareUpgradeProposal struct {
|
||||||
|
TextProposal
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewSoftwareUpgradeProposal(title, description string) SoftwareUpgradeProposal {
|
||||||
|
return SoftwareUpgradeProposal{
|
||||||
|
TextProposal: NewTextProposal(title, description),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Implements Proposal Interface
|
||||||
|
var _ ProposalContent = SoftwareUpgradeProposal{}
|
||||||
|
|
||||||
|
// nolint
|
||||||
|
func (sup SoftwareUpgradeProposal) ProposalType() ProposalKind { return ProposalTypeSoftwareUpgrade }
|
||||||
|
|
||||||
// ProposalQueue
|
// ProposalQueue
|
||||||
type ProposalQueue []uint64
|
type ProposalQueue []uint64
|
||||||
|
|
||||||
|
|
|
@ -99,8 +99,8 @@ func queryProposal(ctx sdk.Context, path []string, req abci.RequestQuery, keeper
|
||||||
return nil, sdk.ErrUnknownRequest(sdk.AppendMsgToErr("incorrectly formatted request data", err.Error()))
|
return nil, sdk.ErrUnknownRequest(sdk.AppendMsgToErr("incorrectly formatted request data", err.Error()))
|
||||||
}
|
}
|
||||||
|
|
||||||
proposal := keeper.GetProposal(ctx, params.ProposalID)
|
proposal, ok := keeper.GetProposal(ctx, params.ProposalID)
|
||||||
if proposal == nil {
|
if !ok {
|
||||||
return nil, ErrUnknownProposal(DefaultCodespace, params.ProposalID)
|
return nil, ErrUnknownProposal(DefaultCodespace, params.ProposalID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -205,17 +205,17 @@ func queryTally(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Ke
|
||||||
|
|
||||||
proposalID := params.ProposalID
|
proposalID := params.ProposalID
|
||||||
|
|
||||||
proposal := keeper.GetProposal(ctx, proposalID)
|
proposal, ok := keeper.GetProposal(ctx, proposalID)
|
||||||
if proposal == nil {
|
if !ok {
|
||||||
return nil, ErrUnknownProposal(DefaultCodespace, proposalID)
|
return nil, ErrUnknownProposal(DefaultCodespace, proposalID)
|
||||||
}
|
}
|
||||||
|
|
||||||
var tallyResult TallyResult
|
var tallyResult TallyResult
|
||||||
|
|
||||||
if proposal.GetStatus() == StatusDepositPeriod {
|
if proposal.Status == StatusDepositPeriod {
|
||||||
tallyResult = EmptyTallyResult()
|
tallyResult = EmptyTallyResult()
|
||||||
} else if proposal.GetStatus() == StatusPassed || proposal.GetStatus() == StatusRejected {
|
} else if proposal.Status == StatusPassed || proposal.Status == StatusRejected {
|
||||||
tallyResult = proposal.GetFinalTallyResult()
|
tallyResult = proposal.FinalTallyResult
|
||||||
} else {
|
} else {
|
||||||
// proposal is in voting period
|
// proposal is in voting period
|
||||||
_, tallyResult = tally(ctx, keeper, proposal)
|
_, tallyResult = tally(ctx, keeper, proposal)
|
||||||
|
|
|
@ -227,12 +227,12 @@ func testQueries(t *testing.T) {
|
||||||
// Only proposal #1 should be in Deposit Period
|
// Only proposal #1 should be in Deposit Period
|
||||||
proposals := getQueriedProposals(t, ctx, cdc, querier, nil, nil, StatusDepositPeriod, 0)
|
proposals := getQueriedProposals(t, ctx, cdc, querier, nil, nil, StatusDepositPeriod, 0)
|
||||||
require.Len(t, proposals, 1)
|
require.Len(t, proposals, 1)
|
||||||
require.Equal(t, proposalID1, proposals[0].GetProposalID())
|
require.Equal(t, proposalID1, proposals[0].ProposalID)
|
||||||
// Only proposals #2 and #3 should be in Voting Period
|
// Only proposals #2 and #3 should be in Voting Period
|
||||||
proposals = getQueriedProposals(t, ctx, cdc, querier, nil, nil, StatusVotingPeriod, 0)
|
proposals = getQueriedProposals(t, ctx, cdc, querier, nil, nil, StatusVotingPeriod, 0)
|
||||||
require.Len(t, proposals, 2)
|
require.Len(t, proposals, 2)
|
||||||
require.Equal(t, proposalID2, proposals[0].GetProposalID())
|
require.Equal(t, proposalID2, proposals[0].ProposalID)
|
||||||
require.Equal(t, proposalID3, proposals[1].GetProposalID())
|
require.Equal(t, proposalID3, proposals[1].ProposalID)
|
||||||
|
|
||||||
// Addrs[0] votes on proposals #2 & #3
|
// Addrs[0] votes on proposals #2 & #3
|
||||||
handler(ctx, NewMsgVote(addrs[0], proposalID2, OptionYes))
|
handler(ctx, NewMsgVote(addrs[0], proposalID2, OptionYes))
|
||||||
|
@ -243,8 +243,8 @@ func testQueries(t *testing.T) {
|
||||||
|
|
||||||
// Test query voted by addrs[0]
|
// Test query voted by addrs[0]
|
||||||
proposals = getQueriedProposals(t, ctx, cdc, querier, nil, addrs[0], StatusNil, 0)
|
proposals = getQueriedProposals(t, ctx, cdc, querier, nil, addrs[0], StatusNil, 0)
|
||||||
require.Equal(t, proposalID2, (proposals[0]).GetProposalID())
|
require.Equal(t, proposalID2, (proposals[0]).ProposalID)
|
||||||
require.Equal(t, proposalID3, (proposals[1]).GetProposalID())
|
require.Equal(t, proposalID3, (proposals[1]).ProposalID)
|
||||||
|
|
||||||
// Test query votes on Proposal 2
|
// Test query votes on Proposal 2
|
||||||
votes := getQueriedVotes(t, ctx, cdc, querier, proposalID2)
|
votes := getQueriedVotes(t, ctx, cdc, querier, proposalID2)
|
||||||
|
@ -263,26 +263,26 @@ func testQueries(t *testing.T) {
|
||||||
|
|
||||||
// Test query all proposals
|
// Test query all proposals
|
||||||
proposals = getQueriedProposals(t, ctx, cdc, querier, nil, nil, StatusNil, 0)
|
proposals = getQueriedProposals(t, ctx, cdc, querier, nil, nil, StatusNil, 0)
|
||||||
require.Equal(t, proposalID1, (proposals[0]).GetProposalID())
|
require.Equal(t, proposalID1, (proposals[0]).ProposalID)
|
||||||
require.Equal(t, proposalID2, (proposals[1]).GetProposalID())
|
require.Equal(t, proposalID2, (proposals[1]).ProposalID)
|
||||||
require.Equal(t, proposalID3, (proposals[2]).GetProposalID())
|
require.Equal(t, proposalID3, (proposals[2]).ProposalID)
|
||||||
|
|
||||||
// Test query voted by addrs[1]
|
// Test query voted by addrs[1]
|
||||||
proposals = getQueriedProposals(t, ctx, cdc, querier, nil, addrs[1], StatusNil, 0)
|
proposals = getQueriedProposals(t, ctx, cdc, querier, nil, addrs[1], StatusNil, 0)
|
||||||
require.Equal(t, proposalID3, (proposals[0]).GetProposalID())
|
require.Equal(t, proposalID3, (proposals[0]).ProposalID)
|
||||||
|
|
||||||
// Test query deposited by addrs[0]
|
// Test query deposited by addrs[0]
|
||||||
proposals = getQueriedProposals(t, ctx, cdc, querier, addrs[0], nil, StatusNil, 0)
|
proposals = getQueriedProposals(t, ctx, cdc, querier, addrs[0], nil, StatusNil, 0)
|
||||||
require.Equal(t, proposalID1, (proposals[0]).GetProposalID())
|
require.Equal(t, proposalID1, (proposals[0]).ProposalID)
|
||||||
|
|
||||||
// Test query deposited by addr2
|
// Test query deposited by addr2
|
||||||
proposals = getQueriedProposals(t, ctx, cdc, querier, addrs[1], nil, StatusNil, 0)
|
proposals = getQueriedProposals(t, ctx, cdc, querier, addrs[1], nil, StatusNil, 0)
|
||||||
require.Equal(t, proposalID2, (proposals[0]).GetProposalID())
|
require.Equal(t, proposalID2, (proposals[0]).ProposalID)
|
||||||
require.Equal(t, proposalID3, (proposals[1]).GetProposalID())
|
require.Equal(t, proposalID3, (proposals[1]).ProposalID)
|
||||||
|
|
||||||
// Test query voted AND deposited by addr1
|
// Test query voted AND deposited by addr1
|
||||||
proposals = getQueriedProposals(t, ctx, cdc, querier, addrs[0], addrs[0], StatusNil, 0)
|
proposals = getQueriedProposals(t, ctx, cdc, querier, addrs[0], addrs[0], StatusNil, 0)
|
||||||
require.Equal(t, proposalID2, (proposals[0]).GetProposalID())
|
require.Equal(t, proposalID2, (proposals[0]).ProposalID)
|
||||||
|
|
||||||
// Test Tally Query
|
// Test Tally Query
|
||||||
tally := getQueriedTally(t, ctx, cdc, querier, proposalID2)
|
tally := getQueriedTally(t, ctx, cdc, querier, proposalID2)
|
||||||
|
|
|
@ -49,7 +49,7 @@ func tally(ctx sdk.Context, keeper Keeper, proposal Proposal) (passes bool, tall
|
||||||
})
|
})
|
||||||
|
|
||||||
// iterate over all the votes
|
// iterate over all the votes
|
||||||
votesIterator := keeper.GetVotes(ctx, proposal.GetProposalID())
|
votesIterator := keeper.GetVotes(ctx, proposal.ProposalID)
|
||||||
defer votesIterator.Close()
|
defer votesIterator.Close()
|
||||||
for ; votesIterator.Valid(); votesIterator.Next() {
|
for ; votesIterator.Valid(); votesIterator.Next() {
|
||||||
vote := &Vote{}
|
vote := &Vote{}
|
||||||
|
|
|
@ -53,12 +53,16 @@ func TestTallyNoOneVotes(t *testing.T) {
|
||||||
createValidators(t, stakingHandler, ctx, valAddrs, []int64{5, 5})
|
createValidators(t, stakingHandler, ctx, valAddrs, []int64{5, 5})
|
||||||
staking.EndBlocker(ctx, sk)
|
staking.EndBlocker(ctx, sk)
|
||||||
|
|
||||||
proposal := keeper.NewTextProposal(ctx, "Test", "description", ProposalTypeText)
|
tp := TextProposal{"Test", "description"}
|
||||||
proposalID := proposal.GetProposalID()
|
proposal, err := keeper.SubmitProposal(ctx, tp)
|
||||||
proposal.SetStatus(StatusVotingPeriod)
|
require.NoError(t, err)
|
||||||
|
proposalID := proposal.ProposalID
|
||||||
|
proposal.Status = StatusVotingPeriod
|
||||||
keeper.SetProposal(ctx, proposal)
|
keeper.SetProposal(ctx, proposal)
|
||||||
|
|
||||||
passes, tallyResults := tally(ctx, keeper, keeper.GetProposal(ctx, proposalID))
|
proposal, ok := keeper.GetProposal(ctx, proposalID)
|
||||||
|
require.True(t, ok)
|
||||||
|
passes, tallyResults := tally(ctx, keeper, proposal)
|
||||||
|
|
||||||
require.False(t, passes)
|
require.False(t, passes)
|
||||||
require.True(t, tallyResults.Equals(EmptyTallyResult()))
|
require.True(t, tallyResults.Equals(EmptyTallyResult()))
|
||||||
|
@ -81,15 +85,19 @@ func TestTallyNoQuorum(t *testing.T) {
|
||||||
createValidators(t, stakingHandler, ctx, valAddrs, []int64{2, 5})
|
createValidators(t, stakingHandler, ctx, valAddrs, []int64{2, 5})
|
||||||
staking.EndBlocker(ctx, sk)
|
staking.EndBlocker(ctx, sk)
|
||||||
|
|
||||||
proposal := keeper.NewTextProposal(ctx, "Test", "description", ProposalTypeText)
|
tp := TextProposal{"Test", "description"}
|
||||||
proposalID := proposal.GetProposalID()
|
proposal, err := keeper.SubmitProposal(ctx, tp)
|
||||||
proposal.SetStatus(StatusVotingPeriod)
|
require.NoError(t, err)
|
||||||
|
proposalID := proposal.ProposalID
|
||||||
|
proposal.Status = StatusVotingPeriod
|
||||||
keeper.SetProposal(ctx, proposal)
|
keeper.SetProposal(ctx, proposal)
|
||||||
|
|
||||||
err := keeper.AddVote(ctx, proposalID, addrs[0], OptionYes)
|
err = keeper.AddVote(ctx, proposalID, addrs[0], OptionYes)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
|
|
||||||
passes, _ := tally(ctx, keeper, keeper.GetProposal(ctx, proposalID))
|
proposal, ok := keeper.GetProposal(ctx, proposalID)
|
||||||
|
require.True(t, ok)
|
||||||
|
passes, _ := tally(ctx, keeper, proposal)
|
||||||
require.False(t, passes)
|
require.False(t, passes)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,17 +118,21 @@ func TestTallyOnlyValidatorsAllYes(t *testing.T) {
|
||||||
createValidators(t, stakingHandler, ctx, valAddrs, []int64{5, 5})
|
createValidators(t, stakingHandler, ctx, valAddrs, []int64{5, 5})
|
||||||
staking.EndBlocker(ctx, sk)
|
staking.EndBlocker(ctx, sk)
|
||||||
|
|
||||||
proposal := keeper.NewTextProposal(ctx, "Test", "description", ProposalTypeText)
|
tp := TextProposal{"Test", "description"}
|
||||||
proposalID := proposal.GetProposalID()
|
proposal, err := keeper.SubmitProposal(ctx, tp)
|
||||||
proposal.SetStatus(StatusVotingPeriod)
|
require.NoError(t, err)
|
||||||
|
proposalID := proposal.ProposalID
|
||||||
|
proposal.Status = StatusVotingPeriod
|
||||||
keeper.SetProposal(ctx, proposal)
|
keeper.SetProposal(ctx, proposal)
|
||||||
|
|
||||||
err := keeper.AddVote(ctx, proposalID, addrs[0], OptionYes)
|
err = keeper.AddVote(ctx, proposalID, addrs[0], OptionYes)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
err = keeper.AddVote(ctx, proposalID, addrs[1], OptionYes)
|
err = keeper.AddVote(ctx, proposalID, addrs[1], OptionYes)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
|
|
||||||
passes, tallyResults := tally(ctx, keeper, keeper.GetProposal(ctx, proposalID))
|
proposal, ok := keeper.GetProposal(ctx, proposalID)
|
||||||
|
require.True(t, ok)
|
||||||
|
passes, tallyResults := tally(ctx, keeper, proposal)
|
||||||
|
|
||||||
require.True(t, passes)
|
require.True(t, passes)
|
||||||
require.False(t, tallyResults.Equals(EmptyTallyResult()))
|
require.False(t, tallyResults.Equals(EmptyTallyResult()))
|
||||||
|
@ -143,17 +155,21 @@ func TestTallyOnlyValidators51No(t *testing.T) {
|
||||||
createValidators(t, stakingHandler, ctx, valAddrs, []int64{5, 6})
|
createValidators(t, stakingHandler, ctx, valAddrs, []int64{5, 6})
|
||||||
staking.EndBlocker(ctx, sk)
|
staking.EndBlocker(ctx, sk)
|
||||||
|
|
||||||
proposal := keeper.NewTextProposal(ctx, "Test", "description", ProposalTypeText)
|
tp := TextProposal{"Test", "description"}
|
||||||
proposalID := proposal.GetProposalID()
|
proposal, err := keeper.SubmitProposal(ctx, tp)
|
||||||
proposal.SetStatus(StatusVotingPeriod)
|
require.NoError(t, err)
|
||||||
|
proposalID := proposal.ProposalID
|
||||||
|
proposal.Status = StatusVotingPeriod
|
||||||
keeper.SetProposal(ctx, proposal)
|
keeper.SetProposal(ctx, proposal)
|
||||||
|
|
||||||
err := keeper.AddVote(ctx, proposalID, addrs[0], OptionYes)
|
err = keeper.AddVote(ctx, proposalID, addrs[0], OptionYes)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
err = keeper.AddVote(ctx, proposalID, addrs[1], OptionNo)
|
err = keeper.AddVote(ctx, proposalID, addrs[1], OptionNo)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
|
|
||||||
passes, _ := tally(ctx, keeper, keeper.GetProposal(ctx, proposalID))
|
proposal, ok := keeper.GetProposal(ctx, proposalID)
|
||||||
|
require.True(t, ok)
|
||||||
|
passes, _ := tally(ctx, keeper, proposal)
|
||||||
|
|
||||||
require.False(t, passes)
|
require.False(t, passes)
|
||||||
}
|
}
|
||||||
|
@ -175,19 +191,23 @@ func TestTallyOnlyValidators51Yes(t *testing.T) {
|
||||||
createValidators(t, stakingHandler, ctx, valAddrs, []int64{6, 6, 7})
|
createValidators(t, stakingHandler, ctx, valAddrs, []int64{6, 6, 7})
|
||||||
staking.EndBlocker(ctx, sk)
|
staking.EndBlocker(ctx, sk)
|
||||||
|
|
||||||
proposal := keeper.NewTextProposal(ctx, "Test", "description", ProposalTypeText)
|
tp := TextProposal{"Test", "description"}
|
||||||
proposalID := proposal.GetProposalID()
|
proposal, err := keeper.SubmitProposal(ctx, tp)
|
||||||
proposal.SetStatus(StatusVotingPeriod)
|
require.NoError(t, err)
|
||||||
|
proposalID := proposal.ProposalID
|
||||||
|
proposal.Status = StatusVotingPeriod
|
||||||
keeper.SetProposal(ctx, proposal)
|
keeper.SetProposal(ctx, proposal)
|
||||||
|
|
||||||
err := keeper.AddVote(ctx, proposalID, addrs[0], OptionYes)
|
err = keeper.AddVote(ctx, proposalID, addrs[0], OptionYes)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
err = keeper.AddVote(ctx, proposalID, addrs[1], OptionYes)
|
err = keeper.AddVote(ctx, proposalID, addrs[1], OptionYes)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
err = keeper.AddVote(ctx, proposalID, addrs[2], OptionNo)
|
err = keeper.AddVote(ctx, proposalID, addrs[2], OptionNo)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
|
|
||||||
passes, tallyResults := tally(ctx, keeper, keeper.GetProposal(ctx, proposalID))
|
proposal, ok := keeper.GetProposal(ctx, proposalID)
|
||||||
|
require.True(t, ok)
|
||||||
|
passes, tallyResults := tally(ctx, keeper, proposal)
|
||||||
|
|
||||||
require.True(t, passes)
|
require.True(t, passes)
|
||||||
require.False(t, tallyResults.Equals(EmptyTallyResult()))
|
require.False(t, tallyResults.Equals(EmptyTallyResult()))
|
||||||
|
@ -210,19 +230,23 @@ func TestTallyOnlyValidatorsVetoed(t *testing.T) {
|
||||||
createValidators(t, stakingHandler, ctx, valAddrs, []int64{6, 6, 7})
|
createValidators(t, stakingHandler, ctx, valAddrs, []int64{6, 6, 7})
|
||||||
staking.EndBlocker(ctx, sk)
|
staking.EndBlocker(ctx, sk)
|
||||||
|
|
||||||
proposal := keeper.NewTextProposal(ctx, "Test", "description", ProposalTypeText)
|
tp := TextProposal{"Test", "description"}
|
||||||
proposalID := proposal.GetProposalID()
|
proposal, err := keeper.SubmitProposal(ctx, tp)
|
||||||
proposal.SetStatus(StatusVotingPeriod)
|
require.NoError(t, err)
|
||||||
|
proposalID := proposal.ProposalID
|
||||||
|
proposal.Status = StatusVotingPeriod
|
||||||
keeper.SetProposal(ctx, proposal)
|
keeper.SetProposal(ctx, proposal)
|
||||||
|
|
||||||
err := keeper.AddVote(ctx, proposalID, addrs[0], OptionYes)
|
err = keeper.AddVote(ctx, proposalID, addrs[0], OptionYes)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
err = keeper.AddVote(ctx, proposalID, addrs[1], OptionYes)
|
err = keeper.AddVote(ctx, proposalID, addrs[1], OptionYes)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
err = keeper.AddVote(ctx, proposalID, addrs[2], OptionNoWithVeto)
|
err = keeper.AddVote(ctx, proposalID, addrs[2], OptionNoWithVeto)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
|
|
||||||
passes, tallyResults := tally(ctx, keeper, keeper.GetProposal(ctx, proposalID))
|
proposal, ok := keeper.GetProposal(ctx, proposalID)
|
||||||
|
require.True(t, ok)
|
||||||
|
passes, tallyResults := tally(ctx, keeper, proposal)
|
||||||
|
|
||||||
require.False(t, passes)
|
require.False(t, passes)
|
||||||
require.False(t, tallyResults.Equals(EmptyTallyResult()))
|
require.False(t, tallyResults.Equals(EmptyTallyResult()))
|
||||||
|
@ -245,19 +269,23 @@ func TestTallyOnlyValidatorsAbstainPasses(t *testing.T) {
|
||||||
createValidators(t, stakingHandler, ctx, valAddrs, []int64{6, 6, 7})
|
createValidators(t, stakingHandler, ctx, valAddrs, []int64{6, 6, 7})
|
||||||
staking.EndBlocker(ctx, sk)
|
staking.EndBlocker(ctx, sk)
|
||||||
|
|
||||||
proposal := keeper.NewTextProposal(ctx, "Test", "description", ProposalTypeText)
|
tp := TextProposal{"Test", "description"}
|
||||||
proposalID := proposal.GetProposalID()
|
proposal, err := keeper.SubmitProposal(ctx, tp)
|
||||||
proposal.SetStatus(StatusVotingPeriod)
|
require.NoError(t, err)
|
||||||
|
proposalID := proposal.ProposalID
|
||||||
|
proposal.Status = StatusVotingPeriod
|
||||||
keeper.SetProposal(ctx, proposal)
|
keeper.SetProposal(ctx, proposal)
|
||||||
|
|
||||||
err := keeper.AddVote(ctx, proposalID, addrs[0], OptionAbstain)
|
err = keeper.AddVote(ctx, proposalID, addrs[0], OptionAbstain)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
err = keeper.AddVote(ctx, proposalID, addrs[1], OptionNo)
|
err = keeper.AddVote(ctx, proposalID, addrs[1], OptionNo)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
err = keeper.AddVote(ctx, proposalID, addrs[2], OptionYes)
|
err = keeper.AddVote(ctx, proposalID, addrs[2], OptionYes)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
|
|
||||||
passes, tallyResults := tally(ctx, keeper, keeper.GetProposal(ctx, proposalID))
|
proposal, ok := keeper.GetProposal(ctx, proposalID)
|
||||||
|
require.True(t, ok)
|
||||||
|
passes, tallyResults := tally(ctx, keeper, proposal)
|
||||||
|
|
||||||
require.True(t, passes)
|
require.True(t, passes)
|
||||||
require.False(t, tallyResults.Equals(EmptyTallyResult()))
|
require.False(t, tallyResults.Equals(EmptyTallyResult()))
|
||||||
|
@ -280,19 +308,23 @@ func TestTallyOnlyValidatorsAbstainFails(t *testing.T) {
|
||||||
createValidators(t, stakingHandler, ctx, valAddrs, []int64{6, 6, 7})
|
createValidators(t, stakingHandler, ctx, valAddrs, []int64{6, 6, 7})
|
||||||
staking.EndBlocker(ctx, sk)
|
staking.EndBlocker(ctx, sk)
|
||||||
|
|
||||||
proposal := keeper.NewTextProposal(ctx, "Test", "description", ProposalTypeText)
|
tp := TextProposal{"Test", "description"}
|
||||||
proposalID := proposal.GetProposalID()
|
proposal, err := keeper.SubmitProposal(ctx, tp)
|
||||||
proposal.SetStatus(StatusVotingPeriod)
|
require.NoError(t, err)
|
||||||
|
proposalID := proposal.ProposalID
|
||||||
|
proposal.Status = StatusVotingPeriod
|
||||||
keeper.SetProposal(ctx, proposal)
|
keeper.SetProposal(ctx, proposal)
|
||||||
|
|
||||||
err := keeper.AddVote(ctx, proposalID, addrs[0], OptionAbstain)
|
err = keeper.AddVote(ctx, proposalID, addrs[0], OptionAbstain)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
err = keeper.AddVote(ctx, proposalID, addrs[1], OptionYes)
|
err = keeper.AddVote(ctx, proposalID, addrs[1], OptionYes)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
err = keeper.AddVote(ctx, proposalID, addrs[2], OptionNo)
|
err = keeper.AddVote(ctx, proposalID, addrs[2], OptionNo)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
|
|
||||||
passes, tallyResults := tally(ctx, keeper, keeper.GetProposal(ctx, proposalID))
|
proposal, ok := keeper.GetProposal(ctx, proposalID)
|
||||||
|
require.True(t, ok)
|
||||||
|
passes, tallyResults := tally(ctx, keeper, proposal)
|
||||||
|
|
||||||
require.False(t, passes)
|
require.False(t, passes)
|
||||||
require.False(t, tallyResults.Equals(EmptyTallyResult()))
|
require.False(t, tallyResults.Equals(EmptyTallyResult()))
|
||||||
|
@ -315,17 +347,21 @@ func TestTallyOnlyValidatorsNonVoter(t *testing.T) {
|
||||||
createValidators(t, stakingHandler, ctx, valAddrs, []int64{6, 6, 7})
|
createValidators(t, stakingHandler, ctx, valAddrs, []int64{6, 6, 7})
|
||||||
staking.EndBlocker(ctx, sk)
|
staking.EndBlocker(ctx, sk)
|
||||||
|
|
||||||
proposal := keeper.NewTextProposal(ctx, "Test", "description", ProposalTypeText)
|
tp := TextProposal{"Test", "description"}
|
||||||
proposalID := proposal.GetProposalID()
|
proposal, err := keeper.SubmitProposal(ctx, tp)
|
||||||
proposal.SetStatus(StatusVotingPeriod)
|
require.NoError(t, err)
|
||||||
|
proposalID := proposal.ProposalID
|
||||||
|
proposal.Status = StatusVotingPeriod
|
||||||
keeper.SetProposal(ctx, proposal)
|
keeper.SetProposal(ctx, proposal)
|
||||||
|
|
||||||
err := keeper.AddVote(ctx, proposalID, addrs[1], OptionYes)
|
err = keeper.AddVote(ctx, proposalID, addrs[1], OptionYes)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
err = keeper.AddVote(ctx, proposalID, addrs[2], OptionNo)
|
err = keeper.AddVote(ctx, proposalID, addrs[2], OptionNo)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
|
|
||||||
passes, tallyResults := tally(ctx, keeper, keeper.GetProposal(ctx, proposalID))
|
proposal, ok := keeper.GetProposal(ctx, proposalID)
|
||||||
|
require.True(t, ok)
|
||||||
|
passes, tallyResults := tally(ctx, keeper, proposal)
|
||||||
|
|
||||||
require.False(t, passes)
|
require.False(t, passes)
|
||||||
require.False(t, tallyResults.Equals(EmptyTallyResult()))
|
require.False(t, tallyResults.Equals(EmptyTallyResult()))
|
||||||
|
@ -352,12 +388,14 @@ func TestTallyDelgatorOverride(t *testing.T) {
|
||||||
delegator1Msg := staking.NewMsgDelegate(addrs[3], sdk.ValAddress(addrs[2]), sdk.NewCoin(sdk.DefaultBondDenom, delTokens))
|
delegator1Msg := staking.NewMsgDelegate(addrs[3], sdk.ValAddress(addrs[2]), sdk.NewCoin(sdk.DefaultBondDenom, delTokens))
|
||||||
stakingHandler(ctx, delegator1Msg)
|
stakingHandler(ctx, delegator1Msg)
|
||||||
|
|
||||||
proposal := keeper.NewTextProposal(ctx, "Test", "description", ProposalTypeText)
|
tp := TextProposal{"Test", "description"}
|
||||||
proposalID := proposal.GetProposalID()
|
proposal, err := keeper.SubmitProposal(ctx, tp)
|
||||||
proposal.SetStatus(StatusVotingPeriod)
|
require.NoError(t, err)
|
||||||
|
proposalID := proposal.ProposalID
|
||||||
|
proposal.Status = StatusVotingPeriod
|
||||||
keeper.SetProposal(ctx, proposal)
|
keeper.SetProposal(ctx, proposal)
|
||||||
|
|
||||||
err := keeper.AddVote(ctx, proposalID, addrs[0], OptionYes)
|
err = keeper.AddVote(ctx, proposalID, addrs[0], OptionYes)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
err = keeper.AddVote(ctx, proposalID, addrs[1], OptionYes)
|
err = keeper.AddVote(ctx, proposalID, addrs[1], OptionYes)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
|
@ -366,7 +404,9 @@ func TestTallyDelgatorOverride(t *testing.T) {
|
||||||
err = keeper.AddVote(ctx, proposalID, addrs[3], OptionNo)
|
err = keeper.AddVote(ctx, proposalID, addrs[3], OptionNo)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
|
|
||||||
passes, tallyResults := tally(ctx, keeper, keeper.GetProposal(ctx, proposalID))
|
proposal, ok := keeper.GetProposal(ctx, proposalID)
|
||||||
|
require.True(t, ok)
|
||||||
|
passes, tallyResults := tally(ctx, keeper, proposal)
|
||||||
|
|
||||||
require.False(t, passes)
|
require.False(t, passes)
|
||||||
require.False(t, tallyResults.Equals(EmptyTallyResult()))
|
require.False(t, tallyResults.Equals(EmptyTallyResult()))
|
||||||
|
@ -393,19 +433,23 @@ func TestTallyDelgatorInherit(t *testing.T) {
|
||||||
delegator1Msg := staking.NewMsgDelegate(addrs[3], sdk.ValAddress(addrs[2]), sdk.NewCoin(sdk.DefaultBondDenom, delTokens))
|
delegator1Msg := staking.NewMsgDelegate(addrs[3], sdk.ValAddress(addrs[2]), sdk.NewCoin(sdk.DefaultBondDenom, delTokens))
|
||||||
stakingHandler(ctx, delegator1Msg)
|
stakingHandler(ctx, delegator1Msg)
|
||||||
|
|
||||||
proposal := keeper.NewTextProposal(ctx, "Test", "description", ProposalTypeText)
|
tp := TextProposal{"Test", "description"}
|
||||||
proposalID := proposal.GetProposalID()
|
proposal, err := keeper.SubmitProposal(ctx, tp)
|
||||||
proposal.SetStatus(StatusVotingPeriod)
|
require.NoError(t, err)
|
||||||
|
proposalID := proposal.ProposalID
|
||||||
|
proposal.Status = StatusVotingPeriod
|
||||||
keeper.SetProposal(ctx, proposal)
|
keeper.SetProposal(ctx, proposal)
|
||||||
|
|
||||||
err := keeper.AddVote(ctx, proposalID, addrs[0], OptionNo)
|
err = keeper.AddVote(ctx, proposalID, addrs[0], OptionNo)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
err = keeper.AddVote(ctx, proposalID, addrs[1], OptionNo)
|
err = keeper.AddVote(ctx, proposalID, addrs[1], OptionNo)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
err = keeper.AddVote(ctx, proposalID, addrs[2], OptionYes)
|
err = keeper.AddVote(ctx, proposalID, addrs[2], OptionYes)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
|
|
||||||
passes, tallyResults := tally(ctx, keeper, keeper.GetProposal(ctx, proposalID))
|
proposal, ok := keeper.GetProposal(ctx, proposalID)
|
||||||
|
require.True(t, ok)
|
||||||
|
passes, tallyResults := tally(ctx, keeper, proposal)
|
||||||
|
|
||||||
require.True(t, passes)
|
require.True(t, passes)
|
||||||
require.False(t, tallyResults.Equals(EmptyTallyResult()))
|
require.False(t, tallyResults.Equals(EmptyTallyResult()))
|
||||||
|
@ -434,12 +478,14 @@ func TestTallyDelgatorMultipleOverride(t *testing.T) {
|
||||||
delegator1Msg2 := staking.NewMsgDelegate(addrs[3], sdk.ValAddress(addrs[1]), sdk.NewCoin(sdk.DefaultBondDenom, delTokens))
|
delegator1Msg2 := staking.NewMsgDelegate(addrs[3], sdk.ValAddress(addrs[1]), sdk.NewCoin(sdk.DefaultBondDenom, delTokens))
|
||||||
stakingHandler(ctx, delegator1Msg2)
|
stakingHandler(ctx, delegator1Msg2)
|
||||||
|
|
||||||
proposal := keeper.NewTextProposal(ctx, "Test", "description", ProposalTypeText)
|
tp := TextProposal{"Test", "description"}
|
||||||
proposalID := proposal.GetProposalID()
|
proposal, err := keeper.SubmitProposal(ctx, tp)
|
||||||
proposal.SetStatus(StatusVotingPeriod)
|
require.NoError(t, err)
|
||||||
|
proposalID := proposal.ProposalID
|
||||||
|
proposal.Status = StatusVotingPeriod
|
||||||
keeper.SetProposal(ctx, proposal)
|
keeper.SetProposal(ctx, proposal)
|
||||||
|
|
||||||
err := keeper.AddVote(ctx, proposalID, addrs[0], OptionYes)
|
err = keeper.AddVote(ctx, proposalID, addrs[0], OptionYes)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
err = keeper.AddVote(ctx, proposalID, addrs[1], OptionYes)
|
err = keeper.AddVote(ctx, proposalID, addrs[1], OptionYes)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
|
@ -448,7 +494,9 @@ func TestTallyDelgatorMultipleOverride(t *testing.T) {
|
||||||
err = keeper.AddVote(ctx, proposalID, addrs[3], OptionNo)
|
err = keeper.AddVote(ctx, proposalID, addrs[3], OptionNo)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
|
|
||||||
passes, tallyResults := tally(ctx, keeper, keeper.GetProposal(ctx, proposalID))
|
proposal, ok := keeper.GetProposal(ctx, proposalID)
|
||||||
|
require.True(t, ok)
|
||||||
|
passes, tallyResults := tally(ctx, keeper, proposal)
|
||||||
|
|
||||||
require.False(t, passes)
|
require.False(t, passes)
|
||||||
require.False(t, tallyResults.Equals(EmptyTallyResult()))
|
require.False(t, tallyResults.Equals(EmptyTallyResult()))
|
||||||
|
@ -490,19 +538,23 @@ func TestTallyDelgatorMultipleInherit(t *testing.T) {
|
||||||
|
|
||||||
staking.EndBlocker(ctx, sk)
|
staking.EndBlocker(ctx, sk)
|
||||||
|
|
||||||
proposal := keeper.NewTextProposal(ctx, "Test", "description", ProposalTypeText)
|
tp := TextProposal{"Test", "description"}
|
||||||
proposalID := proposal.GetProposalID()
|
proposal, err := keeper.SubmitProposal(ctx, tp)
|
||||||
proposal.SetStatus(StatusVotingPeriod)
|
require.NoError(t, err)
|
||||||
|
proposalID := proposal.ProposalID
|
||||||
|
proposal.Status = StatusVotingPeriod
|
||||||
keeper.SetProposal(ctx, proposal)
|
keeper.SetProposal(ctx, proposal)
|
||||||
|
|
||||||
err := keeper.AddVote(ctx, proposalID, addrs[0], OptionYes)
|
err = keeper.AddVote(ctx, proposalID, addrs[0], OptionYes)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
err = keeper.AddVote(ctx, proposalID, addrs[1], OptionNo)
|
err = keeper.AddVote(ctx, proposalID, addrs[1], OptionNo)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
err = keeper.AddVote(ctx, proposalID, addrs[2], OptionNo)
|
err = keeper.AddVote(ctx, proposalID, addrs[2], OptionNo)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
|
|
||||||
passes, tallyResults := tally(ctx, keeper, keeper.GetProposal(ctx, proposalID))
|
proposal, ok := keeper.GetProposal(ctx, proposalID)
|
||||||
|
require.True(t, ok)
|
||||||
|
passes, tallyResults := tally(ctx, keeper, proposal)
|
||||||
|
|
||||||
require.False(t, passes)
|
require.False(t, passes)
|
||||||
require.False(t, tallyResults.Equals(EmptyTallyResult()))
|
require.False(t, tallyResults.Equals(EmptyTallyResult()))
|
||||||
|
@ -538,19 +590,23 @@ func TestTallyJailedValidator(t *testing.T) {
|
||||||
|
|
||||||
staking.EndBlocker(ctx, sk)
|
staking.EndBlocker(ctx, sk)
|
||||||
|
|
||||||
proposal := keeper.NewTextProposal(ctx, "Test", "description", ProposalTypeText)
|
tp := TextProposal{"Test", "description"}
|
||||||
proposalID := proposal.GetProposalID()
|
proposal, err := keeper.SubmitProposal(ctx, tp)
|
||||||
proposal.SetStatus(StatusVotingPeriod)
|
require.NoError(t, err)
|
||||||
|
proposalID := proposal.ProposalID
|
||||||
|
proposal.Status = StatusVotingPeriod
|
||||||
keeper.SetProposal(ctx, proposal)
|
keeper.SetProposal(ctx, proposal)
|
||||||
|
|
||||||
err := keeper.AddVote(ctx, proposalID, addrs[0], OptionYes)
|
err = keeper.AddVote(ctx, proposalID, addrs[0], OptionYes)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
err = keeper.AddVote(ctx, proposalID, addrs[1], OptionNo)
|
err = keeper.AddVote(ctx, proposalID, addrs[1], OptionNo)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
err = keeper.AddVote(ctx, proposalID, addrs[2], OptionNo)
|
err = keeper.AddVote(ctx, proposalID, addrs[2], OptionNo)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
|
|
||||||
passes, tallyResults := tally(ctx, keeper, keeper.GetProposal(ctx, proposalID))
|
proposal, ok := keeper.GetProposal(ctx, proposalID)
|
||||||
|
require.True(t, ok)
|
||||||
|
passes, tallyResults := tally(ctx, keeper, proposal)
|
||||||
|
|
||||||
require.True(t, passes)
|
require.True(t, passes)
|
||||||
require.False(t, tallyResults.Equals(EmptyTallyResult()))
|
require.False(t, tallyResults.Equals(EmptyTallyResult()))
|
||||||
|
|
|
@ -146,3 +146,12 @@ func SortByteArrays(src [][]byte) [][]byte {
|
||||||
sort.Sort(sorted)
|
sort.Sort(sorted)
|
||||||
return sorted
|
return sorted
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func testProposal() TextProposal {
|
||||||
|
return NewTextProposal("Test", "description")
|
||||||
|
}
|
||||||
|
|
||||||
|
// checks if two proposals are equal (note: slow, for tests only)
|
||||||
|
func ProposalEqual(proposalA Proposal, proposalB Proposal) bool {
|
||||||
|
return bytes.Equal(msgCdc.MustMarshalBinaryBare(proposalA), msgCdc.MustMarshalBinaryBare(proposalB))
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue