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  }