github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/libs/cosmos-sdk/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 tmtypes "github.com/fibonacci-chain/fbc/libs/tendermint/types" 13 14 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/codec" 15 simapparams "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/simapp/params" 16 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types/module" 17 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/auth" 18 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/simulation" 19 ) 20 21 // AppStateFn returns the initial application state using a genesis or the simulation parameters. 22 // It panics if the user provides files for both of them. 23 // If a file is not given for the genesis or the sim params, it creates a randomized one. 24 func AppStateFn(cdc *codec.Codec, simManager *module.SimulationManager) simulation.AppStateFn { 25 return func(r *rand.Rand, accs []simulation.Account, config simulation.Config, 26 ) (appState json.RawMessage, simAccs []simulation.Account, chainID string, genesisTimestamp time.Time) { 27 28 if FlagGenesisTimeValue == 0 { 29 genesisTimestamp = simulation.RandTimestamp(r) 30 } else { 31 genesisTimestamp = time.Unix(FlagGenesisTimeValue, 0) 32 } 33 34 chainID = config.ChainID 35 switch { 36 case config.ParamsFile != "" && config.GenesisFile != "": 37 panic("cannot provide both a genesis file and a params file") 38 39 case config.GenesisFile != "": 40 // override the default chain-id from simapp to set it later to the config 41 genesisDoc, accounts := AppStateFromGenesisFileFn(r, cdc, config.GenesisFile) 42 43 if FlagGenesisTimeValue == 0 { 44 // use genesis timestamp if no custom timestamp is provided (i.e no random timestamp) 45 genesisTimestamp = genesisDoc.GenesisTime 46 } 47 48 appState = genesisDoc.AppState 49 chainID = genesisDoc.ChainID 50 simAccs = accounts 51 52 case config.ParamsFile != "": 53 appParams := make(simulation.AppParams) 54 bz, err := ioutil.ReadFile(config.ParamsFile) 55 if err != nil { 56 panic(err) 57 } 58 59 cdc.MustUnmarshalJSON(bz, &appParams) 60 appState, simAccs = AppStateRandomizedFn(simManager, r, cdc, accs, genesisTimestamp, appParams) 61 62 default: 63 appParams := make(simulation.AppParams) 64 appState, simAccs = AppStateRandomizedFn(simManager, r, cdc, accs, genesisTimestamp, appParams) 65 } 66 67 return appState, simAccs, chainID, genesisTimestamp 68 } 69 } 70 71 // AppStateRandomizedFn creates calls each module's GenesisState generator function 72 // and creates the simulation params 73 func AppStateRandomizedFn( 74 simManager *module.SimulationManager, r *rand.Rand, cdc *codec.Codec, 75 accs []simulation.Account, genesisTimestamp time.Time, appParams simulation.AppParams, 76 ) (json.RawMessage, []simulation.Account) { 77 numAccs := int64(len(accs)) 78 genesisState := NewDefaultGenesisState() 79 80 // generate a random amount of initial stake coins and a random initial 81 // number of bonded accounts 82 var initialStake, numInitiallyBonded int64 83 appParams.GetOrGenerate( 84 cdc, simapparams.StakePerAccount, &initialStake, r, 85 func(r *rand.Rand) { initialStake = r.Int63n(1e12) }, 86 ) 87 appParams.GetOrGenerate( 88 cdc, simapparams.InitiallyBondedValidators, &numInitiallyBonded, r, 89 func(r *rand.Rand) { numInitiallyBonded = int64(r.Intn(300)) }, 90 ) 91 92 if numInitiallyBonded > numAccs { 93 numInitiallyBonded = numAccs 94 } 95 96 fmt.Printf( 97 `Selected randomly generated parameters for simulated genesis: 98 { 99 stake_per_account: "%d", 100 initially_bonded_validators: "%d" 101 } 102 `, initialStake, numInitiallyBonded, 103 ) 104 105 simState := &module.SimulationState{ 106 AppParams: appParams, 107 Cdc: cdc, 108 Rand: r, 109 GenState: genesisState, 110 Accounts: accs, 111 InitialStake: initialStake, 112 NumBonded: numInitiallyBonded, 113 GenTimestamp: genesisTimestamp, 114 } 115 116 simManager.GenerateGenesisStates(simState) 117 118 appState, err := cdc.MarshalJSON(genesisState) 119 if err != nil { 120 panic(err) 121 } 122 123 return appState, accs 124 } 125 126 // AppStateFromGenesisFileFn util function to generate the genesis AppState 127 // from a genesis.json file. 128 func AppStateFromGenesisFileFn(r io.Reader, cdc *codec.Codec, genesisFile string) (tmtypes.GenesisDoc, []simulation.Account) { 129 bytes, err := ioutil.ReadFile(genesisFile) 130 if err != nil { 131 panic(err) 132 } 133 134 var genesis tmtypes.GenesisDoc 135 cdc.MustUnmarshalJSON(bytes, &genesis) 136 137 var appState GenesisState 138 cdc.MustUnmarshalJSON(genesis.AppState, &appState) 139 140 var authGenesis auth.GenesisState 141 if appState[auth.ModuleName] != nil { 142 cdc.MustUnmarshalJSON(appState[auth.ModuleName], &authGenesis) 143 } 144 145 newAccs := make([]simulation.Account, len(authGenesis.Accounts)) 146 for i, acc := range authGenesis.Accounts { 147 // Pick a random private key, since we don't know the actual key 148 // This should be fine as it's only used for mock Tendermint validators 149 // and these keys are never actually used to sign by mock Tendermint. 150 privkeySeed := make([]byte, 15) 151 if _, err := r.Read(privkeySeed); err != nil { 152 panic(err) 153 } 154 155 privKey := secp256k1.GenPrivKeySecp256k1(privkeySeed) 156 157 // create simulator accounts 158 simAcc := simulation.Account{PrivKey: privKey, PubKey: privKey.PubKey(), Address: acc.GetAddress()} 159 newAccs[i] = simAcc 160 } 161 162 return genesis, newAccs 163 }