simulation: Make validator choice use validator set

This also had to change the default seed, since with the previous one it
actually got into a state where there were no validators left bonded, lol.

This also changes Unbond msgs from failing with almost 100% probability to now
only failing with 33% probability.
Thus more of the state machine is getting tested!
This commit is contained in:
ValarDragon 2018-11-01 11:58:25 -07:00
parent 9cf53f25f7
commit 3cffe29da7
4 changed files with 44 additions and 20 deletions

View File

@ -169,7 +169,7 @@ test_sim_gaia_nondeterminism:
test_sim_gaia_fast:
@echo "Running quick Gaia simulation. This may take several minutes..."
@go test ./cmd/gaia/app -run TestFullGaiaSimulation -SimulationEnabled=true -SimulationNumBlocks=500 -SimulationBlockSize=200 -SimulationCommit=true -SimulationSeed=9 -v -timeout 24h
@go test ./cmd/gaia/app -run TestFullGaiaSimulation -SimulationEnabled=true -SimulationNumBlocks=500 -SimulationBlockSize=200 -SimulationCommit=true -SimulationSeed=10 -v -timeout 24h
test_sim_gaia_multi_seed:
@echo "Running multi-seed Gaia simulation. This may take awhile!"

View File

@ -2,6 +2,7 @@ package simulation
import (
"fmt"
"math/big"
"math/rand"
"os"
"sort"
@ -71,6 +72,12 @@ func RandomAmount(r *rand.Rand, max sdk.Int) sdk.Int {
return sdk.NewInt(int64(r.Intn(int(max.Int64()))))
}
// RandomDecAmount generates a random decimal amount
func RandomDecAmount(r *rand.Rand, max sdk.Dec) sdk.Dec {
randInt := big.NewInt(0).Rand(r, max.Int)
return sdk.NewDecFromBigIntWithPrec(randInt, sdk.Precision)
}
// RandomAccounts generates n random accounts
func RandomAccounts(r *rand.Rand, n int) []Account {
accs := make([]Account, n)

View File

@ -3,6 +3,7 @@ package keeper
import (
"bytes"
"encoding/hex"
"math/rand"
"strconv"
"testing"
@ -215,3 +216,17 @@ func validatorByPowerIndexExists(k Keeper, ctx sdk.Context, power []byte) bool {
store := ctx.KVStore(k.storeKey)
return store.Has(power)
}
// RandomValidator returns a random validator given access to the keeper and ctx
func RandomValidator(r *rand.Rand, keeper Keeper, ctx sdk.Context) types.Validator {
vals := keeper.GetAllValidators(ctx)
i := r.Intn(len(vals))
return vals[i]
}
// RandomBondedValidator returns a random bonded validator given access to the keeper and ctx
func RandomBondedValidator(r *rand.Rand, keeper Keeper, ctx sdk.Context) types.Validator {
vals := keeper.GetBondedValidatorsByPower(ctx)
i := r.Intn(len(vals))
return vals[i]
}

View File

@ -10,6 +10,7 @@ import (
"github.com/cosmos/cosmos-sdk/x/mock"
"github.com/cosmos/cosmos-sdk/x/mock/simulation"
"github.com/cosmos/cosmos-sdk/x/stake"
"github.com/cosmos/cosmos-sdk/x/stake/keeper"
abci "github.com/tendermint/tendermint/abci/types"
)
@ -87,8 +88,8 @@ func SimulateMsgEditValidator(k stake.Keeper) simulation.Operation {
maxCommission := sdk.NewInt(10)
newCommissionRate := sdk.NewDecWithPrec(simulation.RandomAmount(r, maxCommission).Int64(), 1)
acc := simulation.RandomAcc(r, accs)
address := sdk.ValAddress(acc.Address)
val := keeper.RandomValidator(r, k, ctx)
address := val.GetOperator()
msg := stake.MsgEditValidator{
Description: description,
ValidatorAddr: address,
@ -118,8 +119,8 @@ func SimulateMsgDelegate(m auth.AccountKeeper, k stake.Keeper) simulation.Operat
action string, fOp []simulation.FutureOperation, err error) {
denom := k.GetParams(ctx).BondDenom
validatorAcc := simulation.RandomAcc(r, accs)
validatorAddress := sdk.ValAddress(validatorAcc.Address)
val := keeper.RandomValidator(r, k, ctx)
validatorAddress := val.GetOperator()
delegatorAcc := simulation.RandomAcc(r, accs)
delegatorAddress := delegatorAcc.Address
amount := m.GetAccount(ctx, delegatorAddress).GetCoins().AmountOf(denom)
@ -155,25 +156,26 @@ func SimulateMsgBeginUnbonding(m auth.AccountKeeper, k stake.Keeper) simulation.
accs []simulation.Account, event func(string)) (
action string, fOp []simulation.FutureOperation, err error) {
denom := k.GetParams(ctx).BondDenom
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)
delegations := k.GetAllDelegatorDelegations(ctx, delegatorAddress)
if len(delegations) == 0 {
return "no-operation", nil, nil
}
if amount.Equal(sdk.ZeroInt()) {
delegation := delegations[r.Intn(len(delegations))]
numShares := simulation.RandomDecAmount(r, delegation.Shares)
if numShares.Equal(sdk.ZeroDec()) {
return "no-operation", nil, nil
}
msg := stake.MsgBeginUnbonding{
DelegatorAddr: delegatorAddress,
ValidatorAddr: validatorAddress,
SharesAmount: sdk.NewDecFromInt(amount),
ValidatorAddr: delegation.ValidatorAddr,
SharesAmount: numShares,
}
if msg.ValidateBasic() != nil {
return "", nil, fmt.Errorf("expected msg to pass ValidateBasic: %s", msg.GetSignBytes())
return "", nil, fmt.Errorf("expected msg to pass ValidateBasic: %s, got error %v",
msg.GetSignBytes(), msg.ValidateBasic())
}
ctx, write := ctx.CacheContext()
result := handler(ctx, msg)
@ -194,10 +196,10 @@ func SimulateMsgBeginRedelegate(m auth.AccountKeeper, k stake.Keeper) simulation
action string, fOp []simulation.FutureOperation, err error) {
denom := k.GetParams(ctx).BondDenom
sourceValidatorAcc := simulation.RandomAcc(r, accs)
sourceValidatorAddress := sdk.ValAddress(sourceValidatorAcc.Address)
destValidatorAcc := simulation.RandomAcc(r, accs)
destValidatorAddress := sdk.ValAddress(destValidatorAcc.Address)
srcVal := keeper.RandomValidator(r, k, ctx)
srcValidatorAddress := srcVal.GetOperator()
destVal := keeper.RandomValidator(r, k, ctx)
destValidatorAddress := destVal.GetOperator()
delegatorAcc := simulation.RandomAcc(r, accs)
delegatorAddress := delegatorAcc.Address
// TODO
@ -210,7 +212,7 @@ func SimulateMsgBeginRedelegate(m auth.AccountKeeper, k stake.Keeper) simulation
}
msg := stake.MsgBeginRedelegate{
DelegatorAddr: delegatorAddress,
ValidatorSrcAddr: sourceValidatorAddress,
ValidatorSrcAddr: srcValidatorAddress,
ValidatorDstAddr: destValidatorAddress,
SharesAmount: sdk.NewDecFromInt(amount),
}