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  }