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