github.com/Finschia/finschia-sdk@v0.48.1/types/simulation/types.go (about)

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