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  }