github.com/cosmos/cosmos-sdk@v0.50.10/types/simulation/types.go (about)

     1  package simulation
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"math/rand"
     7  	"time"
     8  
     9  	"github.com/cosmos/gogoproto/proto"
    10  
    11  	"github.com/cosmos/cosmos-sdk/baseapp"
    12  	sdk "github.com/cosmos/cosmos-sdk/types"
    13  	"github.com/cosmos/cosmos-sdk/types/kv"
    14  )
    15  
    16  // Deprecated: Use WeightedProposalMsg instead.
    17  type WeightedProposalContent interface {
    18  	AppParamsKey() string                   // key used to retrieve the value of the weight from the simulation application params
    19  	DefaultWeight() int                     // default weight
    20  	ContentSimulatorFn() ContentSimulatorFn // content simulator function
    21  }
    22  
    23  // Deprecated: Use MsgSimulatorFn instead.
    24  type ContentSimulatorFn func(r *rand.Rand, ctx sdk.Context, accs []Account) Content
    25  
    26  // Deprecated: Use MsgSimulatorFn instead.
    27  type Content interface {
    28  	GetTitle() string
    29  	GetDescription() string
    30  	ProposalRoute() string
    31  	ProposalType() string
    32  	ValidateBasic() error
    33  	String() string
    34  }
    35  
    36  type WeightedProposalMsg interface {
    37  	AppParamsKey() string           // key used to retrieve the value of the weight from the simulation application params
    38  	DefaultWeight() int             // default weight
    39  	MsgSimulatorFn() MsgSimulatorFn // msg simulator function
    40  }
    41  
    42  type MsgSimulatorFn func(r *rand.Rand, ctx sdk.Context, accs []Account) sdk.Msg
    43  
    44  type SimValFn func(r *rand.Rand) string
    45  
    46  type LegacyParamChange interface {
    47  	Subspace() string
    48  	Key() string
    49  	SimValue() SimValFn
    50  	ComposedKey() string
    51  }
    52  
    53  type WeightedOperation interface {
    54  	Weight() int
    55  	Op() Operation
    56  }
    57  
    58  // Operation runs a state machine transition, and ensures the transition
    59  // happened as expected.  The operation could be running and testing a fuzzed
    60  // transaction, or doing the same for a message.
    61  //
    62  // For ease of debugging, an operation returns a descriptive message "action",
    63  // which details what this fuzzed state machine transition actually did.
    64  //
    65  // Operations can optionally provide a list of "FutureOperations" to run later
    66  // These will be ran at the beginning of the corresponding block.
    67  type Operation func(r *rand.Rand, app *baseapp.BaseApp,
    68  	ctx sdk.Context, accounts []Account, chainID string) (
    69  	OperationMsg OperationMsg, futureOps []FutureOperation, err error)
    70  
    71  // OperationMsg - structure for operation output
    72  type OperationMsg struct {
    73  	Route   string `json:"route" yaml:"route"`     // msg route (i.e module name)
    74  	Name    string `json:"name" yaml:"name"`       // operation name (msg Type or "no-operation")
    75  	Comment string `json:"comment" yaml:"comment"` // additional comment
    76  	OK      bool   `json:"ok" yaml:"ok"`           // success
    77  	Msg     []byte `json:"msg" yaml:"msg"`         // protobuf encoded msg
    78  }
    79  
    80  // NewOperationMsgBasic creates a new operation message from raw input.
    81  func NewOperationMsgBasic(moduleName, msgType, comment string, ok bool, msg []byte) OperationMsg {
    82  	return OperationMsg{
    83  		Route:   moduleName,
    84  		Name:    msgType,
    85  		Comment: comment,
    86  		OK:      ok,
    87  		Msg:     msg,
    88  	}
    89  }
    90  
    91  // NewOperationMsg - create a new operation message from sdk.Msg
    92  func NewOperationMsg(msg sdk.Msg, ok bool, comment string) OperationMsg {
    93  	msgType := sdk.MsgTypeURL(msg)
    94  	moduleName := sdk.GetModuleNameFromTypeURL(msgType)
    95  	if moduleName == "" {
    96  		moduleName = msgType
    97  	}
    98  	protoBz, err := proto.Marshal(msg)
    99  	if err != nil {
   100  		panic(fmt.Errorf("failed to marshal proto message: %w", err))
   101  	}
   102  
   103  	return NewOperationMsgBasic(moduleName, msgType, comment, ok, protoBz)
   104  }
   105  
   106  // NoOpMsg - create a no-operation message
   107  func NoOpMsg(moduleName, msgType, comment string) OperationMsg {
   108  	return NewOperationMsgBasic(moduleName, msgType, comment, false, nil)
   109  }
   110  
   111  // log entry text for this operation msg
   112  func (om OperationMsg) String() string {
   113  	out, err := json.Marshal(om)
   114  	if err != nil {
   115  		panic(err)
   116  	}
   117  
   118  	return string(out)
   119  }
   120  
   121  // MustMarshal Marshals the operation msg, panic on error
   122  func (om OperationMsg) MustMarshal() json.RawMessage {
   123  	out, err := json.Marshal(om)
   124  	if err != nil {
   125  		panic(err)
   126  	}
   127  
   128  	return out
   129  }
   130  
   131  // LogEvent adds an event for the events stats
   132  func (om OperationMsg) LogEvent(eventLogger func(route, op, evResult string)) {
   133  	pass := "ok"
   134  	if !om.OK {
   135  		pass = "failure"
   136  	}
   137  
   138  	eventLogger(om.Route, om.Name, pass)
   139  }
   140  
   141  // FutureOperation is an operation which will be ran at the beginning of the
   142  // provided BlockHeight. If both a BlockHeight and BlockTime are specified, it
   143  // will use the BlockHeight. In the (likely) event that multiple operations
   144  // are queued at the same block height, they will execute in a FIFO pattern.
   145  type FutureOperation struct {
   146  	BlockHeight int
   147  	BlockTime   time.Time
   148  	Op          Operation
   149  }
   150  
   151  // AppParams defines a flat JSON of key/values for all possible configurable
   152  // simulation parameters. It might contain: operation weights, simulation parameters
   153  // and flattened module state parameters (i.e not stored under it's respective module name).
   154  type AppParams map[string]json.RawMessage
   155  
   156  // GetOrGenerate attempts to get a given parameter by key from the AppParams
   157  // object. If it exists, it'll be decoded and returned. Otherwise, the provided
   158  // ParamSimulator is used to generate a random value or default value (eg: in the
   159  // case of operation weights where Rand is not used).
   160  func (sp AppParams) GetOrGenerate(key string, ptr interface{}, r *rand.Rand, ps ParamSimulator) {
   161  	if v, ok := sp[key]; ok && v != nil {
   162  		err := json.Unmarshal(v, ptr)
   163  		if err != nil {
   164  			panic(err)
   165  		}
   166  		return
   167  	}
   168  
   169  	ps(r)
   170  }
   171  
   172  type ParamSimulator func(r *rand.Rand)
   173  
   174  type SelectOpFn func(r *rand.Rand) Operation
   175  
   176  // AppStateFn returns the app state json bytes and the genesis accounts
   177  type AppStateFn func(r *rand.Rand, accs []Account, config Config) (
   178  	appState json.RawMessage, accounts []Account, chainId string, genesisTimestamp time.Time,
   179  )
   180  
   181  // RandomAccountFn returns a slice of n random simulation accounts
   182  type RandomAccountFn func(r *rand.Rand, n int) []Account
   183  
   184  type Params interface {
   185  	PastEvidenceFraction() float64
   186  	NumKeys() int
   187  	EvidenceFraction() float64
   188  	InitialLivenessWeightings() []int
   189  	LivenessTransitionMatrix() TransitionMatrix
   190  	BlockSizeTransitionMatrix() TransitionMatrix
   191  }
   192  
   193  // StoreDecoderRegistry defines each of the modules store decoders. Used for ImportExport
   194  // simulation.
   195  type StoreDecoderRegistry map[string]func(kvA, kvB kv.Pair) string