2018-06-21 17:19:14 -07:00
|
|
|
package gov
|
|
|
|
|
|
|
|
import (
|
2019-02-08 18:33:06 -08:00
|
|
|
"bytes"
|
2018-12-11 11:05:49 -08:00
|
|
|
"fmt"
|
2018-09-20 07:53:52 -07:00
|
|
|
"time"
|
|
|
|
|
2018-06-21 17:19:14 -07:00
|
|
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
|
|
)
|
|
|
|
|
2019-02-08 18:33:06 -08:00
|
|
|
const (
|
|
|
|
// Default period for deposits & voting
|
|
|
|
DefaultPeriod time.Duration = 86400 * 2 * time.Second // 2 days
|
|
|
|
)
|
|
|
|
|
2018-06-21 17:19:14 -07:00
|
|
|
// GenesisState - all staking state that must be provided at genesis
|
|
|
|
type GenesisState struct {
|
2018-11-08 16:28:28 -08:00
|
|
|
StartingProposalID uint64 `json:"starting_proposal_id"`
|
|
|
|
Deposits []DepositWithMetadata `json:"deposits"`
|
|
|
|
Votes []VoteWithMetadata `json:"votes"`
|
|
|
|
Proposals []Proposal `json:"proposals"`
|
|
|
|
DepositParams DepositParams `json:"deposit_params"`
|
|
|
|
VotingParams VotingParams `json:"voting_params"`
|
|
|
|
TallyParams TallyParams `json:"tally_params"`
|
|
|
|
}
|
|
|
|
|
|
|
|
// DepositWithMetadata (just for genesis)
|
|
|
|
type DepositWithMetadata struct {
|
|
|
|
ProposalID uint64 `json:"proposal_id"`
|
|
|
|
Deposit Deposit `json:"deposit"`
|
|
|
|
}
|
|
|
|
|
|
|
|
// VoteWithMetadata (just for genesis)
|
|
|
|
type VoteWithMetadata struct {
|
|
|
|
ProposalID uint64 `json:"proposal_id"`
|
|
|
|
Vote Vote `json:"vote"`
|
2018-06-21 17:19:14 -07:00
|
|
|
}
|
|
|
|
|
2018-11-06 23:33:18 -08:00
|
|
|
func NewGenesisState(startingProposalID uint64, dp DepositParams, vp VotingParams, tp TallyParams) GenesisState {
|
2018-06-21 17:19:14 -07:00
|
|
|
return GenesisState{
|
|
|
|
StartingProposalID: startingProposalID,
|
2018-11-06 23:33:18 -08:00
|
|
|
DepositParams: dp,
|
|
|
|
VotingParams: vp,
|
|
|
|
TallyParams: tp,
|
2018-06-21 17:19:14 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// get raw genesis raw message for testing
|
|
|
|
func DefaultGenesisState() GenesisState {
|
2019-02-13 15:01:50 -08:00
|
|
|
minDepositTokens := sdk.TokensFromTendermintPower(10)
|
2018-06-21 17:19:14 -07:00
|
|
|
return GenesisState{
|
|
|
|
StartingProposalID: 1,
|
2018-11-06 23:33:18 -08:00
|
|
|
DepositParams: DepositParams{
|
2019-02-13 15:01:50 -08:00
|
|
|
MinDeposit: sdk.Coins{sdk.NewCoin(sdk.DefaultBondDenom, minDepositTokens)},
|
2019-02-08 18:33:06 -08:00
|
|
|
MaxDepositPeriod: DefaultPeriod,
|
2018-07-26 18:24:41 -07:00
|
|
|
},
|
2018-11-06 23:33:18 -08:00
|
|
|
VotingParams: VotingParams{
|
2019-02-08 18:33:06 -08:00
|
|
|
VotingPeriod: DefaultPeriod,
|
2018-07-26 18:24:41 -07:00
|
|
|
},
|
2018-11-06 23:33:18 -08:00
|
|
|
TallyParams: TallyParams{
|
2019-02-27 08:44:05 -08:00
|
|
|
Quorum: sdk.NewDecWithPrec(334, 3),
|
|
|
|
Threshold: sdk.NewDecWithPrec(5, 1),
|
|
|
|
Veto: sdk.NewDecWithPrec(334, 3),
|
2018-07-26 18:24:41 -07:00
|
|
|
},
|
2018-06-21 17:19:14 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-01-07 14:24:04 -08:00
|
|
|
// Checks whether 2 GenesisState structs are equivalent.
|
|
|
|
func (data GenesisState) Equal(data2 GenesisState) bool {
|
2019-02-08 18:33:06 -08:00
|
|
|
b1 := msgCdc.MustMarshalBinaryBare(data)
|
|
|
|
b2 := msgCdc.MustMarshalBinaryBare(data2)
|
|
|
|
return bytes.Equal(b1, b2)
|
2019-01-07 14:24:04 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Returns if a GenesisState is empty or has data in it
|
|
|
|
func (data GenesisState) IsEmpty() bool {
|
|
|
|
emptyGenState := GenesisState{}
|
|
|
|
return data.Equal(emptyGenState)
|
|
|
|
}
|
|
|
|
|
2019-02-08 18:33:06 -08:00
|
|
|
// ValidateGenesis
|
2018-12-06 16:22:24 -08:00
|
|
|
func ValidateGenesis(data GenesisState) error {
|
2018-12-11 11:05:49 -08:00
|
|
|
threshold := data.TallyParams.Threshold
|
|
|
|
if threshold.IsNegative() || threshold.GT(sdk.OneDec()) {
|
|
|
|
return fmt.Errorf("Governance vote threshold should be positive and less or equal to one, is %s",
|
|
|
|
threshold.String())
|
|
|
|
}
|
|
|
|
|
|
|
|
veto := data.TallyParams.Veto
|
|
|
|
if veto.IsNegative() || veto.GT(sdk.OneDec()) {
|
|
|
|
return fmt.Errorf("Governance vote veto threshold should be positive and less or equal to one, is %s",
|
|
|
|
veto.String())
|
|
|
|
}
|
|
|
|
|
|
|
|
if data.DepositParams.MaxDepositPeriod > data.VotingParams.VotingPeriod {
|
|
|
|
return fmt.Errorf("Governance deposit period should be less than or equal to the voting period (%ds), is %ds",
|
|
|
|
data.VotingParams.VotingPeriod, data.DepositParams.MaxDepositPeriod)
|
|
|
|
}
|
|
|
|
|
|
|
|
if !data.DepositParams.MinDeposit.IsValid() {
|
|
|
|
return fmt.Errorf("Governance deposit amount must be a valid sdk.Coins amount, is %s",
|
|
|
|
data.DepositParams.MinDeposit.String())
|
|
|
|
}
|
|
|
|
|
2018-12-06 16:22:24 -08:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2018-06-21 17:19:14 -07:00
|
|
|
// InitGenesis - store genesis parameters
|
|
|
|
func InitGenesis(ctx sdk.Context, k Keeper, data GenesisState) {
|
2018-06-28 15:52:10 -07:00
|
|
|
err := k.setInitialProposalID(ctx, data.StartingProposalID)
|
|
|
|
if err != nil {
|
|
|
|
// TODO: Handle this with #870
|
|
|
|
panic(err)
|
|
|
|
}
|
2018-11-06 23:33:18 -08:00
|
|
|
k.setDepositParams(ctx, data.DepositParams)
|
|
|
|
k.setVotingParams(ctx, data.VotingParams)
|
|
|
|
k.setTallyParams(ctx, data.TallyParams)
|
2018-11-08 16:28:28 -08:00
|
|
|
for _, deposit := range data.Deposits {
|
2018-11-21 15:53:33 -08:00
|
|
|
k.setDeposit(ctx, deposit.ProposalID, deposit.Deposit.Depositor, deposit.Deposit)
|
2018-11-08 16:28:28 -08:00
|
|
|
}
|
|
|
|
for _, vote := range data.Votes {
|
|
|
|
k.setVote(ctx, vote.ProposalID, vote.Vote.Voter, vote.Vote)
|
|
|
|
}
|
|
|
|
for _, proposal := range data.Proposals {
|
2019-01-07 14:24:04 -08:00
|
|
|
switch proposal.GetStatus() {
|
|
|
|
case StatusDepositPeriod:
|
|
|
|
k.InsertInactiveProposalQueue(ctx, proposal.GetDepositEndTime(), proposal.GetProposalID())
|
|
|
|
case StatusVotingPeriod:
|
|
|
|
k.InsertActiveProposalQueue(ctx, proposal.GetVotingEndTime(), proposal.GetProposalID())
|
|
|
|
}
|
2018-11-08 16:28:28 -08:00
|
|
|
k.SetProposal(ctx, proposal)
|
|
|
|
}
|
2018-06-21 17:19:14 -07:00
|
|
|
}
|
|
|
|
|
2018-11-08 16:28:28 -08:00
|
|
|
// ExportGenesis - output genesis parameters
|
|
|
|
func ExportGenesis(ctx sdk.Context, k Keeper) GenesisState {
|
|
|
|
startingProposalID, _ := k.peekCurrentProposalID(ctx)
|
2018-11-06 23:33:18 -08:00
|
|
|
depositParams := k.GetDepositParams(ctx)
|
|
|
|
votingParams := k.GetVotingParams(ctx)
|
|
|
|
tallyParams := k.GetTallyParams(ctx)
|
2018-11-08 16:28:28 -08:00
|
|
|
var deposits []DepositWithMetadata
|
|
|
|
var votes []VoteWithMetadata
|
|
|
|
proposals := k.GetProposalsFiltered(ctx, nil, nil, StatusNil, 0)
|
|
|
|
for _, proposal := range proposals {
|
|
|
|
proposalID := proposal.GetProposalID()
|
|
|
|
depositsIterator := k.GetDeposits(ctx, proposalID)
|
2019-01-25 03:13:17 -08:00
|
|
|
defer depositsIterator.Close()
|
2018-11-08 16:28:28 -08:00
|
|
|
for ; depositsIterator.Valid(); depositsIterator.Next() {
|
|
|
|
var deposit Deposit
|
|
|
|
k.cdc.MustUnmarshalBinaryLengthPrefixed(depositsIterator.Value(), &deposit)
|
|
|
|
deposits = append(deposits, DepositWithMetadata{proposalID, deposit})
|
|
|
|
}
|
|
|
|
votesIterator := k.GetVotes(ctx, proposalID)
|
2019-01-25 03:13:17 -08:00
|
|
|
defer votesIterator.Close()
|
2018-11-08 16:28:28 -08:00
|
|
|
for ; votesIterator.Valid(); votesIterator.Next() {
|
|
|
|
var vote Vote
|
|
|
|
k.cdc.MustUnmarshalBinaryLengthPrefixed(votesIterator.Value(), &vote)
|
|
|
|
votes = append(votes, VoteWithMetadata{proposalID, vote})
|
|
|
|
}
|
|
|
|
}
|
2018-06-21 17:19:14 -07:00
|
|
|
|
|
|
|
return GenesisState{
|
2018-07-26 18:24:41 -07:00
|
|
|
StartingProposalID: startingProposalID,
|
2018-11-08 16:28:28 -08:00
|
|
|
Deposits: deposits,
|
|
|
|
Votes: votes,
|
|
|
|
Proposals: proposals,
|
2018-11-06 23:33:18 -08:00
|
|
|
DepositParams: depositParams,
|
|
|
|
VotingParams: votingParams,
|
|
|
|
TallyParams: tallyParams,
|
2018-06-21 17:19:14 -07:00
|
|
|
}
|
|
|
|
}
|