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