simulation: Add benchmarking
This commit is contained in:
parent
fd8c1e5253
commit
46bbada4ee
|
@ -45,6 +45,7 @@ FEATURES
|
||||||
* SDK
|
* SDK
|
||||||
* [querier] added custom querier functionality, so ABCI query requests can be handled by keepers
|
* [querier] added custom querier functionality, so ABCI query requests can be handled by keepers
|
||||||
* [simulation] \#1924 allow operations to specify future operations
|
* [simulation] \#1924 allow operations to specify future operations
|
||||||
|
* [simulation] Add benchmarking capabilities
|
||||||
|
|
||||||
* Tendermint
|
* Tendermint
|
||||||
|
|
||||||
|
|
|
@ -112,6 +112,27 @@ func invariants(app *GaiaApp) []simulation.Invariant {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Profile with:
|
||||||
|
// /usr/local/go/bin/go test -benchmem -run=^$ github.com/cosmos/cosmos-sdk/cmd/gaia/app -bench ^BenchmarkFullGaiaSimulation$ -cpuprofile cpu.out
|
||||||
|
func BenchmarkFullGaiaSimulation(b *testing.B) {
|
||||||
|
// Setup Gaia application
|
||||||
|
var logger log.Logger
|
||||||
|
logger = log.NewNopLogger()
|
||||||
|
db := dbm.NewMemDB()
|
||||||
|
app := NewGaiaApp(logger, db, nil)
|
||||||
|
|
||||||
|
// Run randomized simulation
|
||||||
|
// TODO parameterize numbers, save for a later PR
|
||||||
|
simulation.BenchmarkSimulationFromSeed(
|
||||||
|
b, app.BaseApp, appStateFn, seed,
|
||||||
|
testAndRunTxs(app),
|
||||||
|
[]simulation.RandSetup{},
|
||||||
|
10,
|
||||||
|
100,
|
||||||
|
false,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
func TestFullGaiaSimulation(t *testing.T) {
|
func TestFullGaiaSimulation(t *testing.T) {
|
||||||
if !enabled {
|
if !enabled {
|
||||||
t.Skip("Skipping Gaia simulation")
|
t.Skip("Skipping Gaia simulation")
|
||||||
|
|
|
@ -21,7 +21,7 @@ import (
|
||||||
// SimulateSingleInputMsgSend tests and runs a single msg send, with one input and one output, where both
|
// SimulateSingleInputMsgSend tests and runs a single msg send, with one input and one output, where both
|
||||||
// accounts already exist.
|
// accounts already exist.
|
||||||
func SimulateSingleInputMsgSend(mapper auth.AccountMapper) simulation.Operation {
|
func SimulateSingleInputMsgSend(mapper auth.AccountMapper) simulation.Operation {
|
||||||
return func(t *testing.T, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string, event func(string)) (action string, fOps []simulation.FutureOperation, err sdk.Error) {
|
return func(tb testing.TB, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string, event func(string)) (action string, fOps []simulation.FutureOperation, err sdk.Error) {
|
||||||
fromKey := simulation.RandomKey(r, keys)
|
fromKey := simulation.RandomKey(r, keys)
|
||||||
fromAddr := sdk.AccAddress(fromKey.PubKey().Address())
|
fromAddr := sdk.AccAddress(fromKey.PubKey().Address())
|
||||||
toKey := simulation.RandomKey(r, keys)
|
toKey := simulation.RandomKey(r, keys)
|
||||||
|
@ -58,7 +58,7 @@ func SimulateSingleInputMsgSend(mapper auth.AccountMapper) simulation.Operation
|
||||||
Inputs: []bank.Input{bank.NewInput(fromAddr, coins)},
|
Inputs: []bank.Input{bank.NewInput(fromAddr, coins)},
|
||||||
Outputs: []bank.Output{bank.NewOutput(toAddr, coins)},
|
Outputs: []bank.Output{bank.NewOutput(toAddr, coins)},
|
||||||
}
|
}
|
||||||
sendAndVerifyMsgSend(t, app, mapper, msg, ctx, log, []crypto.PrivKey{fromKey})
|
sendAndVerifyMsgSend(tb, app, mapper, msg, ctx, log, []crypto.PrivKey{fromKey})
|
||||||
event("bank/sendAndVerifyMsgSend/ok")
|
event("bank/sendAndVerifyMsgSend/ok")
|
||||||
|
|
||||||
return action, nil, nil
|
return action, nil, nil
|
||||||
|
@ -66,7 +66,7 @@ func SimulateSingleInputMsgSend(mapper auth.AccountMapper) simulation.Operation
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sends and verifies the transition of a msg send. This fails if there are repeated inputs or outputs
|
// Sends and verifies the transition of a msg send. This fails if there are repeated inputs or outputs
|
||||||
func sendAndVerifyMsgSend(t *testing.T, app *baseapp.BaseApp, mapper auth.AccountMapper, msg bank.MsgSend, ctx sdk.Context, log string, privkeys []crypto.PrivKey) {
|
func sendAndVerifyMsgSend(tb testing.TB, app *baseapp.BaseApp, mapper auth.AccountMapper, msg bank.MsgSend, ctx sdk.Context, log string, privkeys []crypto.PrivKey) {
|
||||||
initialInputAddrCoins := make([]sdk.Coins, len(msg.Inputs))
|
initialInputAddrCoins := make([]sdk.Coins, len(msg.Inputs))
|
||||||
initialOutputAddrCoins := make([]sdk.Coins, len(msg.Outputs))
|
initialOutputAddrCoins := make([]sdk.Coins, len(msg.Outputs))
|
||||||
AccountNumbers := make([]int64, len(msg.Inputs))
|
AccountNumbers := make([]int64, len(msg.Inputs))
|
||||||
|
@ -91,12 +91,12 @@ func sendAndVerifyMsgSend(t *testing.T, app *baseapp.BaseApp, mapper auth.Accoun
|
||||||
// TODO: Do this in a more 'canonical' way
|
// TODO: Do this in a more 'canonical' way
|
||||||
fmt.Println(res)
|
fmt.Println(res)
|
||||||
fmt.Println(log)
|
fmt.Println(log)
|
||||||
t.FailNow()
|
tb.FailNow()
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := 0; i < len(msg.Inputs); i++ {
|
for i := 0; i < len(msg.Inputs); i++ {
|
||||||
terminalInputCoins := mapper.GetAccount(ctx, msg.Inputs[i].Address).GetCoins()
|
terminalInputCoins := mapper.GetAccount(ctx, msg.Inputs[i].Address).GetCoins()
|
||||||
require.Equal(t,
|
require.Equal(tb,
|
||||||
initialInputAddrCoins[i].Minus(msg.Inputs[i].Coins),
|
initialInputAddrCoins[i].Minus(msg.Inputs[i].Coins),
|
||||||
terminalInputCoins,
|
terminalInputCoins,
|
||||||
fmt.Sprintf("Input #%d had an incorrect amount of coins\n%s", i, log),
|
fmt.Sprintf("Input #%d had an incorrect amount of coins\n%s", i, log),
|
||||||
|
@ -104,11 +104,9 @@ func sendAndVerifyMsgSend(t *testing.T, app *baseapp.BaseApp, mapper auth.Accoun
|
||||||
}
|
}
|
||||||
for i := 0; i < len(msg.Outputs); i++ {
|
for i := 0; i < len(msg.Outputs); i++ {
|
||||||
terminalOutputCoins := mapper.GetAccount(ctx, msg.Outputs[i].Address).GetCoins()
|
terminalOutputCoins := mapper.GetAccount(ctx, msg.Outputs[i].Address).GetCoins()
|
||||||
require.Equal(t,
|
if !terminalOutputCoins.IsEqual(initialOutputAddrCoins[i].Plus(msg.Outputs[i].Coins)) {
|
||||||
initialOutputAddrCoins[i].Plus(msg.Outputs[i].Coins),
|
tb.Fatalf("Output #%d had an incorrect amount of coins\n%s", i, log)
|
||||||
terminalOutputCoins,
|
}
|
||||||
fmt.Sprintf("Output #%d had an incorrect amount of coins\n%s", i, log),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,8 +5,6 @@ import (
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
|
|
||||||
"github.com/tendermint/tendermint/crypto"
|
"github.com/tendermint/tendermint/crypto"
|
||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/baseapp"
|
"github.com/cosmos/cosmos-sdk/baseapp"
|
||||||
|
@ -23,7 +21,25 @@ const (
|
||||||
// SimulateMsgSubmitProposal simulates a msg Submit Proposal
|
// SimulateMsgSubmitProposal simulates a msg Submit Proposal
|
||||||
// Note: Currently doesn't ensure that the proposal txt is in JSON form
|
// Note: Currently doesn't ensure that the proposal txt is in JSON form
|
||||||
func SimulateMsgSubmitProposal(k gov.Keeper, sk stake.Keeper) simulation.Operation {
|
func SimulateMsgSubmitProposal(k gov.Keeper, sk stake.Keeper) simulation.Operation {
|
||||||
return func(t *testing.T, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string, event func(string)) (action string, fOps []simulation.FutureOperation, err sdk.Error) {
|
handler := gov.NewHandler(k)
|
||||||
|
return func(tb testing.TB, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string, event func(string)) (action string, fOps []simulation.FutureOperation, err sdk.Error) {
|
||||||
|
msg := simulationCreateMsgSubmitProposal(tb, r, keys, log)
|
||||||
|
ctx, write := ctx.CacheContext()
|
||||||
|
result := handler(ctx, msg)
|
||||||
|
if result.IsOK() {
|
||||||
|
// Update pool to keep invariants
|
||||||
|
pool := sk.GetPool(ctx)
|
||||||
|
pool.LooseTokens = pool.LooseTokens.Sub(sdk.NewDecFromInt(msg.InitialDeposit.AmountOf(denom)))
|
||||||
|
sk.SetPool(ctx, pool)
|
||||||
|
write()
|
||||||
|
}
|
||||||
|
event(fmt.Sprintf("gov/MsgSubmitProposal/%v", result.IsOK()))
|
||||||
|
action = fmt.Sprintf("TestMsgSubmitProposal: ok %v, msg %s", result.IsOK(), msg.GetSignBytes())
|
||||||
|
return action, nil, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func simulationCreateMsgSubmitProposal(tb testing.TB, r *rand.Rand, keys []crypto.PrivKey, log string) gov.MsgSubmitProposal {
|
||||||
key := simulation.RandomKey(r, keys)
|
key := simulation.RandomKey(r, keys)
|
||||||
addr := sdk.AccAddress(key.PubKey().Address())
|
addr := sdk.AccAddress(key.PubKey().Address())
|
||||||
deposit := randomDeposit(r)
|
deposit := randomDeposit(r)
|
||||||
|
@ -34,25 +50,15 @@ func SimulateMsgSubmitProposal(k gov.Keeper, sk stake.Keeper) simulation.Operati
|
||||||
addr,
|
addr,
|
||||||
deposit,
|
deposit,
|
||||||
)
|
)
|
||||||
require.Nil(t, msg.ValidateBasic(), "expected msg to pass ValidateBasic: %s", msg.GetSignBytes())
|
if msg.ValidateBasic() != nil {
|
||||||
ctx, write := ctx.CacheContext()
|
tb.Fatalf("expected msg to pass ValidateBasic: %s, log %s", msg.GetSignBytes(), log)
|
||||||
result := gov.NewHandler(k)(ctx, msg)
|
|
||||||
if result.IsOK() {
|
|
||||||
// Update pool to keep invariants
|
|
||||||
pool := sk.GetPool(ctx)
|
|
||||||
pool.LooseTokens = pool.LooseTokens.Sub(sdk.NewDecFromInt(deposit.AmountOf(denom)))
|
|
||||||
sk.SetPool(ctx, pool)
|
|
||||||
write()
|
|
||||||
}
|
|
||||||
event(fmt.Sprintf("gov/MsgSubmitProposal/%v", result.IsOK()))
|
|
||||||
action = fmt.Sprintf("TestMsgSubmitProposal: ok %v, msg %s", result.IsOK(), msg.GetSignBytes())
|
|
||||||
return action, nil, nil
|
|
||||||
}
|
}
|
||||||
|
return msg
|
||||||
}
|
}
|
||||||
|
|
||||||
// SimulateMsgDeposit
|
// SimulateMsgDeposit
|
||||||
func SimulateMsgDeposit(k gov.Keeper, sk stake.Keeper) simulation.Operation {
|
func SimulateMsgDeposit(k gov.Keeper, sk stake.Keeper) simulation.Operation {
|
||||||
return func(t *testing.T, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string, event func(string)) (action string, fOp []simulation.FutureOperation, err sdk.Error) {
|
return func(tb testing.TB, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string, event func(string)) (action string, fOp []simulation.FutureOperation, err sdk.Error) {
|
||||||
key := simulation.RandomKey(r, keys)
|
key := simulation.RandomKey(r, keys)
|
||||||
addr := sdk.AccAddress(key.PubKey().Address())
|
addr := sdk.AccAddress(key.PubKey().Address())
|
||||||
proposalID, ok := randomProposalID(r, k, ctx)
|
proposalID, ok := randomProposalID(r, k, ctx)
|
||||||
|
@ -61,7 +67,9 @@ func SimulateMsgDeposit(k gov.Keeper, sk stake.Keeper) simulation.Operation {
|
||||||
}
|
}
|
||||||
deposit := randomDeposit(r)
|
deposit := randomDeposit(r)
|
||||||
msg := gov.NewMsgDeposit(addr, proposalID, deposit)
|
msg := gov.NewMsgDeposit(addr, proposalID, deposit)
|
||||||
require.Nil(t, msg.ValidateBasic(), "expected msg to pass ValidateBasic: %s", msg.GetSignBytes())
|
if msg.ValidateBasic() != nil {
|
||||||
|
tb.Fatalf("expected msg to pass ValidateBasic: %s, log %s", msg.GetSignBytes(), log)
|
||||||
|
}
|
||||||
ctx, write := ctx.CacheContext()
|
ctx, write := ctx.CacheContext()
|
||||||
result := gov.NewHandler(k)(ctx, msg)
|
result := gov.NewHandler(k)(ctx, msg)
|
||||||
if result.IsOK() {
|
if result.IsOK() {
|
||||||
|
@ -79,7 +87,7 @@ func SimulateMsgDeposit(k gov.Keeper, sk stake.Keeper) simulation.Operation {
|
||||||
|
|
||||||
// SimulateMsgVote
|
// SimulateMsgVote
|
||||||
func SimulateMsgVote(k gov.Keeper, sk stake.Keeper) simulation.Operation {
|
func SimulateMsgVote(k gov.Keeper, sk stake.Keeper) simulation.Operation {
|
||||||
return func(t *testing.T, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string, event func(string)) (action string, fOp []simulation.FutureOperation, err sdk.Error) {
|
return func(tb testing.TB, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string, event func(string)) (action string, fOp []simulation.FutureOperation, err sdk.Error) {
|
||||||
key := simulation.RandomKey(r, keys)
|
key := simulation.RandomKey(r, keys)
|
||||||
addr := sdk.AccAddress(key.PubKey().Address())
|
addr := sdk.AccAddress(key.PubKey().Address())
|
||||||
proposalID, ok := randomProposalID(r, k, ctx)
|
proposalID, ok := randomProposalID(r, k, ctx)
|
||||||
|
@ -88,7 +96,9 @@ func SimulateMsgVote(k gov.Keeper, sk stake.Keeper) simulation.Operation {
|
||||||
}
|
}
|
||||||
option := randomVotingOption(r)
|
option := randomVotingOption(r)
|
||||||
msg := gov.NewMsgVote(addr, proposalID, option)
|
msg := gov.NewMsgVote(addr, proposalID, option)
|
||||||
require.Nil(t, msg.ValidateBasic(), "expected msg to pass ValidateBasic: %s", msg.GetSignBytes())
|
if msg.ValidateBasic() != nil {
|
||||||
|
tb.Fatalf("expected msg to pass ValidateBasic: %s, log %s", msg.GetSignBytes(), log)
|
||||||
|
}
|
||||||
ctx, write := ctx.CacheContext()
|
ctx, write := ctx.CacheContext()
|
||||||
result := gov.NewHandler(k)(ctx, msg)
|
result := gov.NewHandler(k)(ctx, msg)
|
||||||
if result.IsOK() {
|
if result.IsOK() {
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
|
"os"
|
||||||
"sort"
|
"sort"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
@ -28,6 +29,26 @@ func Simulate(
|
||||||
SimulateFromSeed(t, app, appStateFn, time, ops, setups, invariants, numBlocks, blockSize, commit)
|
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)})
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func randTimestamp(r *rand.Rand) time.Time {
|
||||||
|
unixTime := r.Int63n(int64(math.Pow(2, 40)))
|
||||||
|
return time.Unix(unixTime, 0)
|
||||||
|
}
|
||||||
|
|
||||||
// SimulateFromSeed tests an application by running the provided
|
// SimulateFromSeed tests an application by running the provided
|
||||||
// operations, testing the provided invariants, but using the provided seed.
|
// operations, testing the provided invariants, but using the provided seed.
|
||||||
func SimulateFromSeed(
|
func SimulateFromSeed(
|
||||||
|
@ -36,11 +57,7 @@ func SimulateFromSeed(
|
||||||
) {
|
) {
|
||||||
log := fmt.Sprintf("Starting SimulateFromSeed with randomness created with seed %d", int(seed))
|
log := fmt.Sprintf("Starting SimulateFromSeed with randomness created with seed %d", int(seed))
|
||||||
r := rand.New(rand.NewSource(seed))
|
r := rand.New(rand.NewSource(seed))
|
||||||
|
timestamp := randTimestamp(r)
|
||||||
unixTime := r.Int63n(int64(math.Pow(2, 40)))
|
|
||||||
|
|
||||||
// Set the timestamp for simulation
|
|
||||||
timestamp := time.Unix(unixTime, 0)
|
|
||||||
log = fmt.Sprintf("%s\nStarting the simulation from time %v, unixtime %v", log, timestamp.UTC().Format(time.UnixDate), timestamp.Unix())
|
log = fmt.Sprintf("%s\nStarting the simulation from time %v, unixtime %v", log, timestamp.UTC().Format(time.UnixDate), timestamp.Unix())
|
||||||
fmt.Printf("%s\n", log)
|
fmt.Printf("%s\n", log)
|
||||||
timeDiff := maxTimePerBlock - minTimePerBlock
|
timeDiff := maxTimePerBlock - minTimePerBlock
|
||||||
|
@ -54,30 +71,18 @@ func SimulateFromSeed(
|
||||||
events[what]++
|
events[what]++
|
||||||
}
|
}
|
||||||
|
|
||||||
res := app.InitChain(abci.RequestInitChain{AppStateBytes: appStateFn(r, keys, accs)})
|
validators := initChain(r, keys, accs, setups, app, appStateFn)
|
||||||
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)
|
|
||||||
}
|
|
||||||
|
|
||||||
header := abci.Header{Height: 0, Time: timestamp}
|
header := abci.Header{Height: 0, Time: timestamp}
|
||||||
opCount := 0
|
opCount := 0
|
||||||
|
|
||||||
request := abci.RequestBeginBlock{Header: header}
|
request := abci.RequestBeginBlock{Header: header}
|
||||||
|
|
||||||
var pastTimes []time.Time
|
var lastHeaderTime time.Time
|
||||||
// These are operations which have been queued by previous operations
|
// These are operations which have been queued by previous operations
|
||||||
operationQueue := make(map[int][]Operation)
|
operationQueue := make(map[int][]Operation)
|
||||||
|
|
||||||
for i := 0; i < numBlocks; i++ {
|
for i := 0; i < numBlocks; i++ {
|
||||||
|
|
||||||
// Log the header time for future lookup
|
|
||||||
pastTimes = append(pastTimes, header.Time)
|
|
||||||
|
|
||||||
// Run the BeginBlock handler
|
// Run the BeginBlock handler
|
||||||
app.BeginBlock(request)
|
app.BeginBlock(request)
|
||||||
|
|
||||||
|
@ -88,16 +93,8 @@ func SimulateFromSeed(
|
||||||
|
|
||||||
ctx := app.NewContext(false, header)
|
ctx := app.NewContext(false, header)
|
||||||
|
|
||||||
var thisBlockSize int
|
thisBlockSize := getBlockSize(r, blockSize)
|
||||||
load := r.Float64()
|
|
||||||
switch {
|
|
||||||
case load < 0.33:
|
|
||||||
thisBlockSize = 0
|
|
||||||
case load < 0.66:
|
|
||||||
thisBlockSize = r.Intn(blockSize * 2)
|
|
||||||
default:
|
|
||||||
thisBlockSize = r.Intn(blockSize * 4)
|
|
||||||
}
|
|
||||||
// Run queued operations. Ignores blocksize if blocksize is too small
|
// Run queued operations. Ignores blocksize if blocksize is too small
|
||||||
log, numQueuedOpsRan := runQueuedOperations(operationQueue, int(header.Height), t, r, app, ctx, keys, log, event)
|
log, numQueuedOpsRan := runQueuedOperations(operationQueue, int(header.Height), t, r, app, ctx, keys, log, event)
|
||||||
opCount += numQueuedOpsRan
|
opCount += numQueuedOpsRan
|
||||||
|
@ -119,6 +116,7 @@ func SimulateFromSeed(
|
||||||
|
|
||||||
res := app.EndBlock(abci.RequestEndBlock{})
|
res := app.EndBlock(abci.RequestEndBlock{})
|
||||||
header.Height++
|
header.Height++
|
||||||
|
lastHeaderTime = header.Time
|
||||||
header.Time = header.Time.Add(time.Duration(minTimePerBlock) * time.Second).Add(time.Duration(int64(r.Intn(int(timeDiff)))) * time.Second)
|
header.Time = header.Time.Add(time.Duration(minTimePerBlock) * time.Second).Add(time.Duration(int64(r.Intn(int(timeDiff)))) * time.Second)
|
||||||
|
|
||||||
log += "\nEndBlock"
|
log += "\nEndBlock"
|
||||||
|
@ -131,7 +129,7 @@ func SimulateFromSeed(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate a random RequestBeginBlock with the current validator set for the next block
|
// Generate a random RequestBeginBlock with the current validator set for the next block
|
||||||
request = RandomRequestBeginBlock(t, r, validators, livenessTransitionMatrix, evidenceFraction, pastTimes, event, header, log)
|
request = RandomRequestBeginBlock(r, validators, livenessTransitionMatrix, evidenceFraction, lastHeaderTime, event, header, log)
|
||||||
|
|
||||||
// Update the validator set
|
// Update the validator set
|
||||||
validators = updateValidators(t, r, validators, res.ValidatorUpdates, event)
|
validators = updateValidators(t, r, validators, res.ValidatorUpdates, event)
|
||||||
|
@ -141,6 +139,84 @@ func SimulateFromSeed(
|
||||||
DisplayEvents(events)
|
DisplayEvents(events)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getBlockSize(r *rand.Rand, blockSize int) int {
|
||||||
|
load := r.Float64()
|
||||||
|
switch {
|
||||||
|
case load < 0.33:
|
||||||
|
return 0
|
||||||
|
case load < 0.66:
|
||||||
|
return r.Intn(blockSize * 2)
|
||||||
|
default:
|
||||||
|
return r.Intn(blockSize * 4)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Simulate from seed, benchmarks
|
||||||
|
func BenchmarkSimulationFromSeed(b *testing.B, app *baseapp.BaseApp, appStateFn func(r *rand.Rand, keys []crypto.PrivKey, accs []sdk.AccAddress) json.RawMessage,
|
||||||
|
seed int64, ops []Operation, setups []RandSetup, numBlocks int, blockSize int, commit bool) {
|
||||||
|
r := rand.New(rand.NewSource(seed))
|
||||||
|
timestamp := randTimestamp(r)
|
||||||
|
timeDiff := maxTimePerBlock - minTimePerBlock
|
||||||
|
keys, accs := mock.GeneratePrivKeyAddressPairsFromRand(r, numKeys)
|
||||||
|
|
||||||
|
// Setup event stats
|
||||||
|
events := make(map[string]uint)
|
||||||
|
event := func(what string) {
|
||||||
|
events[what]++
|
||||||
|
}
|
||||||
|
|
||||||
|
validators := initChain(r, keys, accs, setups, app, appStateFn)
|
||||||
|
|
||||||
|
header := abci.Header{Height: 0, Time: timestamp}
|
||||||
|
opCount := 0
|
||||||
|
|
||||||
|
request := abci.RequestBeginBlock{Header: header}
|
||||||
|
|
||||||
|
var lastHeaderTime time.Time
|
||||||
|
// These are operations which have been queued by previous operations
|
||||||
|
operationQueue := make(map[int][]Operation)
|
||||||
|
b.ResetTimer()
|
||||||
|
|
||||||
|
for i := 0; i < numBlocks; i++ {
|
||||||
|
|
||||||
|
// Run the BeginBlock handler
|
||||||
|
app.BeginBlock(request)
|
||||||
|
|
||||||
|
ctx := app.NewContext(false, header)
|
||||||
|
|
||||||
|
thisBlockSize := getBlockSize(r, blockSize)
|
||||||
|
|
||||||
|
// Run queued operations. Ignores blocksize if blocksize is too small
|
||||||
|
log, numQueuedOpsRan := runQueuedOperations(operationQueue, int(header.Height), b, r, app, ctx, keys, "", event)
|
||||||
|
opCount += numQueuedOpsRan
|
||||||
|
thisBlockSize -= numQueuedOpsRan
|
||||||
|
for j := 0; j < thisBlockSize; j++ {
|
||||||
|
_, futureOps, err := ops[r.Intn(len(ops))](b, r, app, ctx, keys, "", event)
|
||||||
|
queueOperations(operationQueue, futureOps)
|
||||||
|
if err != nil {
|
||||||
|
b.Fatalf("error on operation %d, %v", opCount, err)
|
||||||
|
}
|
||||||
|
opCount++
|
||||||
|
}
|
||||||
|
|
||||||
|
res := app.EndBlock(abci.RequestEndBlock{})
|
||||||
|
header.Height++
|
||||||
|
lastHeaderTime = header.Time
|
||||||
|
header.Time = header.Time.Add(time.Duration(minTimePerBlock) * time.Second).Add(time.Duration(int64(r.Intn(int(timeDiff)))) * time.Second)
|
||||||
|
if commit {
|
||||||
|
app.Commit()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate a random RequestBeginBlock with the current validator set for the next block
|
||||||
|
request = RandomRequestBeginBlock(r, validators, livenessTransitionMatrix, evidenceFraction, lastHeaderTime, event, header, log)
|
||||||
|
|
||||||
|
// Update the validator set
|
||||||
|
validators = updateValidators(b, r, validators, res.ValidatorUpdates, event)
|
||||||
|
}
|
||||||
|
DisplayEvents(events)
|
||||||
|
fmt.Printf("Benchmark simulation ran %d operations\n", opCount)
|
||||||
|
}
|
||||||
|
|
||||||
// adds all future operations into the operation queue.
|
// adds all future operations into the operation queue.
|
||||||
func queueOperations(queuedOperations map[int][]Operation, futureOperations []FutureOperation) {
|
func queueOperations(queuedOperations map[int][]Operation, futureOperations []FutureOperation) {
|
||||||
if futureOperations == nil {
|
if futureOperations == nil {
|
||||||
|
@ -155,7 +231,7 @@ func queueOperations(queuedOperations map[int][]Operation, futureOperations []Fu
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func runQueuedOperations(queueOperations map[int][]Operation, height int, t *testing.T, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context,
|
func runQueuedOperations(queueOperations map[int][]Operation, height int, tb testing.TB, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context,
|
||||||
privKeys []crypto.PrivKey, log string, event func(string)) (updatedLog string, numOpsRan int) {
|
privKeys []crypto.PrivKey, log string, event func(string)) (updatedLog string, numOpsRan int) {
|
||||||
updatedLog = log
|
updatedLog = log
|
||||||
if queuedOps, ok := queueOperations[height]; ok {
|
if queuedOps, ok := queueOperations[height]; ok {
|
||||||
|
@ -164,9 +240,12 @@ func runQueuedOperations(queueOperations map[int][]Operation, height int, t *tes
|
||||||
// For now, queued operations cannot queue more operations.
|
// For now, queued operations cannot queue more operations.
|
||||||
// If a need arises for us to support queued messages to queue more messages, this can
|
// If a need arises for us to support queued messages to queue more messages, this can
|
||||||
// be changed.
|
// be changed.
|
||||||
logUpdate, _, err := queuedOps[i](t, r, app, ctx, privKeys, updatedLog, event)
|
logUpdate, _, err := queuedOps[i](tb, r, app, ctx, privKeys, updatedLog, event)
|
||||||
updatedLog += "\n" + logUpdate
|
updatedLog = fmt.Sprintf("%s\n%s", updatedLog, logUpdate)
|
||||||
require.Nil(t, err, updatedLog)
|
if err != nil {
|
||||||
|
fmt.Fprint(os.Stderr, updatedLog)
|
||||||
|
tb.FailNow()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
delete(queueOperations, height)
|
delete(queueOperations, height)
|
||||||
return updatedLog, numOps
|
return updatedLog, numOps
|
||||||
|
@ -186,8 +265,8 @@ func getKeys(validators map[string]mockValidator) []string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// RandomRequestBeginBlock generates a list of signing validators according to the provided list of validators, signing fraction, and evidence fraction
|
// RandomRequestBeginBlock generates a list of signing validators according to the provided list of validators, signing fraction, and evidence fraction
|
||||||
func RandomRequestBeginBlock(t *testing.T, r *rand.Rand, validators map[string]mockValidator, livenessTransitions TransitionMatrix, evidenceFraction float64,
|
func RandomRequestBeginBlock(r *rand.Rand, validators map[string]mockValidator, livenessTransitions TransitionMatrix, evidenceFraction float64,
|
||||||
pastTimes []time.Time, event func(string), header abci.Header, log string) abci.RequestBeginBlock {
|
lastHeaderTime time.Time, event func(string), header abci.Header, log string) abci.RequestBeginBlock {
|
||||||
if len(validators) == 0 {
|
if len(validators) == 0 {
|
||||||
return abci.RequestBeginBlock{Header: header}
|
return abci.RequestBeginBlock{Header: header}
|
||||||
}
|
}
|
||||||
|
@ -219,13 +298,14 @@ func RandomRequestBeginBlock(t *testing.T, r *rand.Rand, validators map[string]m
|
||||||
}
|
}
|
||||||
i++
|
i++
|
||||||
}
|
}
|
||||||
|
// TODO: Determine capacity before allocation
|
||||||
evidence := make([]abci.Evidence, 0)
|
evidence := make([]abci.Evidence, 0)
|
||||||
for r.Float64() < evidenceFraction {
|
for r.Float64() < evidenceFraction {
|
||||||
height := header.Height
|
height := header.Height
|
||||||
time := header.Time
|
time := header.Time
|
||||||
if r.Float64() < pastEvidenceFraction {
|
if r.Float64() < pastEvidenceFraction {
|
||||||
height = int64(r.Intn(int(header.Height)))
|
height = int64(r.Intn(int(header.Height)))
|
||||||
time = pastTimes[height]
|
time = lastHeaderTime
|
||||||
}
|
}
|
||||||
validator := signingValidators[r.Intn(len(signingValidators))].Validator
|
validator := signingValidators[r.Intn(len(signingValidators))].Validator
|
||||||
var currentTotalVotingPower int64
|
var currentTotalVotingPower int64
|
||||||
|
@ -258,11 +338,19 @@ func AssertAllInvariants(t *testing.T, app *baseapp.BaseApp, tests []Invariant,
|
||||||
}
|
}
|
||||||
|
|
||||||
// updateValidators mimicks Tendermint's update logic
|
// updateValidators mimicks Tendermint's update logic
|
||||||
func updateValidators(t *testing.T, r *rand.Rand, current map[string]mockValidator, updates []abci.Validator, event func(string)) map[string]mockValidator {
|
func updateValidators(tb testing.TB, r *rand.Rand, current map[string]mockValidator, updates []abci.Validator, event func(string)) map[string]mockValidator {
|
||||||
for _, update := range updates {
|
for _, update := range updates {
|
||||||
switch {
|
switch {
|
||||||
case update.Power == 0:
|
case update.Power == 0:
|
||||||
require.NotNil(t, current[string(update.PubKey.Data)], "tried to delete a nonexistent validator")
|
// // TEMPORARY DEBUG CODE TO PROVE THAT THE OLD METHOD WAS BROKEN
|
||||||
|
// // (i.e. didn't catch in the event of problem)
|
||||||
|
// if val, ok := tb.(*testing.T); ok {
|
||||||
|
// require.NotNil(val, current[string(update.PubKey.Data)])
|
||||||
|
// }
|
||||||
|
// // CORRECT CHECK
|
||||||
|
// if _, ok := current[string(update.PubKey.Data)]; !ok {
|
||||||
|
// tb.Fatalf("tried to delete a nonexistent validator")
|
||||||
|
// }
|
||||||
event("endblock/validatorupdates/kicked")
|
event("endblock/validatorupdates/kicked")
|
||||||
delete(current, string(update.PubKey.Data))
|
delete(current, string(update.PubKey.Data))
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -23,7 +23,7 @@ type (
|
||||||
// Operations can optionally provide a list of "FutureOperations" to run later
|
// Operations can optionally provide a list of "FutureOperations" to run later
|
||||||
// These will be ran at the beginning of the corresponding block.
|
// These will be ran at the beginning of the corresponding block.
|
||||||
Operation func(
|
Operation func(
|
||||||
t *testing.T, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context,
|
tb testing.TB, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context,
|
||||||
privKeys []crypto.PrivKey, log string, event func(string),
|
privKeys []crypto.PrivKey, log string, event func(string),
|
||||||
) (action string, futureOperations []FutureOperation, err sdk.Error)
|
) (action string, futureOperations []FutureOperation, err sdk.Error)
|
||||||
|
|
||||||
|
|
|
@ -5,8 +5,6 @@ import (
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
|
|
||||||
"github.com/tendermint/tendermint/crypto"
|
"github.com/tendermint/tendermint/crypto"
|
||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/baseapp"
|
"github.com/cosmos/cosmos-sdk/baseapp"
|
||||||
|
@ -17,11 +15,13 @@ import (
|
||||||
|
|
||||||
// SimulateMsgUnjail
|
// SimulateMsgUnjail
|
||||||
func SimulateMsgUnjail(k slashing.Keeper) simulation.Operation {
|
func SimulateMsgUnjail(k slashing.Keeper) simulation.Operation {
|
||||||
return func(t *testing.T, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string, event func(string)) (action string, fOp []simulation.FutureOperation, err sdk.Error) {
|
return func(tb testing.TB, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string, event func(string)) (action string, fOp []simulation.FutureOperation, err sdk.Error) {
|
||||||
key := simulation.RandomKey(r, keys)
|
key := simulation.RandomKey(r, keys)
|
||||||
address := sdk.AccAddress(key.PubKey().Address())
|
address := sdk.AccAddress(key.PubKey().Address())
|
||||||
msg := slashing.NewMsgUnjail(address)
|
msg := slashing.NewMsgUnjail(address)
|
||||||
require.Nil(t, msg.ValidateBasic(), "expected msg to pass ValidateBasic: %s", msg.GetSignBytes())
|
if msg.ValidateBasic() != nil {
|
||||||
|
tb.Fatalf("expected msg to pass ValidateBasic: %s, log %s", msg.GetSignBytes(), log)
|
||||||
|
}
|
||||||
ctx, write := ctx.CacheContext()
|
ctx, write := ctx.CacheContext()
|
||||||
result := slashing.NewHandler(k)(ctx, msg)
|
result := slashing.NewHandler(k)(ctx, msg)
|
||||||
if result.IsOK() {
|
if result.IsOK() {
|
||||||
|
|
|
@ -5,8 +5,6 @@ import (
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/baseapp"
|
"github.com/cosmos/cosmos-sdk/baseapp"
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
"github.com/cosmos/cosmos-sdk/x/auth"
|
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||||
|
@ -19,7 +17,7 @@ import (
|
||||||
|
|
||||||
// SimulateMsgCreateValidator
|
// SimulateMsgCreateValidator
|
||||||
func SimulateMsgCreateValidator(m auth.AccountMapper, k stake.Keeper) simulation.Operation {
|
func SimulateMsgCreateValidator(m auth.AccountMapper, k stake.Keeper) simulation.Operation {
|
||||||
return func(t *testing.T, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string, event func(string)) (action string, fOp []simulation.FutureOperation, err sdk.Error) {
|
return func(tb testing.TB, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string, event func(string)) (action string, fOp []simulation.FutureOperation, err sdk.Error) {
|
||||||
denom := k.GetParams(ctx).BondDenom
|
denom := k.GetParams(ctx).BondDenom
|
||||||
description := stake.Description{
|
description := stake.Description{
|
||||||
Moniker: simulation.RandStringOfLength(r, 10),
|
Moniker: simulation.RandStringOfLength(r, 10),
|
||||||
|
@ -41,7 +39,9 @@ func SimulateMsgCreateValidator(m auth.AccountMapper, k stake.Keeper) simulation
|
||||||
PubKey: pubkey,
|
PubKey: pubkey,
|
||||||
Delegation: sdk.NewCoin(denom, amount),
|
Delegation: sdk.NewCoin(denom, amount),
|
||||||
}
|
}
|
||||||
require.Nil(t, msg.ValidateBasic(), "expected msg to pass ValidateBasic: %s", msg.GetSignBytes())
|
if msg.ValidateBasic() != nil {
|
||||||
|
tb.Fatalf("expected msg to pass ValidateBasic: %s, log %s", msg.GetSignBytes(), log)
|
||||||
|
}
|
||||||
ctx, write := ctx.CacheContext()
|
ctx, write := ctx.CacheContext()
|
||||||
result := stake.NewHandler(k)(ctx, msg)
|
result := stake.NewHandler(k)(ctx, msg)
|
||||||
if result.IsOK() {
|
if result.IsOK() {
|
||||||
|
@ -56,7 +56,7 @@ func SimulateMsgCreateValidator(m auth.AccountMapper, k stake.Keeper) simulation
|
||||||
|
|
||||||
// SimulateMsgEditValidator
|
// SimulateMsgEditValidator
|
||||||
func SimulateMsgEditValidator(k stake.Keeper) simulation.Operation {
|
func SimulateMsgEditValidator(k stake.Keeper) simulation.Operation {
|
||||||
return func(t *testing.T, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string, event func(string)) (action string, fOp []simulation.FutureOperation, err sdk.Error) {
|
return func(tb testing.TB, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string, event func(string)) (action string, fOp []simulation.FutureOperation, err sdk.Error) {
|
||||||
description := stake.Description{
|
description := stake.Description{
|
||||||
Moniker: simulation.RandStringOfLength(r, 10),
|
Moniker: simulation.RandStringOfLength(r, 10),
|
||||||
Identity: simulation.RandStringOfLength(r, 10),
|
Identity: simulation.RandStringOfLength(r, 10),
|
||||||
|
@ -70,7 +70,9 @@ func SimulateMsgEditValidator(k stake.Keeper) simulation.Operation {
|
||||||
Description: description,
|
Description: description,
|
||||||
ValidatorAddr: address,
|
ValidatorAddr: address,
|
||||||
}
|
}
|
||||||
require.Nil(t, msg.ValidateBasic(), "expected msg to pass ValidateBasic: %s", msg.GetSignBytes())
|
if msg.ValidateBasic() != nil {
|
||||||
|
tb.Fatalf("expected msg to pass ValidateBasic: %s, log %s", msg.GetSignBytes(), log)
|
||||||
|
}
|
||||||
ctx, write := ctx.CacheContext()
|
ctx, write := ctx.CacheContext()
|
||||||
result := stake.NewHandler(k)(ctx, msg)
|
result := stake.NewHandler(k)(ctx, msg)
|
||||||
if result.IsOK() {
|
if result.IsOK() {
|
||||||
|
@ -84,7 +86,7 @@ func SimulateMsgEditValidator(k stake.Keeper) simulation.Operation {
|
||||||
|
|
||||||
// SimulateMsgDelegate
|
// SimulateMsgDelegate
|
||||||
func SimulateMsgDelegate(m auth.AccountMapper, k stake.Keeper) simulation.Operation {
|
func SimulateMsgDelegate(m auth.AccountMapper, k stake.Keeper) simulation.Operation {
|
||||||
return func(t *testing.T, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string, event func(string)) (action string, fOp []simulation.FutureOperation, err sdk.Error) {
|
return func(tb testing.TB, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string, event func(string)) (action string, fOp []simulation.FutureOperation, err sdk.Error) {
|
||||||
denom := k.GetParams(ctx).BondDenom
|
denom := k.GetParams(ctx).BondDenom
|
||||||
validatorKey := simulation.RandomKey(r, keys)
|
validatorKey := simulation.RandomKey(r, keys)
|
||||||
validatorAddress := sdk.AccAddress(validatorKey.PubKey().Address())
|
validatorAddress := sdk.AccAddress(validatorKey.PubKey().Address())
|
||||||
|
@ -102,7 +104,9 @@ func SimulateMsgDelegate(m auth.AccountMapper, k stake.Keeper) simulation.Operat
|
||||||
ValidatorAddr: validatorAddress,
|
ValidatorAddr: validatorAddress,
|
||||||
Delegation: sdk.NewCoin(denom, amount),
|
Delegation: sdk.NewCoin(denom, amount),
|
||||||
}
|
}
|
||||||
require.Nil(t, msg.ValidateBasic(), "expected msg to pass ValidateBasic: %s", msg.GetSignBytes())
|
if msg.ValidateBasic() != nil {
|
||||||
|
tb.Fatalf("expected msg to pass ValidateBasic: %s, log %s", msg.GetSignBytes(), log)
|
||||||
|
}
|
||||||
ctx, write := ctx.CacheContext()
|
ctx, write := ctx.CacheContext()
|
||||||
result := stake.NewHandler(k)(ctx, msg)
|
result := stake.NewHandler(k)(ctx, msg)
|
||||||
if result.IsOK() {
|
if result.IsOK() {
|
||||||
|
@ -116,7 +120,7 @@ func SimulateMsgDelegate(m auth.AccountMapper, k stake.Keeper) simulation.Operat
|
||||||
|
|
||||||
// SimulateMsgBeginUnbonding
|
// SimulateMsgBeginUnbonding
|
||||||
func SimulateMsgBeginUnbonding(m auth.AccountMapper, k stake.Keeper) simulation.Operation {
|
func SimulateMsgBeginUnbonding(m auth.AccountMapper, k stake.Keeper) simulation.Operation {
|
||||||
return func(t *testing.T, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string, event func(string)) (action string, fOp []simulation.FutureOperation, err sdk.Error) {
|
return func(tb testing.TB, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string, event func(string)) (action string, fOp []simulation.FutureOperation, err sdk.Error) {
|
||||||
denom := k.GetParams(ctx).BondDenom
|
denom := k.GetParams(ctx).BondDenom
|
||||||
validatorKey := simulation.RandomKey(r, keys)
|
validatorKey := simulation.RandomKey(r, keys)
|
||||||
validatorAddress := sdk.AccAddress(validatorKey.PubKey().Address())
|
validatorAddress := sdk.AccAddress(validatorKey.PubKey().Address())
|
||||||
|
@ -134,7 +138,9 @@ func SimulateMsgBeginUnbonding(m auth.AccountMapper, k stake.Keeper) simulation.
|
||||||
ValidatorAddr: validatorAddress,
|
ValidatorAddr: validatorAddress,
|
||||||
SharesAmount: sdk.NewDecFromInt(amount),
|
SharesAmount: sdk.NewDecFromInt(amount),
|
||||||
}
|
}
|
||||||
require.Nil(t, msg.ValidateBasic(), "expected msg to pass ValidateBasic: %s", msg.GetSignBytes())
|
if msg.ValidateBasic() != nil {
|
||||||
|
tb.Fatalf("expected msg to pass ValidateBasic: %s, log %s", msg.GetSignBytes(), log)
|
||||||
|
}
|
||||||
ctx, write := ctx.CacheContext()
|
ctx, write := ctx.CacheContext()
|
||||||
result := stake.NewHandler(k)(ctx, msg)
|
result := stake.NewHandler(k)(ctx, msg)
|
||||||
if result.IsOK() {
|
if result.IsOK() {
|
||||||
|
@ -148,7 +154,7 @@ func SimulateMsgBeginUnbonding(m auth.AccountMapper, k stake.Keeper) simulation.
|
||||||
|
|
||||||
// SimulateMsgCompleteUnbonding
|
// SimulateMsgCompleteUnbonding
|
||||||
func SimulateMsgCompleteUnbonding(k stake.Keeper) simulation.Operation {
|
func SimulateMsgCompleteUnbonding(k stake.Keeper) simulation.Operation {
|
||||||
return func(t *testing.T, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string, event func(string)) (action string, fOp []simulation.FutureOperation, err sdk.Error) {
|
return func(tb testing.TB, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string, event func(string)) (action string, fOp []simulation.FutureOperation, err sdk.Error) {
|
||||||
validatorKey := simulation.RandomKey(r, keys)
|
validatorKey := simulation.RandomKey(r, keys)
|
||||||
validatorAddress := sdk.AccAddress(validatorKey.PubKey().Address())
|
validatorAddress := sdk.AccAddress(validatorKey.PubKey().Address())
|
||||||
delegatorKey := simulation.RandomKey(r, keys)
|
delegatorKey := simulation.RandomKey(r, keys)
|
||||||
|
@ -157,7 +163,9 @@ func SimulateMsgCompleteUnbonding(k stake.Keeper) simulation.Operation {
|
||||||
DelegatorAddr: delegatorAddress,
|
DelegatorAddr: delegatorAddress,
|
||||||
ValidatorAddr: validatorAddress,
|
ValidatorAddr: validatorAddress,
|
||||||
}
|
}
|
||||||
require.Nil(t, msg.ValidateBasic(), "expected msg to pass ValidateBasic: %s", msg.GetSignBytes())
|
if msg.ValidateBasic() != nil {
|
||||||
|
tb.Fatalf("expected msg to pass ValidateBasic: %s, log %s", msg.GetSignBytes(), log)
|
||||||
|
}
|
||||||
ctx, write := ctx.CacheContext()
|
ctx, write := ctx.CacheContext()
|
||||||
result := stake.NewHandler(k)(ctx, msg)
|
result := stake.NewHandler(k)(ctx, msg)
|
||||||
if result.IsOK() {
|
if result.IsOK() {
|
||||||
|
@ -171,7 +179,7 @@ func SimulateMsgCompleteUnbonding(k stake.Keeper) simulation.Operation {
|
||||||
|
|
||||||
// SimulateMsgBeginRedelegate
|
// SimulateMsgBeginRedelegate
|
||||||
func SimulateMsgBeginRedelegate(m auth.AccountMapper, k stake.Keeper) simulation.Operation {
|
func SimulateMsgBeginRedelegate(m auth.AccountMapper, k stake.Keeper) simulation.Operation {
|
||||||
return func(t *testing.T, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string, event func(string)) (action string, fOp []simulation.FutureOperation, err sdk.Error) {
|
return func(tb testing.TB, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string, event func(string)) (action string, fOp []simulation.FutureOperation, err sdk.Error) {
|
||||||
denom := k.GetParams(ctx).BondDenom
|
denom := k.GetParams(ctx).BondDenom
|
||||||
sourceValidatorKey := simulation.RandomKey(r, keys)
|
sourceValidatorKey := simulation.RandomKey(r, keys)
|
||||||
sourceValidatorAddress := sdk.AccAddress(sourceValidatorKey.PubKey().Address())
|
sourceValidatorAddress := sdk.AccAddress(sourceValidatorKey.PubKey().Address())
|
||||||
|
@ -193,7 +201,9 @@ func SimulateMsgBeginRedelegate(m auth.AccountMapper, k stake.Keeper) simulation
|
||||||
ValidatorDstAddr: destValidatorAddress,
|
ValidatorDstAddr: destValidatorAddress,
|
||||||
SharesAmount: sdk.NewDecFromInt(amount),
|
SharesAmount: sdk.NewDecFromInt(amount),
|
||||||
}
|
}
|
||||||
require.Nil(t, msg.ValidateBasic(), "expected msg to pass ValidateBasic: %s", msg.GetSignBytes())
|
if msg.ValidateBasic() != nil {
|
||||||
|
tb.Fatalf("expected msg to pass ValidateBasic: %s, log %s", msg.GetSignBytes(), log)
|
||||||
|
}
|
||||||
ctx, write := ctx.CacheContext()
|
ctx, write := ctx.CacheContext()
|
||||||
result := stake.NewHandler(k)(ctx, msg)
|
result := stake.NewHandler(k)(ctx, msg)
|
||||||
if result.IsOK() {
|
if result.IsOK() {
|
||||||
|
@ -207,7 +217,7 @@ func SimulateMsgBeginRedelegate(m auth.AccountMapper, k stake.Keeper) simulation
|
||||||
|
|
||||||
// SimulateMsgCompleteRedelegate
|
// SimulateMsgCompleteRedelegate
|
||||||
func SimulateMsgCompleteRedelegate(k stake.Keeper) simulation.Operation {
|
func SimulateMsgCompleteRedelegate(k stake.Keeper) simulation.Operation {
|
||||||
return func(t *testing.T, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string, event func(string)) (action string, fOp []simulation.FutureOperation, err sdk.Error) {
|
return func(tb testing.TB, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string, event func(string)) (action string, fOp []simulation.FutureOperation, err sdk.Error) {
|
||||||
validatorSrcKey := simulation.RandomKey(r, keys)
|
validatorSrcKey := simulation.RandomKey(r, keys)
|
||||||
validatorSrcAddress := sdk.AccAddress(validatorSrcKey.PubKey().Address())
|
validatorSrcAddress := sdk.AccAddress(validatorSrcKey.PubKey().Address())
|
||||||
validatorDstKey := simulation.RandomKey(r, keys)
|
validatorDstKey := simulation.RandomKey(r, keys)
|
||||||
|
@ -219,7 +229,9 @@ func SimulateMsgCompleteRedelegate(k stake.Keeper) simulation.Operation {
|
||||||
ValidatorSrcAddr: validatorSrcAddress,
|
ValidatorSrcAddr: validatorSrcAddress,
|
||||||
ValidatorDstAddr: validatorDstAddress,
|
ValidatorDstAddr: validatorDstAddress,
|
||||||
}
|
}
|
||||||
require.Nil(t, msg.ValidateBasic(), "expected msg to pass ValidateBasic: %s", msg.GetSignBytes())
|
if msg.ValidateBasic() != nil {
|
||||||
|
tb.Fatalf("expected msg to pass ValidateBasic: %s, log %s", msg.GetSignBytes(), log)
|
||||||
|
}
|
||||||
ctx, write := ctx.CacheContext()
|
ctx, write := ctx.CacheContext()
|
||||||
result := stake.NewHandler(k)(ctx, msg)
|
result := stake.NewHandler(k)(ctx, msg)
|
||||||
if result.IsOK() {
|
if result.IsOK() {
|
||||||
|
|
Loading…
Reference in New Issue