github.com/Finschia/finschia-sdk@v0.48.1/x/foundation/genesis.go (about) 1 package foundation 2 3 import ( 4 "github.com/gogo/protobuf/proto" 5 6 codectypes "github.com/Finschia/finschia-sdk/codec/types" 7 sdk "github.com/Finschia/finschia-sdk/types" 8 sdkerrors "github.com/Finschia/finschia-sdk/types/errors" 9 authtypes "github.com/Finschia/finschia-sdk/x/auth/types" 10 ) 11 12 // DefaultGenesisState creates a default GenesisState object 13 func DefaultGenesisState() *GenesisState { 14 return &GenesisState{ 15 Params: DefaultParams(), 16 Foundation: DefaultFoundation(), 17 } 18 } 19 20 func DefaultFoundation() FoundationInfo { 21 return *FoundationInfo{ 22 Version: 1, 23 TotalWeight: sdk.ZeroDec(), 24 }.WithDecisionPolicy(DefaultDecisionPolicy()) 25 } 26 27 func DefaultDecisionPolicy() DecisionPolicy { 28 return &OutsourcingDecisionPolicy{ 29 Description: "using x/group", 30 } 31 } 32 33 func DefaultAuthority() sdk.AccAddress { 34 return authtypes.NewModuleAddress(ModuleName) 35 } 36 37 func DefaultParams() Params { 38 return Params{ 39 FoundationTax: sdk.ZeroDec(), 40 } 41 } 42 43 func (data GenesisState) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error { 44 if err := data.Foundation.UnpackInterfaces(unpacker); err != nil { 45 return err 46 } 47 48 for _, p := range data.Proposals { 49 if err := p.UnpackInterfaces(unpacker); err != nil { 50 return err 51 } 52 } 53 54 for _, ga := range data.Authorizations { 55 if err := ga.UnpackInterfaces(unpacker); err != nil { 56 return err 57 } 58 } 59 60 return nil 61 } 62 63 func (i FoundationInfo) ValidateBasic() error { 64 if i.Version == 0 { 65 return sdkerrors.ErrInvalidVersion.Wrap("version must be > 0") 66 } 67 68 if i.TotalWeight.IsNil() || i.TotalWeight.IsNegative() { 69 return sdkerrors.ErrInvalidRequest.Wrap("total weight must be >= 0") 70 } 71 72 policy := i.GetDecisionPolicy() 73 if policy == nil { 74 return sdkerrors.ErrInvalidRequest.Wrap("must provide decision policy") 75 } 76 if err := policy.ValidateBasic(); err != nil { 77 return err 78 } 79 80 // Is foundation outsourcing the proposal feature 81 _, isOutsourcing := i.GetDecisionPolicy().(*OutsourcingDecisionPolicy) 82 memberNotExists := i.TotalWeight.IsZero() 83 if isOutsourcing && !memberNotExists { 84 return sdkerrors.ErrInvalidRequest.Wrap("outsourcing policy not allows members") 85 } 86 if !isOutsourcing && memberNotExists { 87 return sdkerrors.ErrInvalidRequest.Wrap("one member must exist at least") 88 } 89 90 return nil 91 } 92 93 // ValidateGenesis validates the provided genesis state to ensure the 94 // expected invariants holds. 95 func ValidateGenesis(data GenesisState) error { 96 if err := data.Params.ValidateBasic(); err != nil { 97 return err 98 } 99 100 info := data.Foundation 101 if err := info.ValidateBasic(); err != nil { 102 return err 103 } 104 // Is x/foundation outsourcing the proposal feature 105 isOutsourcing := info.TotalWeight.IsZero() 106 107 if realWeight := sdk.NewDec(int64(len(data.Members))); !info.TotalWeight.Equal(realWeight) { 108 return sdkerrors.ErrInvalidRequest.Wrapf("total weight not match, %s != %s", info.TotalWeight, realWeight) 109 } 110 members := Members{Members: data.Members} 111 if err := members.ValidateBasic(); err != nil { 112 return err 113 } 114 115 if isOutsourcing && len(data.Proposals) != 0 { 116 return sdkerrors.ErrInvalidRequest.Wrap("outsourcing policy not allows proposals") 117 } 118 proposalIDs := map[uint64]bool{} 119 for _, proposal := range data.Proposals { 120 id := proposal.Id 121 if id > data.PreviousProposalId { 122 return sdkerrors.ErrInvalidRequest.Wrapf("proposal %d has not yet been submitted", id) 123 } 124 if proposalIDs[id] { 125 return sdkerrors.ErrInvalidRequest.Wrapf("duplicated proposal id of %d", id) 126 } 127 proposalIDs[id] = true 128 129 if err := proposal.ValidateBasic(); err != nil { 130 return err 131 } 132 133 if proposal.FoundationVersion > info.Version { 134 return sdkerrors.ErrInvalidRequest.Wrapf("invalid foundation version of proposal %d", id) 135 } 136 } 137 138 for _, vote := range data.Votes { 139 if !proposalIDs[vote.ProposalId] { 140 return sdkerrors.ErrInvalidRequest.Wrapf("vote for a proposal which does not exist: id %d", vote.ProposalId) 141 } 142 143 if _, err := sdk.AccAddressFromBech32(vote.Voter); err != nil { 144 return sdkerrors.ErrInvalidAddress.Wrapf("invalid voter address: %s", vote.Voter) 145 } 146 147 if err := validateVoteOption(vote.Option); err != nil { 148 return err 149 } 150 } 151 152 seenURLs := map[string]bool{} 153 for _, censorship := range data.Censorships { 154 if err := censorship.ValidateBasic(); err != nil { 155 return err 156 } 157 if censorship.Authority == CensorshipAuthorityUnspecified { 158 return sdkerrors.ErrInvalidRequest.Wrap("authority unspecified") 159 } 160 161 url := censorship.MsgTypeUrl 162 if seenURLs[url] { 163 return sdkerrors.ErrInvalidRequest.Wrapf("duplicate censorship over %s", url) 164 } 165 seenURLs[url] = true 166 } 167 168 for _, ga := range data.Authorizations { 169 auth := ga.GetAuthorization() 170 if auth == nil { 171 return sdkerrors.ErrInvalidType.Wrap("invalid authorization") 172 } 173 174 url := auth.MsgTypeURL() 175 if !seenURLs[url] { 176 return sdkerrors.ErrInvalidRequest.Wrapf("no censorship over %s", url) 177 } 178 179 if _, err := sdk.AccAddressFromBech32(ga.Grantee); err != nil { 180 return err 181 } 182 } 183 184 if err := data.Pool.ValidateBasic(); err != nil { 185 return err 186 } 187 188 return nil 189 } 190 191 func (g GrantAuthorization) GetAuthorization() Authorization { 192 if g.Authorization == nil { 193 return nil 194 } 195 196 a, ok := g.Authorization.GetCachedValue().(Authorization) 197 if !ok { 198 return nil 199 } 200 return a 201 } 202 203 func (g *GrantAuthorization) SetAuthorization(a Authorization) error { 204 msg, ok := a.(proto.Message) 205 if !ok { 206 return sdkerrors.ErrInvalidType.Wrapf("can't proto marshal %T", msg) 207 } 208 209 any, err := codectypes.NewAnyWithValue(msg) 210 if err != nil { 211 return err 212 } 213 g.Authorization = any 214 215 return nil 216 } 217 218 // for the tests 219 func (g GrantAuthorization) WithAuthorization(authorization Authorization) *GrantAuthorization { 220 grant := g 221 if err := grant.SetAuthorization(authorization); err != nil { 222 return nil 223 } 224 return &grant 225 } 226 227 func (g GrantAuthorization) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error { 228 var authorization Authorization 229 return unpacker.UnpackAny(g.Authorization, &authorization) 230 }