github.com/Finschia/finschia-sdk@v0.49.1/x/auth/types/genesis.go (about) 1 package types 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "sort" 7 8 proto "github.com/gogo/protobuf/proto" 9 10 "github.com/Finschia/finschia-sdk/codec" 11 "github.com/Finschia/finschia-sdk/codec/types" 12 "github.com/Finschia/finschia-sdk/types/module" 13 ) 14 15 var _ types.UnpackInterfacesMessage = GenesisState{} 16 17 // RandomGenesisAccountsFn defines the function required to generate custom account types 18 type RandomGenesisAccountsFn func(simState *module.SimulationState) GenesisAccounts 19 20 // NewGenesisState - Create a new genesis state 21 func NewGenesisState(params Params, accounts GenesisAccounts) *GenesisState { 22 genAccounts, err := PackAccounts(accounts) 23 if err != nil { 24 panic(err) 25 } 26 return &GenesisState{ 27 Params: params, 28 Accounts: genAccounts, 29 } 30 } 31 32 // UnpackInterfaces implements UnpackInterfacesMessage.UnpackInterfaces 33 func (g GenesisState) UnpackInterfaces(unpacker types.AnyUnpacker) error { 34 for _, any := range g.Accounts { 35 var account GenesisAccount 36 err := unpacker.UnpackAny(any, &account) 37 if err != nil { 38 return err 39 } 40 } 41 return nil 42 } 43 44 // DefaultGenesisState - Return a default genesis state 45 func DefaultGenesisState() *GenesisState { 46 return NewGenesisState(DefaultParams(), GenesisAccounts{}) 47 } 48 49 // GetGenesisStateFromAppState returns x/auth GenesisState given raw application 50 // genesis state. 51 func GetGenesisStateFromAppState(cdc codec.Codec, appState map[string]json.RawMessage) GenesisState { 52 var genesisState GenesisState 53 54 if appState[ModuleName] != nil { 55 cdc.MustUnmarshalJSON(appState[ModuleName], &genesisState) 56 } 57 58 return genesisState 59 } 60 61 // ValidateGenesis performs basic validation of auth genesis data returning an 62 // error for any failed validation criteria. 63 func ValidateGenesis(data GenesisState) error { 64 if err := data.Params.Validate(); err != nil { 65 return err 66 } 67 68 genAccs, err := UnpackAccounts(data.Accounts) 69 if err != nil { 70 return err 71 } 72 73 return ValidateGenAccounts(genAccs) 74 } 75 76 // SanitizeGenesisAccounts sorts accounts and coin sets. 77 func SanitizeGenesisAccounts(genAccs GenesisAccounts) GenesisAccounts { 78 sort.Slice(genAccs, func(i, j int) bool { 79 return genAccs[i].GetAccountNumber() < genAccs[j].GetAccountNumber() 80 }) 81 82 return genAccs 83 } 84 85 // ValidateGenAccounts validates an array of GenesisAccounts and checks for duplicates 86 func ValidateGenAccounts(accounts GenesisAccounts) error { 87 addrMap := make(map[string]bool, len(accounts)) 88 89 for _, acc := range accounts { 90 // check for duplicated accounts 91 addrStr := acc.GetAddress().String() 92 if _, ok := addrMap[addrStr]; ok { 93 return fmt.Errorf("duplicate account found in genesis state; address: %s", addrStr) 94 } 95 96 addrMap[addrStr] = true 97 98 // check account specific validation 99 if err := acc.Validate(); err != nil { 100 return fmt.Errorf("invalid account found in genesis state; address: %s, error: %s", addrStr, err.Error()) 101 } 102 } 103 return nil 104 } 105 106 // GenesisAccountIterator implements genesis account iteration. 107 type GenesisAccountIterator struct{} 108 109 // IterateGenesisAccounts iterates over all the genesis accounts found in 110 // appGenesis and invokes a callback on each genesis account. If any call 111 // returns true, iteration stops. 112 func (GenesisAccountIterator) IterateGenesisAccounts( 113 cdc codec.Codec, appGenesis map[string]json.RawMessage, cb func(AccountI) (stop bool), 114 ) { 115 for _, genAcc := range GetGenesisStateFromAppState(cdc, appGenesis).Accounts { 116 acc, ok := genAcc.GetCachedValue().(AccountI) 117 if !ok { 118 panic("expected account") 119 } 120 if cb(acc) { 121 break 122 } 123 } 124 } 125 126 // PackAccounts converts GenesisAccounts to Any slice 127 func PackAccounts(accounts GenesisAccounts) ([]*types.Any, error) { 128 accountsAny := make([]*types.Any, len(accounts)) 129 for i, acc := range accounts { 130 msg, ok := acc.(proto.Message) 131 if !ok { 132 return nil, fmt.Errorf("cannot proto marshal %T", acc) 133 } 134 any, err := types.NewAnyWithValue(msg) 135 if err != nil { 136 return nil, err 137 } 138 accountsAny[i] = any 139 } 140 141 return accountsAny, nil 142 } 143 144 // UnpackAccounts converts Any slice to GenesisAccounts 145 func UnpackAccounts(accountsAny []*types.Any) (GenesisAccounts, error) { 146 accounts := make(GenesisAccounts, len(accountsAny)) 147 for i, any := range accountsAny { 148 acc, ok := any.GetCachedValue().(GenesisAccount) 149 if !ok { 150 return nil, fmt.Errorf("expected genesis account") 151 } 152 accounts[i] = acc 153 } 154 155 return accounts, nil 156 }