package gov import ( "encoding/json" "fmt" "github.com/pkg/errors" sdk "github.com/cosmos/cosmos-sdk/types" ) //----------------------------------------------------------- // Proposal interface type Proposal interface { GetProposalID() int64 SetProposalID(int64) GetTitle() string SetTitle(string) GetDescription() string SetDescription(string) GetProposalType() ProposalKind SetProposalType(ProposalKind) GetStatus() ProposalStatus SetStatus(ProposalStatus) GetSubmitBlock() int64 SetSubmitBlock(int64) GetTotalDeposit() sdk.Coins SetTotalDeposit(sdk.Coins) GetVotingStartBlock() int64 SetVotingStartBlock(int64) } // checks if two proposals are equal func ProposalEqual(proposalA Proposal, proposalB Proposal) bool { if proposalA.GetProposalID() != proposalB.GetProposalID() || proposalA.GetTitle() != proposalB.GetTitle() || proposalA.GetDescription() != proposalB.GetDescription() || proposalA.GetProposalType() != proposalB.GetProposalType() || proposalA.GetStatus() != proposalB.GetStatus() || proposalA.GetSubmitBlock() != proposalB.GetSubmitBlock() || !(proposalA.GetTotalDeposit().IsEqual(proposalB.GetTotalDeposit())) || proposalA.GetVotingStartBlock() != proposalB.GetVotingStartBlock() { return false } return true } //----------------------------------------------------------- // Text Proposals type TextProposal struct { ProposalID int64 `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} SubmitBlock int64 `json:"submit_block"` // Height of the block where TxGovSubmitProposal was included TotalDeposit sdk.Coins `json:"total_deposit"` // Current deposit on this proposal. Initial value is set at InitialDeposit VotingStartBlock int64 `json:"voting_start_block"` // Height of the block where MinDeposit was reached. -1 if MinDeposit is not reached } // Implements Proposal Interface var _ Proposal = (*TextProposal)(nil) // nolint func (tp TextProposal) GetProposalID() int64 { return tp.ProposalID } func (tp *TextProposal) SetProposalID(proposalID int64) { tp.ProposalID = proposalID } func (tp TextProposal) GetTitle() string { return tp.Title } func (tp *TextProposal) SetTitle(title string) { tp.Title = title } func (tp TextProposal) GetDescription() string { return tp.Description } func (tp *TextProposal) SetDescription(description string) { tp.Description = description } func (tp TextProposal) GetProposalType() ProposalKind { return tp.ProposalType } func (tp *TextProposal) SetProposalType(proposalType ProposalKind) { tp.ProposalType = proposalType } func (tp TextProposal) GetStatus() ProposalStatus { return tp.Status } func (tp *TextProposal) SetStatus(status ProposalStatus) { tp.Status = status } func (tp TextProposal) GetSubmitBlock() int64 { return tp.SubmitBlock } func (tp *TextProposal) SetSubmitBlock(submitBlock int64) { tp.SubmitBlock = submitBlock } func (tp TextProposal) GetTotalDeposit() sdk.Coins { return tp.TotalDeposit } func (tp *TextProposal) SetTotalDeposit(totalDeposit sdk.Coins) { tp.TotalDeposit = totalDeposit } func (tp TextProposal) GetVotingStartBlock() int64 { return tp.VotingStartBlock } func (tp *TextProposal) SetVotingStartBlock(votingStartBlock int64) { tp.VotingStartBlock = votingStartBlock } //----------------------------------------------------------- // ProposalQueue type ProposalQueue []int64 //----------------------------------------------------------- // ProposalKind // Type that represents Proposal Type as a byte type ProposalKind byte //nolint const ( ProposalTypeText ProposalKind = 0x01 ProposalTypeParameterChange ProposalKind = 0x02 ProposalTypeSoftwareUpgrade ProposalKind = 0x03 ) // String to proposalType byte. Returns ff if invalid. func ProposalTypeFromString(str string) (ProposalKind, error) { switch str { case "Text": return ProposalTypeText, nil case "ParameterChange": return ProposalTypeParameterChange, nil case "SoftwareUpgrade": return ProposalTypeSoftwareUpgrade, nil default: return ProposalKind(0xff), errors.Errorf("'%s' is not a valid proposal type", str) } } // is defined ProposalType? func validProposalType(pt ProposalKind) bool { if pt == ProposalTypeText || pt == ProposalTypeParameterChange || pt == ProposalTypeSoftwareUpgrade { return true } return false } // Marshal needed for protobuf compatibility func (pt ProposalKind) Marshal() ([]byte, error) { return []byte{byte(pt)}, nil } // Unmarshal needed for protobuf compatibility func (pt *ProposalKind) Unmarshal(data []byte) error { *pt = ProposalKind(data[0]) return nil } // Marshals to JSON using string func (pt ProposalKind) MarshalJSON() ([]byte, error) { return json.Marshal(pt.String()) } // Unmarshals from JSON assuming Bech32 encoding func (pt *ProposalKind) UnmarshalJSON(data []byte) error { var s string err := json.Unmarshal(data, &s) if err != nil { return nil } bz2, err := ProposalTypeFromString(s) if err != nil { return err } *pt = bz2 return nil } // Turns VoteOption byte to String func (pt ProposalKind) String() string { switch pt { case 0x01: return "Text" case 0x02: return "ParameterChange" case 0x03: return "SoftwareUpgrade" default: return "" } } // For Printf / Sprintf, returns bech32 when using %s func (pt ProposalKind) Format(s fmt.State, verb rune) { switch verb { case 's': s.Write([]byte(fmt.Sprintf("%s", pt.String()))) default: s.Write([]byte(fmt.Sprintf("%v", byte(pt)))) } } //----------------------------------------------------------- // ProposalStatus // Type that represents Proposal Status as a byte type ProposalStatus byte //nolint const ( StatusDepositPeriod ProposalStatus = 0x01 StatusVotingPeriod ProposalStatus = 0x02 StatusPassed ProposalStatus = 0x03 StatusRejected ProposalStatus = 0x04 ) // ProposalStatusToString turns a string into a ProposalStatus func ProposalStatusFromString(str string) (ProposalStatus, error) { switch str { case "DepositPeriod": return StatusDepositPeriod, nil case "VotingPeriod": return StatusVotingPeriod, nil case "Passed": return StatusPassed, nil case "Rejected": return StatusRejected, nil default: return ProposalStatus(0xff), errors.Errorf("'%s' is not a valid proposal status", str) } } // is defined ProposalType? func validProposalStatus(status ProposalStatus) bool { if status == StatusDepositPeriod || status == StatusVotingPeriod || status == StatusPassed || status == StatusRejected { return true } return false } // Marshal needed for protobuf compatibility func (status ProposalStatus) Marshal() ([]byte, error) { return []byte{byte(status)}, nil } // Unmarshal needed for protobuf compatibility func (status *ProposalStatus) Unmarshal(data []byte) error { *status = ProposalStatus(data[0]) return nil } // Marshals to JSON using string func (status ProposalStatus) MarshalJSON() ([]byte, error) { return json.Marshal(status.String()) } // Unmarshals from JSON assuming Bech32 encoding func (status *ProposalStatus) UnmarshalJSON(data []byte) error { var s string err := json.Unmarshal(data, &s) if err != nil { return nil } bz2, err := ProposalStatusFromString(s) if err != nil { return err } *status = bz2 return nil } // Turns VoteStatus byte to String func (status ProposalStatus) String() string { switch status { case StatusDepositPeriod: return "DepositPeriod" case StatusVotingPeriod: return "VotingPeriod" case StatusPassed: return "Passed" case StatusRejected: return "Rejected" default: return "" } } // For Printf / Sprintf, returns bech32 when using %s func (status ProposalStatus) Format(s fmt.State, verb rune) { switch verb { case 's': s.Write([]byte(fmt.Sprintf("%s", status.String()))) default: s.Write([]byte(fmt.Sprintf("%v", byte(status)))) } }