github.com/Finschia/finschia-sdk@v0.48.1/x/simulation/util.go (about) 1 package simulation 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "math/rand" 7 "testing" 8 9 "github.com/Finschia/finschia-sdk/baseapp" 10 "github.com/Finschia/finschia-sdk/client" 11 "github.com/Finschia/finschia-sdk/codec" 12 "github.com/Finschia/finschia-sdk/simapp/helpers" 13 sdk "github.com/Finschia/finschia-sdk/types" 14 simtypes "github.com/Finschia/finschia-sdk/types/simulation" 15 ) 16 17 func getTestingMode(tb testing.TB) (testingMode bool, t *testing.T, b *testing.B) { 18 testingMode = false 19 20 if _t, ok := tb.(*testing.T); ok { 21 t = _t 22 testingMode = true 23 } else { 24 b = tb.(*testing.B) 25 } 26 27 return testingMode, t, b 28 } 29 30 // getBlockSize returns a block size as determined from the transition matrix. 31 // It targets making average block size the provided parameter. The three 32 // states it moves between are: 33 // - "over stuffed" blocks with average size of 2 * avgblocksize, 34 // - normal sized blocks, hitting avgBlocksize on average, 35 // - and empty blocks, with no txs / only txs scheduled from the past. 36 func getBlockSize(r *rand.Rand, params Params, lastBlockSizeState, avgBlockSize int) (state, blockSize int) { 37 // TODO: Make default blocksize transition matrix actually make the average 38 // blocksize equal to avgBlockSize. 39 state = params.BlockSizeTransitionMatrix().NextState(r, lastBlockSizeState) 40 41 switch state { 42 case 0: 43 blockSize = r.Intn(avgBlockSize * 4) 44 45 case 1: 46 blockSize = r.Intn(avgBlockSize * 2) 47 48 default: 49 blockSize = 0 50 } 51 52 return state, blockSize 53 } 54 55 func mustMarshalJSONIndent(o interface{}) []byte { 56 bz, err := json.MarshalIndent(o, "", " ") 57 if err != nil { 58 panic(fmt.Sprintf("failed to JSON encode: %s", err)) 59 } 60 61 return bz 62 } 63 64 // OperationInput is a struct that holds all the needed values to generate a tx and deliver it 65 type OperationInput struct { 66 R *rand.Rand 67 App *baseapp.BaseApp 68 TxGen client.TxConfig 69 Cdc *codec.ProtoCodec 70 Msg sdk.Msg 71 MsgType string 72 CoinsSpentInMsg sdk.Coins 73 Context sdk.Context 74 SimAccount simtypes.Account 75 AccountKeeper AccountKeeper 76 Bankkeeper BankKeeper 77 ModuleName string 78 } 79 80 // GenAndDeliverTxWithRandFees generates a transaction with a random fee and delivers it. 81 func GenAndDeliverTxWithRandFees(txCtx OperationInput) (simtypes.OperationMsg, []simtypes.FutureOperation, error) { 82 account := txCtx.AccountKeeper.GetAccount(txCtx.Context, txCtx.SimAccount.Address) 83 spendable := txCtx.Bankkeeper.SpendableCoins(txCtx.Context, account.GetAddress()) 84 85 var fees sdk.Coins 86 var err error 87 88 coins, hasNeg := spendable.SafeSub(txCtx.CoinsSpentInMsg) 89 if hasNeg { 90 return simtypes.NoOpMsg(txCtx.ModuleName, txCtx.MsgType, "message doesn't leave room for fees"), nil, err 91 } 92 93 fees, err = simtypes.RandomFees(txCtx.R, txCtx.Context, coins) 94 if err != nil { 95 return simtypes.NoOpMsg(txCtx.ModuleName, txCtx.MsgType, "unable to generate fees"), nil, err 96 } 97 return GenAndDeliverTx(txCtx, fees) 98 } 99 100 // GenAndDeliverTx generates a transactions and delivers it. 101 func GenAndDeliverTx(txCtx OperationInput, fees sdk.Coins) (simtypes.OperationMsg, []simtypes.FutureOperation, error) { 102 account := txCtx.AccountKeeper.GetAccount(txCtx.Context, txCtx.SimAccount.Address) 103 tx, err := helpers.GenSignedMockTx( 104 txCtx.R, 105 txCtx.TxGen, 106 []sdk.Msg{txCtx.Msg}, 107 fees, 108 helpers.DefaultGenTxGas, 109 txCtx.Context.ChainID(), 110 []uint64{account.GetAccountNumber()}, 111 []uint64{account.GetSequence()}, 112 txCtx.SimAccount.PrivKey, 113 ) 114 if err != nil { 115 return simtypes.NoOpMsg(txCtx.ModuleName, txCtx.MsgType, "unable to generate mock tx"), nil, err 116 } 117 118 _, _, err = txCtx.App.Deliver(txCtx.TxGen.TxEncoder(), tx) 119 if err != nil { 120 return simtypes.NoOpMsg(txCtx.ModuleName, txCtx.MsgType, "unable to deliver tx"), nil, err 121 } 122 123 return simtypes.NewOperationMsg(txCtx.Msg, true, "", txCtx.Cdc), nil, nil 124 }