simulation: Use a simulation.Account struct
This removes privkeys and addresses from function signatures. This comes with a 11% performance improvement to the simulator, as we no longer keep recomputing the pubkeys. Once we move the transient store clearing to endblock, we can further raise the size of make test_sim_gaia_fast concretely, `make test_sim_gaia_fast` went from 16.8 seconds to 13.5 seconds on my system.
This commit is contained in:
parent
6835adb477
commit
bb624b36aa
|
@ -44,6 +44,7 @@ BREAKING CHANGES
|
|||
* [types] [\#2119](https://github.com/cosmos/cosmos-sdk/issues/2119) Parsed error messages and ABCI log errors to make them more human readable.
|
||||
* [simulation] Rename TestAndRunTx to Operation [#2153](https://github.com/cosmos/cosmos-sdk/pull/2153)
|
||||
* [simulation] Remove log and testing.TB from Operation and Invariants, in favor of using errors \#2282
|
||||
* [simulation] Remove usage of keys and addrs in the types, in favor of simulation.Account \#2384
|
||||
* [tools] Removed gocyclo [#2211](https://github.com/cosmos/cosmos-sdk/issues/2211)
|
||||
* [baseapp] Remove `SetTxDecoder` in favor of requiring the decoder be set in baseapp initialization. [#1441](https://github.com/cosmos/cosmos-sdk/issues/1441)
|
||||
* [baseapp] [\#1921](https://github.com/cosmos/cosmos-sdk/issues/1921) Add minimumFees field to BaseApp.
|
||||
|
|
|
@ -10,7 +10,6 @@ import (
|
|||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
dbm "github.com/tendermint/tendermint/libs/db"
|
||||
"github.com/tendermint/tendermint/libs/log"
|
||||
|
||||
|
@ -42,14 +41,14 @@ func init() {
|
|||
flag.BoolVar(&commit, "SimulationCommit", false, "Have the simulation commit")
|
||||
}
|
||||
|
||||
func appStateFn(r *rand.Rand, keys []crypto.PrivKey, accs []sdk.AccAddress) json.RawMessage {
|
||||
func appStateFn(r *rand.Rand, accs []simulation.Account) json.RawMessage {
|
||||
var genesisAccounts []GenesisAccount
|
||||
|
||||
// Randomly generate some genesis accounts
|
||||
for _, acc := range accs {
|
||||
coins := sdk.Coins{sdk.Coin{"steak", sdk.NewInt(100)}}
|
||||
genesisAccounts = append(genesisAccounts, GenesisAccount{
|
||||
Address: acc,
|
||||
Address: acc.Address,
|
||||
Coins: coins,
|
||||
})
|
||||
}
|
||||
|
@ -61,10 +60,10 @@ func appStateFn(r *rand.Rand, keys []crypto.PrivKey, accs []sdk.AccAddress) json
|
|||
// XXX Try different numbers of initially bonded validators
|
||||
numInitiallyBonded := int64(50)
|
||||
for i := 0; i < int(numInitiallyBonded); i++ {
|
||||
validator := stake.NewValidator(sdk.ValAddress(accs[i]), keys[i].PubKey(), stake.Description{})
|
||||
validator := stake.NewValidator(sdk.ValAddress(accs[i].Address), accs[i].PubKey, stake.Description{})
|
||||
validator.Tokens = sdk.NewDec(100)
|
||||
validator.DelegatorShares = sdk.NewDec(100)
|
||||
delegation := stake.Delegation{accs[i], sdk.ValAddress(accs[i]), sdk.NewDec(100), 0}
|
||||
delegation := stake.Delegation{accs[i].Address, sdk.ValAddress(accs[i].Address), sdk.NewDec(100), 0}
|
||||
validators = append(validators, validator)
|
||||
delegations = append(delegations, delegation)
|
||||
}
|
||||
|
|
|
@ -18,19 +18,18 @@ import (
|
|||
// SimulateSingleInputMsgSend tests and runs a single msg send, with one input and one output, where both
|
||||
// accounts already exist.
|
||||
func SimulateSingleInputMsgSend(mapper auth.AccountMapper) simulation.Operation {
|
||||
return func(r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, event func(string)) (action string, fOps []simulation.FutureOperation, err error) {
|
||||
fromKey := simulation.RandomKey(r, keys)
|
||||
fromAddr := sdk.AccAddress(fromKey.PubKey().Address())
|
||||
toKey := simulation.RandomKey(r, keys)
|
||||
return func(r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accs []simulation.Account, event func(string)) (action string, fOps []simulation.FutureOperation, err error) {
|
||||
fromAcc := simulation.RandomAcc(r, accs)
|
||||
toAcc := simulation.RandomAcc(r, accs)
|
||||
// Disallow sending money to yourself
|
||||
for {
|
||||
if !fromKey.Equals(toKey) {
|
||||
if !fromAcc.PubKey.Equals(toAcc.PubKey) {
|
||||
break
|
||||
}
|
||||
toKey = simulation.RandomKey(r, keys)
|
||||
toAcc = simulation.RandomAcc(r, accs)
|
||||
}
|
||||
toAddr := sdk.AccAddress(toKey.PubKey().Address())
|
||||
initFromCoins := mapper.GetAccount(ctx, fromAddr).GetCoins()
|
||||
toAddr := toAcc.Address
|
||||
initFromCoins := mapper.GetAccount(ctx, fromAcc.Address).GetCoins()
|
||||
|
||||
if len(initFromCoins) == 0 {
|
||||
return "skipping, no coins at all", nil, nil
|
||||
|
@ -43,7 +42,7 @@ func SimulateSingleInputMsgSend(mapper auth.AccountMapper) simulation.Operation
|
|||
}
|
||||
|
||||
action = fmt.Sprintf("%s is sending %s %s to %s",
|
||||
fromAddr.String(),
|
||||
fromAcc.Address.String(),
|
||||
amt.String(),
|
||||
initFromCoins[denomIndex].Denom,
|
||||
toAddr.String(),
|
||||
|
@ -51,10 +50,10 @@ func SimulateSingleInputMsgSend(mapper auth.AccountMapper) simulation.Operation
|
|||
|
||||
coins := sdk.Coins{{initFromCoins[denomIndex].Denom, amt}}
|
||||
var msg = bank.MsgSend{
|
||||
Inputs: []bank.Input{bank.NewInput(fromAddr, coins)},
|
||||
Inputs: []bank.Input{bank.NewInput(fromAcc.Address, coins)},
|
||||
Outputs: []bank.Output{bank.NewOutput(toAddr, coins)},
|
||||
}
|
||||
goErr = sendAndVerifyMsgSend(app, mapper, msg, ctx, []crypto.PrivKey{fromKey})
|
||||
goErr = sendAndVerifyMsgSend(app, mapper, msg, ctx, []crypto.PrivKey{fromAcc.PrivKey})
|
||||
if goErr != nil {
|
||||
return "", nil, goErr
|
||||
}
|
||||
|
|
|
@ -5,8 +5,6 @@ import (
|
|||
"math/rand"
|
||||
"testing"
|
||||
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/bank"
|
||||
"github.com/cosmos/cosmos-sdk/x/mock"
|
||||
|
@ -26,8 +24,8 @@ func TestBankWithRandomMessages(t *testing.T) {
|
|||
panic(err)
|
||||
}
|
||||
|
||||
appStateFn := func(r *rand.Rand, keys []crypto.PrivKey, accs []sdk.AccAddress) json.RawMessage {
|
||||
mock.RandomSetGenesis(r, mapp, accs, []string{"stake"})
|
||||
appStateFn := func(r *rand.Rand, accs []simulation.Account) json.RawMessage {
|
||||
simulation.RandomSetGenesis(r, mapp, accs, []string{"stake"})
|
||||
return json.RawMessage("{}")
|
||||
}
|
||||
|
||||
|
|
|
@ -6,8 +6,6 @@ import (
|
|||
"math/rand"
|
||||
"time"
|
||||
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/baseapp"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/gov"
|
||||
|
@ -45,9 +43,9 @@ func SimulateSubmittingVotingAndSlashingForProposal(k gov.Keeper, sk stake.Keepe
|
|||
})
|
||||
statePercentageArray := []float64{1, .9, .75, .4, .15, 0}
|
||||
curNumVotesState := 1
|
||||
return func(r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, event func(string)) (action string, fOps []simulation.FutureOperation, err error) {
|
||||
return func(r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accs []simulation.Account, event func(string)) (action string, fOps []simulation.FutureOperation, err error) {
|
||||
// 1) submit proposal now
|
||||
sender := simulation.RandomKey(r, keys)
|
||||
sender := simulation.RandomAcc(r, accs)
|
||||
msg, err := simulationCreateMsgSubmitProposal(r, sender)
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
|
@ -61,16 +59,16 @@ func SimulateSubmittingVotingAndSlashingForProposal(k gov.Keeper, sk stake.Keepe
|
|||
// 2) Schedule operations for votes
|
||||
// 2.1) first pick a number of people to vote.
|
||||
curNumVotesState = numVotesTransitionMatrix.NextState(r, curNumVotesState)
|
||||
numVotes := int(math.Ceil(float64(len(keys)) * statePercentageArray[curNumVotesState]))
|
||||
numVotes := int(math.Ceil(float64(len(accs)) * statePercentageArray[curNumVotesState]))
|
||||
// 2.2) select who votes and when
|
||||
whoVotes := r.Perm(len(keys))
|
||||
whoVotes := r.Perm(len(accs))
|
||||
// didntVote := whoVotes[numVotes:]
|
||||
whoVotes = whoVotes[:numVotes]
|
||||
votingPeriod := k.GetVotingProcedure(ctx).VotingPeriod
|
||||
fops := make([]simulation.FutureOperation, numVotes+1)
|
||||
for i := 0; i < numVotes; i++ {
|
||||
whenVote := ctx.BlockHeader().Time.Add(time.Duration(r.Int63n(int64(votingPeriod.Seconds()))) * time.Second)
|
||||
fops[i] = simulation.FutureOperation{BlockTime: whenVote, Op: operationSimulateMsgVote(k, sk, keys[whoVotes[i]], proposalID)}
|
||||
fops[i] = simulation.FutureOperation{BlockTime: whenVote, Op: operationSimulateMsgVote(k, sk, accs[whoVotes[i]], proposalID)}
|
||||
}
|
||||
// 3) Make an operation to ensure slashes were done correctly. (Really should be a future invariant)
|
||||
// TODO: Find a way to check if a validator was slashed other than just checking their balance a block
|
||||
|
@ -84,8 +82,8 @@ func SimulateSubmittingVotingAndSlashingForProposal(k gov.Keeper, sk stake.Keepe
|
|||
// Note: Currently doesn't ensure that the proposal txt is in JSON form
|
||||
func SimulateMsgSubmitProposal(k gov.Keeper, sk stake.Keeper) simulation.Operation {
|
||||
handler := gov.NewHandler(k)
|
||||
return func(r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, event func(string)) (action string, fOps []simulation.FutureOperation, err error) {
|
||||
sender := simulation.RandomKey(r, keys)
|
||||
return func(r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accs []simulation.Account, event func(string)) (action string, fOps []simulation.FutureOperation, err error) {
|
||||
sender := simulation.RandomAcc(r, accs)
|
||||
msg, err := simulationCreateMsgSubmitProposal(r, sender)
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
|
@ -111,14 +109,13 @@ func simulateHandleMsgSubmitProposal(msg gov.MsgSubmitProposal, sk stake.Keeper,
|
|||
return
|
||||
}
|
||||
|
||||
func simulationCreateMsgSubmitProposal(r *rand.Rand, sender crypto.PrivKey) (msg gov.MsgSubmitProposal, err error) {
|
||||
addr := sdk.AccAddress(sender.PubKey().Address())
|
||||
func simulationCreateMsgSubmitProposal(r *rand.Rand, sender simulation.Account) (msg gov.MsgSubmitProposal, err error) {
|
||||
deposit := randomDeposit(r)
|
||||
msg = gov.NewMsgSubmitProposal(
|
||||
simulation.RandStringOfLength(r, 5),
|
||||
simulation.RandStringOfLength(r, 5),
|
||||
gov.ProposalTypeText,
|
||||
addr,
|
||||
sender.Address,
|
||||
deposit,
|
||||
)
|
||||
if msg.ValidateBasic() != nil {
|
||||
|
@ -129,15 +126,14 @@ func simulationCreateMsgSubmitProposal(r *rand.Rand, sender crypto.PrivKey) (msg
|
|||
|
||||
// SimulateMsgDeposit
|
||||
func SimulateMsgDeposit(k gov.Keeper, sk stake.Keeper) simulation.Operation {
|
||||
return func(r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, event func(string)) (action string, fOp []simulation.FutureOperation, err error) {
|
||||
key := simulation.RandomKey(r, keys)
|
||||
addr := sdk.AccAddress(key.PubKey().Address())
|
||||
return func(r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accs []simulation.Account, event func(string)) (action string, fOp []simulation.FutureOperation, err error) {
|
||||
acc := simulation.RandomAcc(r, accs)
|
||||
proposalID, ok := randomProposalID(r, k, ctx)
|
||||
if !ok {
|
||||
return "no-operation", nil, nil
|
||||
}
|
||||
deposit := randomDeposit(r)
|
||||
msg := gov.NewMsgDeposit(addr, proposalID, deposit)
|
||||
msg := gov.NewMsgDeposit(acc.Address, proposalID, deposit)
|
||||
if msg.ValidateBasic() != nil {
|
||||
return "", nil, fmt.Errorf("expected msg to pass ValidateBasic: %s", msg.GetSignBytes())
|
||||
}
|
||||
|
@ -159,14 +155,14 @@ func SimulateMsgDeposit(k gov.Keeper, sk stake.Keeper) simulation.Operation {
|
|||
// SimulateMsgVote
|
||||
// nolint: unparam
|
||||
func SimulateMsgVote(k gov.Keeper, sk stake.Keeper) simulation.Operation {
|
||||
return operationSimulateMsgVote(k, sk, nil, -1)
|
||||
return operationSimulateMsgVote(k, sk, simulation.Account{}, -1)
|
||||
}
|
||||
|
||||
// nolint: unparam
|
||||
func operationSimulateMsgVote(k gov.Keeper, sk stake.Keeper, key crypto.PrivKey, proposalID int64) simulation.Operation {
|
||||
return func(r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, event func(string)) (action string, fOp []simulation.FutureOperation, err error) {
|
||||
if key == nil {
|
||||
key = simulation.RandomKey(r, keys)
|
||||
func operationSimulateMsgVote(k gov.Keeper, sk stake.Keeper, acc simulation.Account, proposalID int64) simulation.Operation {
|
||||
return func(r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accs []simulation.Account, event func(string)) (action string, fOp []simulation.FutureOperation, err error) {
|
||||
if acc.Equals(simulation.Account{}) {
|
||||
acc = simulation.RandomAcc(r, accs)
|
||||
}
|
||||
|
||||
var ok bool
|
||||
|
@ -177,10 +173,9 @@ func operationSimulateMsgVote(k gov.Keeper, sk stake.Keeper, key crypto.PrivKey,
|
|||
return "no-operation", nil, nil
|
||||
}
|
||||
}
|
||||
addr := sdk.AccAddress(key.PubKey().Address())
|
||||
option := randomVotingOption(r)
|
||||
|
||||
msg := gov.NewMsgVote(addr, proposalID, option)
|
||||
msg := gov.NewMsgVote(acc.Address, proposalID, option)
|
||||
if msg.ValidateBasic() != nil {
|
||||
return "", nil, fmt.Errorf("expected msg to pass ValidateBasic: %s", msg.GetSignBytes())
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@ import (
|
|||
"testing"
|
||||
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/bank"
|
||||
|
@ -43,12 +42,12 @@ func TestGovWithRandomMessages(t *testing.T) {
|
|||
panic(err)
|
||||
}
|
||||
|
||||
appStateFn := func(r *rand.Rand, keys []crypto.PrivKey, accs []sdk.AccAddress) json.RawMessage {
|
||||
mock.RandomSetGenesis(r, mapp, accs, []string{"stake"})
|
||||
appStateFn := func(r *rand.Rand, accs []simulation.Account) json.RawMessage {
|
||||
simulation.RandomSetGenesis(r, mapp, accs, []string{"stake"})
|
||||
return json.RawMessage("{}")
|
||||
}
|
||||
|
||||
setup := func(r *rand.Rand, privKeys []crypto.PrivKey) {
|
||||
setup := func(r *rand.Rand, accs []simulation.Account) {
|
||||
ctx := mapp.NewContext(false, abci.Header{})
|
||||
stake.InitGenesis(ctx, stakeKeeper, stake.DefaultGenesisState())
|
||||
gov.InitGenesis(ctx, govKeeper, gov.DefaultGenesisState())
|
||||
|
|
|
@ -15,17 +15,15 @@ import (
|
|||
"time"
|
||||
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
tmtypes "github.com/tendermint/tendermint/types"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/baseapp"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/mock"
|
||||
)
|
||||
|
||||
// Simulate tests application by sending random messages.
|
||||
func Simulate(t *testing.T, app *baseapp.BaseApp,
|
||||
appStateFn func(r *rand.Rand, keys []crypto.PrivKey, accs []sdk.AccAddress) json.RawMessage,
|
||||
appStateFn func(r *rand.Rand, accs []Account) json.RawMessage,
|
||||
ops []WeightedOperation, setups []RandSetup,
|
||||
invariants []Invariant, numBlocks int, blockSize int, commit bool) error {
|
||||
|
||||
|
@ -33,16 +31,16 @@ func Simulate(t *testing.T, app *baseapp.BaseApp,
|
|||
return SimulateFromSeed(t, app, appStateFn, time, ops, setups, invariants, numBlocks, blockSize, commit)
|
||||
}
|
||||
|
||||
func initChain(r *rand.Rand, keys []crypto.PrivKey, accs []sdk.AccAddress, setups []RandSetup, app *baseapp.BaseApp,
|
||||
appStateFn func(r *rand.Rand, keys []crypto.PrivKey, accs []sdk.AccAddress) json.RawMessage) (validators map[string]mockValidator) {
|
||||
res := app.InitChain(abci.RequestInitChain{AppStateBytes: appStateFn(r, keys, accs)})
|
||||
func initChain(r *rand.Rand, accounts []Account, setups []RandSetup, app *baseapp.BaseApp,
|
||||
appStateFn func(r *rand.Rand, accounts []Account) json.RawMessage) (validators map[string]mockValidator) {
|
||||
res := app.InitChain(abci.RequestInitChain{AppStateBytes: appStateFn(r, accounts)})
|
||||
validators = make(map[string]mockValidator)
|
||||
for _, validator := range res.Validators {
|
||||
validators[string(validator.Address)] = mockValidator{validator, GetMemberOfInitialState(r, initialLivenessWeightings)}
|
||||
}
|
||||
|
||||
for i := 0; i < len(setups); i++ {
|
||||
setups[i](r, keys)
|
||||
setups[i](r, accounts)
|
||||
}
|
||||
|
||||
return
|
||||
|
@ -56,7 +54,7 @@ func randTimestamp(r *rand.Rand) time.Time {
|
|||
// SimulateFromSeed tests an application by running the provided
|
||||
// operations, testing the provided invariants, but using the provided seed.
|
||||
func SimulateFromSeed(tb testing.TB, app *baseapp.BaseApp,
|
||||
appStateFn func(r *rand.Rand, keys []crypto.PrivKey, accs []sdk.AccAddress) json.RawMessage,
|
||||
appStateFn func(r *rand.Rand, accs []Account) json.RawMessage,
|
||||
seed int64, ops []WeightedOperation, setups []RandSetup, invariants []Invariant,
|
||||
numBlocks int, blockSize int, commit bool) (simError error) {
|
||||
|
||||
|
@ -69,7 +67,7 @@ func SimulateFromSeed(tb testing.TB, app *baseapp.BaseApp,
|
|||
fmt.Printf("Starting the simulation from time %v, unixtime %v\n", timestamp.UTC().Format(time.UnixDate), timestamp.Unix())
|
||||
timeDiff := maxTimePerBlock - minTimePerBlock
|
||||
|
||||
keys, accs := mock.GeneratePrivKeyAddressPairsFromRand(r, numKeys)
|
||||
accs := RandomAccounts(r, numKeys)
|
||||
|
||||
// Setup event stats
|
||||
events := make(map[string]uint)
|
||||
|
@ -77,7 +75,7 @@ func SimulateFromSeed(tb testing.TB, app *baseapp.BaseApp,
|
|||
events[what]++
|
||||
}
|
||||
|
||||
validators := initChain(r, keys, accs, setups, app, appStateFn)
|
||||
validators := initChain(r, accs, setups, app, appStateFn)
|
||||
|
||||
header := abci.Header{Height: 0, Time: timestamp}
|
||||
opCount := 0
|
||||
|
@ -139,10 +137,10 @@ func SimulateFromSeed(tb testing.TB, app *baseapp.BaseApp,
|
|||
thisBlockSize := getBlockSize(r, blockSize)
|
||||
|
||||
// Run queued operations. Ignores blocksize if blocksize is too small
|
||||
numQueuedOpsRan := runQueuedOperations(operationQueue, int(header.Height), tb, r, app, ctx, keys, logWriter, displayLogs, event)
|
||||
numQueuedTimeOpsRan := runQueuedTimeOperations(timeOperationQueue, header.Time, tb, r, app, ctx, keys, logWriter, displayLogs, event)
|
||||
numQueuedOpsRan := runQueuedOperations(operationQueue, int(header.Height), tb, r, app, ctx, accs, logWriter, displayLogs, event)
|
||||
numQueuedTimeOpsRan := runQueuedTimeOperations(timeOperationQueue, header.Time, tb, r, app, ctx, accs, logWriter, displayLogs, event)
|
||||
thisBlockSize = thisBlockSize - numQueuedOpsRan - numQueuedTimeOpsRan
|
||||
operations := blockSimulator(thisBlockSize, r, app, ctx, keys, header, logWriter)
|
||||
operations := blockSimulator(thisBlockSize, r, app, ctx, accs, header, logWriter)
|
||||
opCount += operations + numQueuedOpsRan + numQueuedTimeOpsRan
|
||||
|
||||
res := app.EndBlock(abci.RequestEndBlock{})
|
||||
|
@ -176,7 +174,7 @@ func SimulateFromSeed(tb testing.TB, app *baseapp.BaseApp,
|
|||
// Returns a function to simulate blocks. Written like this to avoid constant parameters being passed everytime, to minimize
|
||||
// memory overhead
|
||||
func createBlockSimulator(testingMode bool, tb testing.TB, t *testing.T, event func(string), invariants []Invariant, ops []WeightedOperation, operationQueue map[int][]Operation, timeOperationQueue []FutureOperation, totalNumBlocks int, displayLogs func()) func(
|
||||
blocksize int, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, privKeys []crypto.PrivKey, header abci.Header, logWriter func(string)) (opCount int) {
|
||||
blocksize int, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accounts []Account, header abci.Header, logWriter func(string)) (opCount int) {
|
||||
totalOpWeight := 0
|
||||
for i := 0; i < len(ops); i++ {
|
||||
totalOpWeight += ops[i].Weight
|
||||
|
@ -193,9 +191,9 @@ func createBlockSimulator(testingMode bool, tb testing.TB, t *testing.T, event f
|
|||
return ops[0].Op
|
||||
}
|
||||
return func(blocksize int, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context,
|
||||
keys []crypto.PrivKey, header abci.Header, logWriter func(string)) (opCount int) {
|
||||
accounts []Account, header abci.Header, logWriter func(string)) (opCount int) {
|
||||
for j := 0; j < blocksize; j++ {
|
||||
logUpdate, futureOps, err := selectOp(r)(r, app, ctx, keys, event)
|
||||
logUpdate, futureOps, err := selectOp(r)(r, app, ctx, accounts, event)
|
||||
if err != nil {
|
||||
displayLogs()
|
||||
tb.Fatalf("error on operation %d within block %d, %v", header.Height, opCount, err)
|
||||
|
@ -264,14 +262,14 @@ func queueOperations(queuedOperations map[int][]Operation, queuedTimeOperations
|
|||
|
||||
// nolint: errcheck
|
||||
func runQueuedOperations(queueOperations map[int][]Operation, height int, tb testing.TB, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context,
|
||||
privKeys []crypto.PrivKey, logWriter func(string), displayLogs func(), event func(string)) (numOpsRan int) {
|
||||
accounts []Account, logWriter func(string), displayLogs func(), event func(string)) (numOpsRan int) {
|
||||
if queuedOps, ok := queueOperations[height]; ok {
|
||||
numOps := len(queuedOps)
|
||||
for i := 0; i < numOps; i++ {
|
||||
// For now, queued operations cannot queue more operations.
|
||||
// If a need arises for us to support queued messages to queue more messages, this can
|
||||
// be changed.
|
||||
logUpdate, _, err := queuedOps[i](r, app, ctx, privKeys, event)
|
||||
logUpdate, _, err := queuedOps[i](r, app, ctx, accounts, event)
|
||||
logWriter(logUpdate)
|
||||
if err != nil {
|
||||
displayLogs()
|
||||
|
@ -285,14 +283,14 @@ func runQueuedOperations(queueOperations map[int][]Operation, height int, tb tes
|
|||
}
|
||||
|
||||
func runQueuedTimeOperations(queueOperations []FutureOperation, currentTime time.Time, tb testing.TB, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context,
|
||||
privKeys []crypto.PrivKey, logWriter func(string), displayLogs func(), event func(string)) (numOpsRan int) {
|
||||
accounts []Account, logWriter func(string), displayLogs func(), event func(string)) (numOpsRan int) {
|
||||
|
||||
numOpsRan = 0
|
||||
for len(queueOperations) > 0 && currentTime.After(queueOperations[0].BlockTime) {
|
||||
// For now, queued operations cannot queue more operations.
|
||||
// If a need arises for us to support queued messages to queue more messages, this can
|
||||
// be changed.
|
||||
logUpdate, _, err := queueOperations[0].Op(r, app, ctx, privKeys, event)
|
||||
logUpdate, _, err := queueOperations[0].Op(r, app, ctx, accounts, event)
|
||||
logWriter(logUpdate)
|
||||
if err != nil {
|
||||
displayLogs()
|
||||
|
|
|
@ -23,11 +23,11 @@ type (
|
|||
// Operations can optionally provide a list of "FutureOperations" to run later
|
||||
// These will be ran at the beginning of the corresponding block.
|
||||
Operation func(r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context,
|
||||
privKeys []crypto.PrivKey, event func(string),
|
||||
accounts []Account, event func(string),
|
||||
) (action string, futureOperations []FutureOperation, err error)
|
||||
|
||||
// RandSetup performs the random setup the mock module needs.
|
||||
RandSetup func(r *rand.Rand, privKeys []crypto.PrivKey)
|
||||
RandSetup func(r *rand.Rand, accounts []Account)
|
||||
|
||||
// An Invariant is a function which tests a particular invariant.
|
||||
// If the invariant has been broken, it should return an error
|
||||
|
@ -35,6 +35,15 @@ type (
|
|||
// The simulator will then halt and print the logs.
|
||||
Invariant func(app *baseapp.BaseApp) error
|
||||
|
||||
// Account contains a privkey, pubkey, address tuple
|
||||
// eventually more useful data can be placed in here.
|
||||
// (e.g. number of coins)
|
||||
Account struct {
|
||||
PrivKey crypto.PrivKey
|
||||
PubKey crypto.PubKey
|
||||
Address sdk.AccAddress
|
||||
}
|
||||
|
||||
mockValidator struct {
|
||||
val abci.Validator
|
||||
livenessState int
|
||||
|
@ -70,3 +79,8 @@ func PeriodicInvariant(invariant Invariant, period int, offset int) Invariant {
|
|||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// nolint
|
||||
func (acc Account) Equals(acc2 Account) bool {
|
||||
return acc.Address.Equals(acc2.Address)
|
||||
}
|
||||
|
|
|
@ -9,10 +9,12 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
"github.com/tendermint/tendermint/crypto/ed25519"
|
||||
"github.com/tendermint/tendermint/crypto/secp256k1"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/baseapp"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/mock"
|
||||
)
|
||||
|
||||
// shamelessly copied from https://stackoverflow.com/questions/22892120/how-to-generate-a-random-string-of-a-fixed-length-in-golang#31832326
|
||||
|
@ -56,10 +58,10 @@ func DisplayEvents(events map[string]uint) {
|
|||
}
|
||||
}
|
||||
|
||||
// Pick a random key from an array
|
||||
func RandomKey(r *rand.Rand, keys []crypto.PrivKey) crypto.PrivKey {
|
||||
return keys[r.Intn(
|
||||
len(keys),
|
||||
// RandomAcc pick a random account from an array
|
||||
func RandomAcc(r *rand.Rand, accs []Account) Account {
|
||||
return accs[r.Intn(
|
||||
len(accs),
|
||||
)]
|
||||
}
|
||||
|
||||
|
@ -68,6 +70,25 @@ func RandomAmount(r *rand.Rand, max sdk.Int) sdk.Int {
|
|||
return sdk.NewInt(int64(r.Intn(int(max.Int64()))))
|
||||
}
|
||||
|
||||
// RandomAccounts generates n random accounts
|
||||
func RandomAccounts(r *rand.Rand, n int) []Account {
|
||||
accs := make([]Account, n)
|
||||
for i := 0; i < n; i++ {
|
||||
// don't need that much entropy for simulation
|
||||
privkeySeed := make([]byte, 15)
|
||||
r.Read(privkeySeed)
|
||||
useSecp := r.Int63()%2 == 0
|
||||
if useSecp {
|
||||
accs[i].PrivKey = secp256k1.GenPrivKeySecp256k1(privkeySeed)
|
||||
} else {
|
||||
accs[i].PrivKey = ed25519.GenPrivKeyFromSecret(privkeySeed)
|
||||
}
|
||||
accs[i].PubKey = accs[i].PrivKey.PubKey()
|
||||
accs[i].Address = sdk.AccAddress(accs[i].PubKey.Address())
|
||||
}
|
||||
return accs
|
||||
}
|
||||
|
||||
// Builds a function to add logs for this particular block
|
||||
func addLogMessage(testingmode bool, blockLogBuilders []*strings.Builder, height int) func(string) {
|
||||
if testingmode {
|
||||
|
@ -92,6 +113,15 @@ func assertAllInvariants(t *testing.T, app *baseapp.BaseApp, invariants []Invari
|
|||
}
|
||||
}
|
||||
|
||||
// RandomSetGenesis wraps mock.RandomSetGenesis, but using simulation accounts
|
||||
func RandomSetGenesis(r *rand.Rand, app *mock.App, accs []Account, denoms []string) {
|
||||
addrs := make([]sdk.AccAddress, len(accs))
|
||||
for i := 0; i < len(accs); i++ {
|
||||
addrs[i] = accs[i].Address
|
||||
}
|
||||
mock.RandomSetGenesis(r, app, addrs, denoms)
|
||||
}
|
||||
|
||||
// Creates a function to print out the logs
|
||||
func logPrinter(testingmode bool, logs []*strings.Builder) func() {
|
||||
if testingmode {
|
||||
|
|
|
@ -4,8 +4,6 @@ import (
|
|||
"fmt"
|
||||
"math/rand"
|
||||
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/baseapp"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/mock/simulation"
|
||||
|
@ -14,9 +12,9 @@ import (
|
|||
|
||||
// SimulateMsgUnjail
|
||||
func SimulateMsgUnjail(k slashing.Keeper) simulation.Operation {
|
||||
return func(r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, event func(string)) (action string, fOp []simulation.FutureOperation, err error) {
|
||||
key := simulation.RandomKey(r, keys)
|
||||
address := sdk.ValAddress(key.PubKey().Address())
|
||||
return func(r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accs []simulation.Account, event func(string)) (action string, fOp []simulation.FutureOperation, err error) {
|
||||
acc := simulation.RandomAcc(r, accs)
|
||||
address := sdk.ValAddress(acc.Address)
|
||||
msg := slashing.NewMsgUnjail(address)
|
||||
if msg.ValidateBasic() != nil {
|
||||
return "", nil, fmt.Errorf("expected msg to pass ValidateBasic: %s", msg.GetSignBytes())
|
||||
|
|
|
@ -11,22 +11,20 @@ import (
|
|||
"github.com/cosmos/cosmos-sdk/x/mock/simulation"
|
||||
"github.com/cosmos/cosmos-sdk/x/stake"
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
)
|
||||
|
||||
// SimulateMsgCreateValidator
|
||||
func SimulateMsgCreateValidator(m auth.AccountMapper, k stake.Keeper) simulation.Operation {
|
||||
handler := stake.NewHandler(k)
|
||||
return func(r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, event func(string)) (action string, fOp []simulation.FutureOperation, err error) {
|
||||
return func(r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accs []simulation.Account, event func(string)) (action string, fOp []simulation.FutureOperation, err error) {
|
||||
|
||||
denom := k.GetParams(ctx).BondDenom
|
||||
description := stake.Description{
|
||||
Moniker: simulation.RandStringOfLength(r, 10),
|
||||
}
|
||||
key := simulation.RandomKey(r, keys)
|
||||
pubkey := key.PubKey()
|
||||
address := sdk.ValAddress(pubkey.Address())
|
||||
amount := m.GetAccount(ctx, sdk.AccAddress(address)).GetCoins().AmountOf(denom)
|
||||
acc := simulation.RandomAcc(r, accs)
|
||||
address := sdk.ValAddress(acc.Address)
|
||||
amount := m.GetAccount(ctx, acc.Address).GetCoins().AmountOf(denom)
|
||||
if amount.GT(sdk.ZeroInt()) {
|
||||
amount = simulation.RandomAmount(r, amount)
|
||||
}
|
||||
|
@ -36,8 +34,8 @@ func SimulateMsgCreateValidator(m auth.AccountMapper, k stake.Keeper) simulation
|
|||
msg := stake.MsgCreateValidator{
|
||||
Description: description,
|
||||
ValidatorAddr: address,
|
||||
DelegatorAddr: sdk.AccAddress(address),
|
||||
PubKey: pubkey,
|
||||
DelegatorAddr: acc.Address,
|
||||
PubKey: acc.PubKey,
|
||||
Delegation: sdk.NewCoin(denom, amount),
|
||||
}
|
||||
if msg.ValidateBasic() != nil {
|
||||
|
@ -58,7 +56,7 @@ func SimulateMsgCreateValidator(m auth.AccountMapper, k stake.Keeper) simulation
|
|||
// SimulateMsgEditValidator
|
||||
func SimulateMsgEditValidator(k stake.Keeper) simulation.Operation {
|
||||
handler := stake.NewHandler(k)
|
||||
return func(r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, event func(string)) (action string, fOp []simulation.FutureOperation, err error) {
|
||||
return func(r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accs []simulation.Account, event func(string)) (action string, fOp []simulation.FutureOperation, err error) {
|
||||
|
||||
description := stake.Description{
|
||||
Moniker: simulation.RandStringOfLength(r, 10),
|
||||
|
@ -66,9 +64,8 @@ func SimulateMsgEditValidator(k stake.Keeper) simulation.Operation {
|
|||
Website: simulation.RandStringOfLength(r, 10),
|
||||
Details: simulation.RandStringOfLength(r, 10),
|
||||
}
|
||||
key := simulation.RandomKey(r, keys)
|
||||
pubkey := key.PubKey()
|
||||
address := sdk.ValAddress(pubkey.Address())
|
||||
acc := simulation.RandomAcc(r, accs)
|
||||
address := sdk.ValAddress(acc.Address)
|
||||
msg := stake.MsgEditValidator{
|
||||
Description: description,
|
||||
ValidatorAddr: address,
|
||||
|
@ -90,13 +87,13 @@ func SimulateMsgEditValidator(k stake.Keeper) simulation.Operation {
|
|||
// SimulateMsgDelegate
|
||||
func SimulateMsgDelegate(m auth.AccountMapper, k stake.Keeper) simulation.Operation {
|
||||
handler := stake.NewHandler(k)
|
||||
return func(r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, event func(string)) (action string, fOp []simulation.FutureOperation, err error) {
|
||||
return func(r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accs []simulation.Account, event func(string)) (action string, fOp []simulation.FutureOperation, err error) {
|
||||
|
||||
denom := k.GetParams(ctx).BondDenom
|
||||
validatorKey := simulation.RandomKey(r, keys)
|
||||
validatorAddress := sdk.ValAddress(validatorKey.PubKey().Address())
|
||||
delegatorKey := simulation.RandomKey(r, keys)
|
||||
delegatorAddress := sdk.AccAddress(delegatorKey.PubKey().Address())
|
||||
validatorAcc := simulation.RandomAcc(r, accs)
|
||||
validatorAddress := sdk.ValAddress(validatorAcc.Address)
|
||||
delegatorAcc := simulation.RandomAcc(r, accs)
|
||||
delegatorAddress := delegatorAcc.Address
|
||||
amount := m.GetAccount(ctx, delegatorAddress).GetCoins().AmountOf(denom)
|
||||
if amount.GT(sdk.ZeroInt()) {
|
||||
amount = simulation.RandomAmount(r, amount)
|
||||
|
@ -126,13 +123,13 @@ func SimulateMsgDelegate(m auth.AccountMapper, k stake.Keeper) simulation.Operat
|
|||
// SimulateMsgBeginUnbonding
|
||||
func SimulateMsgBeginUnbonding(m auth.AccountMapper, k stake.Keeper) simulation.Operation {
|
||||
handler := stake.NewHandler(k)
|
||||
return func(r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, event func(string)) (action string, fOp []simulation.FutureOperation, err error) {
|
||||
return func(r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accs []simulation.Account, event func(string)) (action string, fOp []simulation.FutureOperation, err error) {
|
||||
|
||||
denom := k.GetParams(ctx).BondDenom
|
||||
validatorKey := simulation.RandomKey(r, keys)
|
||||
validatorAddress := sdk.ValAddress(validatorKey.PubKey().Address())
|
||||
delegatorKey := simulation.RandomKey(r, keys)
|
||||
delegatorAddress := sdk.AccAddress(delegatorKey.PubKey().Address())
|
||||
validatorAcc := simulation.RandomAcc(r, accs)
|
||||
validatorAddress := sdk.ValAddress(validatorAcc.Address)
|
||||
delegatorAcc := simulation.RandomAcc(r, accs)
|
||||
delegatorAddress := delegatorAcc.Address
|
||||
amount := m.GetAccount(ctx, delegatorAddress).GetCoins().AmountOf(denom)
|
||||
if amount.GT(sdk.ZeroInt()) {
|
||||
amount = simulation.RandomAmount(r, amount)
|
||||
|
@ -162,12 +159,12 @@ func SimulateMsgBeginUnbonding(m auth.AccountMapper, k stake.Keeper) simulation.
|
|||
// SimulateMsgCompleteUnbonding
|
||||
func SimulateMsgCompleteUnbonding(k stake.Keeper) simulation.Operation {
|
||||
handler := stake.NewHandler(k)
|
||||
return func(r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, event func(string)) (action string, fOp []simulation.FutureOperation, err error) {
|
||||
return func(r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accs []simulation.Account, event func(string)) (action string, fOp []simulation.FutureOperation, err error) {
|
||||
|
||||
validatorKey := simulation.RandomKey(r, keys)
|
||||
validatorAddress := sdk.ValAddress(validatorKey.PubKey().Address())
|
||||
delegatorKey := simulation.RandomKey(r, keys)
|
||||
delegatorAddress := sdk.AccAddress(delegatorKey.PubKey().Address())
|
||||
validatorAcc := simulation.RandomAcc(r, accs)
|
||||
validatorAddress := sdk.ValAddress(validatorAcc.Address)
|
||||
delegatorAcc := simulation.RandomAcc(r, accs)
|
||||
delegatorAddress := delegatorAcc.Address
|
||||
msg := stake.MsgCompleteUnbonding{
|
||||
DelegatorAddr: delegatorAddress,
|
||||
ValidatorAddr: validatorAddress,
|
||||
|
@ -189,15 +186,15 @@ func SimulateMsgCompleteUnbonding(k stake.Keeper) simulation.Operation {
|
|||
// SimulateMsgBeginRedelegate
|
||||
func SimulateMsgBeginRedelegate(m auth.AccountMapper, k stake.Keeper) simulation.Operation {
|
||||
handler := stake.NewHandler(k)
|
||||
return func(r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, event func(string)) (action string, fOp []simulation.FutureOperation, err error) {
|
||||
return func(r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accs []simulation.Account, event func(string)) (action string, fOp []simulation.FutureOperation, err error) {
|
||||
|
||||
denom := k.GetParams(ctx).BondDenom
|
||||
sourceValidatorKey := simulation.RandomKey(r, keys)
|
||||
sourceValidatorAddress := sdk.ValAddress(sourceValidatorKey.PubKey().Address())
|
||||
destValidatorKey := simulation.RandomKey(r, keys)
|
||||
destValidatorAddress := sdk.ValAddress(destValidatorKey.PubKey().Address())
|
||||
delegatorKey := simulation.RandomKey(r, keys)
|
||||
delegatorAddress := sdk.AccAddress(delegatorKey.PubKey().Address())
|
||||
sourceValidatorAcc := simulation.RandomAcc(r, accs)
|
||||
sourceValidatorAddress := sdk.ValAddress(sourceValidatorAcc.Address)
|
||||
destValidatorAcc := simulation.RandomAcc(r, accs)
|
||||
destValidatorAddress := sdk.ValAddress(destValidatorAcc.Address)
|
||||
delegatorAcc := simulation.RandomAcc(r, accs)
|
||||
delegatorAddress := delegatorAcc.Address
|
||||
// TODO
|
||||
amount := m.GetAccount(ctx, delegatorAddress).GetCoins().AmountOf(denom)
|
||||
if amount.GT(sdk.ZeroInt()) {
|
||||
|
@ -229,14 +226,14 @@ func SimulateMsgBeginRedelegate(m auth.AccountMapper, k stake.Keeper) simulation
|
|||
// SimulateMsgCompleteRedelegate
|
||||
func SimulateMsgCompleteRedelegate(k stake.Keeper) simulation.Operation {
|
||||
handler := stake.NewHandler(k)
|
||||
return func(r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, event func(string)) (action string, fOp []simulation.FutureOperation, err error) {
|
||||
return func(r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accs []simulation.Account, event func(string)) (action string, fOp []simulation.FutureOperation, err error) {
|
||||
|
||||
validatorSrcKey := simulation.RandomKey(r, keys)
|
||||
validatorSrcAddress := sdk.ValAddress(validatorSrcKey.PubKey().Address())
|
||||
validatorDstKey := simulation.RandomKey(r, keys)
|
||||
validatorDstAddress := sdk.ValAddress(validatorDstKey.PubKey().Address())
|
||||
delegatorKey := simulation.RandomKey(r, keys)
|
||||
delegatorAddress := sdk.AccAddress(delegatorKey.PubKey().Address())
|
||||
validatorSrcAcc := simulation.RandomAcc(r, accs)
|
||||
validatorSrcAddress := sdk.ValAddress(validatorSrcAcc.Address)
|
||||
validatorDstAcc := simulation.RandomAcc(r, accs)
|
||||
validatorDstAddress := sdk.ValAddress(validatorDstAcc.Address)
|
||||
delegatorAcc := simulation.RandomAcc(r, accs)
|
||||
delegatorAddress := delegatorAcc.Address
|
||||
msg := stake.MsgCompleteRedelegate{
|
||||
DelegatorAddr: delegatorAddress,
|
||||
ValidatorSrcAddr: validatorSrcAddress,
|
||||
|
@ -259,7 +256,7 @@ func SimulateMsgCompleteRedelegate(k stake.Keeper) simulation.Operation {
|
|||
// Setup
|
||||
// nolint: errcheck
|
||||
func Setup(mapp *mock.App, k stake.Keeper) simulation.RandSetup {
|
||||
return func(r *rand.Rand, privKeys []crypto.PrivKey) {
|
||||
return func(r *rand.Rand, accs []simulation.Account) {
|
||||
ctx := mapp.NewContext(false, abci.Header{})
|
||||
gen := stake.DefaultGenesisState()
|
||||
gen.Params.InflationMax = sdk.NewDec(0)
|
||||
|
|
|
@ -6,7 +6,6 @@ import (
|
|||
"testing"
|
||||
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/bank"
|
||||
|
@ -38,8 +37,8 @@ func TestStakeWithRandomMessages(t *testing.T) {
|
|||
panic(err)
|
||||
}
|
||||
|
||||
appStateFn := func(r *rand.Rand, keys []crypto.PrivKey, accs []sdk.AccAddress) json.RawMessage {
|
||||
mock.RandomSetGenesis(r, mapp, accs, []string{"stake"})
|
||||
appStateFn := func(r *rand.Rand, accs []simulation.Account) json.RawMessage {
|
||||
simulation.RandomSetGenesis(r, mapp, accs, []string{"stake"})
|
||||
return json.RawMessage("{}")
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue