github.com/cosmos/cosmos-sdk@v0.50.10/x/gov/types/v1/genesis.go (about) 1 package v1 2 3 import ( 4 "errors" 5 "fmt" 6 7 "golang.org/x/sync/errgroup" 8 9 "github.com/cosmos/cosmos-sdk/codec/types" 10 ) 11 12 // NewGenesisState creates a new genesis state for the governance module 13 func NewGenesisState(startingProposalID uint64, params Params) *GenesisState { 14 return &GenesisState{ 15 StartingProposalId: startingProposalID, 16 Params: ¶ms, 17 } 18 } 19 20 // DefaultGenesisState defines the default governance genesis state 21 func DefaultGenesisState() *GenesisState { 22 return NewGenesisState( 23 DefaultStartingProposalID, 24 DefaultParams(), 25 ) 26 } 27 28 // Empty returns true if a GenesisState is empty 29 func (data GenesisState) Empty() bool { 30 return data.StartingProposalId == 0 || data.Params == nil 31 } 32 33 // ValidateGenesis checks if gov genesis state is valid ranges 34 // It checks if params are in valid ranges 35 // It also makes sure that the provided proposal IDs are unique and 36 // that there are no duplicate deposit or vote records and no vote or deposits for non-existent proposals 37 func ValidateGenesis(data *GenesisState) error { 38 if data.StartingProposalId == 0 { 39 return errors.New("starting proposal id must be greater than 0") 40 } 41 42 var errGroup errgroup.Group 43 44 // weed out duplicate proposals 45 proposalIds := make(map[uint64]struct{}) 46 for _, p := range data.Proposals { 47 if _, ok := proposalIds[p.Id]; ok { 48 return fmt.Errorf("duplicate proposal id: %d", p.Id) 49 } 50 51 proposalIds[p.Id] = struct{}{} 52 } 53 54 // weed out duplicate deposits 55 errGroup.Go(func() error { 56 type depositKey struct { 57 ProposalId uint64 //nolint:revive // staying consistent with main and v0.47 58 Depositor string 59 } 60 depositIds := make(map[depositKey]struct{}) 61 for _, d := range data.Deposits { 62 if _, ok := proposalIds[d.ProposalId]; !ok { 63 return fmt.Errorf("deposit %v has non-existent proposal id: %d", d, d.ProposalId) 64 } 65 66 dk := depositKey{d.ProposalId, d.Depositor} 67 if _, ok := depositIds[dk]; ok { 68 return fmt.Errorf("duplicate deposit: %v", d) 69 } 70 71 depositIds[dk] = struct{}{} 72 } 73 74 return nil 75 }) 76 77 // weed out duplicate votes 78 errGroup.Go(func() error { 79 type voteKey struct { 80 ProposalId uint64 //nolint:revive // staying consistent with main and v0.47 81 Voter string 82 } 83 voteIds := make(map[voteKey]struct{}) 84 for _, v := range data.Votes { 85 if _, ok := proposalIds[v.ProposalId]; !ok { 86 return fmt.Errorf("vote %v has non-existent proposal id: %d", v, v.ProposalId) 87 } 88 89 vk := voteKey{v.ProposalId, v.Voter} 90 if _, ok := voteIds[vk]; ok { 91 return fmt.Errorf("duplicate vote: %v", v) 92 } 93 94 voteIds[vk] = struct{}{} 95 } 96 97 return nil 98 }) 99 100 // verify params 101 errGroup.Go(func() error { 102 return data.Params.ValidateBasic() 103 }) 104 105 return errGroup.Wait() 106 } 107 108 var _ types.UnpackInterfacesMessage = GenesisState{} 109 110 // UnpackInterfaces implements UnpackInterfacesMessage.UnpackInterfaces 111 func (data GenesisState) UnpackInterfaces(unpacker types.AnyUnpacker) error { 112 for _, p := range data.Proposals { 113 err := p.UnpackInterfaces(unpacker) 114 if err != nil { 115 return err 116 } 117 } 118 return nil 119 }