github.com/okex/exchain@v1.8.0/libs/ibc-go/testing/simapp/state.go (about) 1 package simapp 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "io" 7 "io/ioutil" 8 "math/rand" 9 "time" 10 11 "github.com/okex/exchain/libs/tendermint/crypto/secp256k1" 12 // tmjson "github.com/okex/exchain/libs/tendermint/libs/json" 13 tmtypes "github.com/okex/exchain/libs/tendermint/types" 14 15 //stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" 16 "github.com/okex/exchain/libs/cosmos-sdk/codec" 17 18 "github.com/okex/exchain/libs/cosmos-sdk/types/module" 19 stakingtypes "github.com/okex/exchain/libs/cosmos-sdk/x/staking/types" 20 //banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" 21 banktypes "github.com/okex/exchain/libs/cosmos-sdk/x/bank" 22 // authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" 23 authtypes "github.com/okex/exchain/libs/cosmos-sdk/x/auth/types" 24 //simtypes "github.com/cosmos/cosmos-sdk/types/simulation" 25 simtypes "github.com/okex/exchain/libs/cosmos-sdk/x/simulation" 26 simappparams "github.com/okex/exchain/libs/ibc-go/testing/simapp/params" 27 ) 28 29 // AppStateFn returns the initial application state using a genesis or the simulation parameters. 30 // It panics if the user provides files for both of them. 31 // If a file is not given for the genesis or the sim params, it creates a randomized one. 32 func AppStateFn(cdc codec.CodecProxy, simManager *module.SimulationManager) simtypes.AppStateFn { 33 return func(r *rand.Rand, accs []simtypes.Account, config simtypes.Config, 34 ) (appState json.RawMessage, simAccs []simtypes.Account, chainID string, genesisTimestamp time.Time) { 35 36 if FlagGenesisTimeValue == 0 { 37 genesisTimestamp = simtypes.RandTimestamp(r) 38 } else { 39 genesisTimestamp = time.Unix(FlagGenesisTimeValue, 0) 40 } 41 42 chainID = config.ChainID 43 switch { 44 case config.ParamsFile != "" && config.GenesisFile != "": 45 panic("cannot provide both a genesis file and a params file") 46 47 case config.GenesisFile != "": 48 // override the default chain-id from simapp to set it later to the config 49 genesisDoc, accounts := AppStateFromGenesisFileFn(r, cdc, config.GenesisFile) 50 51 if FlagGenesisTimeValue == 0 { 52 // use genesis timestamp if no custom timestamp is provided (i.e no random timestamp) 53 genesisTimestamp = genesisDoc.GenesisTime 54 } 55 56 appState = genesisDoc.AppState 57 chainID = genesisDoc.ChainID 58 simAccs = accounts 59 60 case config.ParamsFile != "": 61 appParams := make(simtypes.AppParams) 62 bz, err := ioutil.ReadFile(config.ParamsFile) 63 if err != nil { 64 panic(err) 65 } 66 67 err = json.Unmarshal(bz, &appParams) 68 if err != nil { 69 panic(err) 70 } 71 appState, simAccs = AppStateRandomizedFn(simManager, r, cdc, accs, genesisTimestamp, appParams) 72 73 default: 74 appParams := make(simtypes.AppParams) 75 appState, simAccs = AppStateRandomizedFn(simManager, r, cdc, accs, genesisTimestamp, appParams) 76 } 77 78 rawState := make(map[string]json.RawMessage) 79 err := json.Unmarshal(appState, &rawState) 80 if err != nil { 81 panic(err) 82 } 83 84 stakingStateBz, ok := rawState[stakingtypes.ModuleName] 85 if !ok { 86 panic("staking genesis state is missing") 87 } 88 89 stakingState := new(stakingtypes.GenesisState) 90 err = cdc.GetCdc().UnmarshalJSON(stakingStateBz, stakingState) 91 if err != nil { 92 panic(err) 93 } 94 // compute not bonded balance 95 // notBondedTokens := sdk.ZeroInt() 96 // for _, val := range stakingState.Validators { 97 // if val.Status != sdk.Unbonded { 98 // continue 99 // } 100 // notBondedTokens = notBondedTokens.Add(val.GetTokens()) 101 // } 102 // notBondedCoins := sdk.NewCoin(stakingState.Params.BondDenom, notBondedTokens) 103 // edit bank state to make it have the not bonded pool tokens 104 bankStateBz, ok := rawState[banktypes.ModuleName] 105 // TODO(fdymylja/jonathan): should we panic in this case 106 if !ok { 107 panic("bank genesis state is missing") 108 } 109 bankState := banktypes.NewGenesisState(true) 110 // bankState := new(banktypes.GenesisState) 111 err = cdc.GetCdc().UnmarshalJSON(bankStateBz, bankState) 112 if err != nil { 113 panic(err) 114 } 115 // todo our genesis bank do not have balance infos 116 // bankState.Balances = append(bankState.Balances, banktypes.Balance{ 117 // Address: authtypes.NewModuleAddress(stakingtypes.NotBondedPoolName).String(), 118 // Coins: sdk.NewCoins(notBondedCoins), 119 // }) 120 121 // change appState back 122 rawState[stakingtypes.ModuleName] = cdc.GetCdc().MustMarshalJSON(stakingState) 123 rawState[banktypes.ModuleName] = cdc.GetCdc().MustMarshalJSON(bankState) 124 125 // replace appstate 126 appState, err = json.Marshal(rawState) 127 if err != nil { 128 panic(err) 129 } 130 return appState, simAccs, chainID, genesisTimestamp 131 } 132 } 133 134 // AppStateRandomizedFn creates calls each module's GenesisState generator function 135 // and creates the simulation params 136 func AppStateRandomizedFn( 137 simManager *module.SimulationManager, r *rand.Rand, cdc codec.CodecProxy, 138 accs []simtypes.Account, genesisTimestamp time.Time, appParams simtypes.AppParams, 139 ) (json.RawMessage, []simtypes.Account) { 140 numAccs := int64(len(accs)) 141 genesisState := NewDefaultGenesisState() 142 143 // generate a random amount of initial stake coins and a random initial 144 // number of bonded accounts 145 var initialStake, numInitiallyBonded int64 146 appParams.GetOrGenerate( 147 cdc.GetCdc(), simappparams.StakePerAccount, &initialStake, r, 148 func(r *rand.Rand) { initialStake = r.Int63n(1e12) }, 149 ) 150 appParams.GetOrGenerate( 151 cdc.GetCdc(), simappparams.InitiallyBondedValidators, &numInitiallyBonded, r, 152 func(r *rand.Rand) { numInitiallyBonded = int64(r.Intn(300)) }, 153 ) 154 155 if numInitiallyBonded > numAccs { 156 numInitiallyBonded = numAccs 157 } 158 159 fmt.Printf( 160 `Selected randomly generated parameters for simulated genesis: 161 { 162 stake_per_account: "%d", 163 initially_bonded_validators: "%d" 164 } 165 `, initialStake, numInitiallyBonded, 166 ) 167 168 simState := &module.SimulationState{ 169 AppParams: appParams, 170 Cdc: cdc.GetCdc(), 171 Rand: r, 172 GenState: genesisState, 173 Accounts: accs, 174 InitialStake: initialStake, 175 NumBonded: numInitiallyBonded, 176 GenTimestamp: genesisTimestamp, 177 } 178 179 simManager.GenerateGenesisStates(simState) 180 181 appState, err := json.Marshal(genesisState) 182 if err != nil { 183 panic(err) 184 } 185 186 return appState, accs 187 } 188 189 // AppStateFromGenesisFileFn util function to generate the genesis AppState 190 // from a genesis.json file. 191 func AppStateFromGenesisFileFn(r io.Reader, cdc codec.CodecProxy, genesisFile string) (tmtypes.GenesisDoc, []simtypes.Account) { 192 // NOTE: Tendermint uses a custom JSON decoder for GenesisDoc 193 genesis, err := tmtypes.GenesisDocFromFile(genesisFile) 194 if err != nil { 195 panic(err) 196 } 197 198 var appState GenesisState 199 err = json.Unmarshal(genesis.AppState, &appState) 200 if err != nil { 201 panic(err) 202 } 203 204 var authGenesis authtypes.GenesisState 205 if appState[authtypes.ModuleName] != nil { 206 cdc.GetCdc().MustUnmarshalJSON(appState[authtypes.ModuleName], &authGenesis) 207 } 208 209 newAccs := make([]simtypes.Account, len(authGenesis.Accounts)) 210 for i, acc := range authGenesis.Accounts { 211 // Pick a random private key, since we don't know the actual key 212 // This should be fine as it's only used for mock Tendermint validators 213 // and these keys are never actually used to sign by mock Tendermint. 214 privkeySeed := make([]byte, 15) 215 if _, err := r.Read(privkeySeed); err != nil { 216 panic(err) 217 } 218 219 privKey := secp256k1.GenPrivKeySecp256k1(privkeySeed) 220 221 // create simulator accounts 222 simAcc := simtypes.Account{PrivKey: privKey, PubKey: privKey.PubKey(), Address: acc.GetAddress()} 223 newAccs[i] = simAcc 224 } 225 226 return *genesis, newAccs 227 }