fix hardcoded auth sims (#7135)

* fix hardcoded auth sims

* changelog

Co-authored-by: Alexander Bezobchuk <alexanderbez@users.noreply.github.com>
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
This commit is contained in:
Federico Kunze 2020-08-24 12:55:42 +02:00 committed by GitHub
parent beafb58656
commit 3e148a9ce7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 124 additions and 71 deletions

View File

@ -186,6 +186,7 @@ be used to retrieve the actual proposal `Content`. Also the `NewMsgSubmitProposa
### Bug Fixes
* (simulation) [\#7129](https://github.com/cosmos/cosmos-sdk/issues/7129) Fix support for custom `Account` and key types on auth's simulation.
* (types) [\#7084](https://github.com/cosmos/cosmos-sdk/pull/7084) Fix panic when calling `BigInt()` on an uninitialized `Int`.
* (x/bank) [\#6536](https://github.com/cosmos/cosmos-sdk/pull/6536) Fix bug in `WriteGeneratedTxResponse` function used by multiple
REST endpoints. Now it writes a Tx in StdTx format.

View File

@ -25,6 +25,7 @@ import (
"github.com/cosmos/cosmos-sdk/x/auth/ante"
authrest "github.com/cosmos/cosmos-sdk/x/auth/client/rest"
authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
authsims "github.com/cosmos/cosmos-sdk/x/auth/simulation"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
"github.com/cosmos/cosmos-sdk/x/bank"
bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper"
@ -291,7 +292,7 @@ func NewSimApp(
app.AccountKeeper, app.StakingKeeper, app.BaseApp.DeliverTx,
encodingConfig.TxConfig,
),
auth.NewAppModule(appCodec, app.AccountKeeper),
auth.NewAppModule(appCodec, app.AccountKeeper, authsims.RandomGenesisAccounts),
bank.NewAppModule(appCodec, app.BankKeeper, app.AccountKeeper),
capability.NewAppModule(appCodec, *app.CapabilityKeeper),
crisis.NewAppModule(&app.CrisisKeeper),
@ -317,7 +318,7 @@ func NewSimApp(
)
app.mm.SetOrderEndBlockers(crisistypes.ModuleName, govtypes.ModuleName, stakingtypes.ModuleName)
// NOTE: The genutils moodule must occur after staking so that pools are
// NOTE: The genutils module must occur after staking so that pools are
// properly initialized with tokens from genesis accounts.
// NOTE: Capability module must occur first so that it can initialize any capabilities
// so that other modules that want to create or claim capabilities afterwards in InitChain
@ -340,7 +341,7 @@ func NewSimApp(
// NOTE: this is not required apps that don't use the simulator for fuzz testing
// transactions
app.sm = module.NewSimulationManager(
auth.NewAppModule(appCodec, app.AccountKeeper),
auth.NewAppModule(appCodec, app.AccountKeeper, authsims.RandomGenesisAccounts),
bank.NewAppModule(appCodec, app.BankKeeper, app.AccountKeeper),
capability.NewAppModule(appCodec, *app.CapabilityKeeper),
gov.NewAppModule(appCodec, app.GovKeeper, app.AccountKeeper, app.BankKeeper),
@ -446,7 +447,7 @@ func (app *SimApp) BlockedAddrs() map[string]bool {
return blockedAddrs
}
// Codec returns SimApp's codec.
// LegacyAmino returns SimApp's amino codec.
//
// NOTE: This is solely to be used for testing purposes as it may be desirable
// for modules to register their own custom testing types.

View File

@ -7,6 +7,7 @@ import (
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
"github.com/cosmos/cosmos-sdk/x/simulation"
)
@ -30,9 +31,14 @@ func BenchmarkFullAppSimulation(b *testing.B) {
// run randomized simulation
_, simParams, simErr := simulation.SimulateFromSeed(
b, os.Stdout, app.BaseApp, AppStateFn(app.AppCodec(), app.SimulationManager()),
b,
os.Stdout,
app.BaseApp,
AppStateFn(app.AppCodec(), app.SimulationManager()),
simtypes.RandomAccounts, // Replace with own random account function if using keys other than secp256k1
SimulationOperations(app, app.AppCodec(), config),
app.ModuleAccountAddrs(), config,
app.ModuleAccountAddrs(),
config,
)
// export state and simParams before the simulation error is checked
@ -69,9 +75,14 @@ func BenchmarkInvariants(b *testing.B) {
// run randomized simulation
_, simParams, simErr := simulation.SimulateFromSeed(
b, os.Stdout, app.BaseApp, AppStateFn(app.AppCodec(), app.SimulationManager()),
b,
os.Stdout,
app.BaseApp,
AppStateFn(app.AppCodec(), app.SimulationManager()),
simtypes.RandomAccounts, // Replace with own random account function if using keys other than secp256k1
SimulationOperations(app, app.AppCodec(), config),
app.ModuleAccountAddrs(), config,
app.ModuleAccountAddrs(),
config,
)
// export state and simParams before the simulation error is checked

View File

@ -17,6 +17,7 @@ import (
"github.com/cosmos/cosmos-sdk/simapp/helpers"
"github.com/cosmos/cosmos-sdk/store"
sdk "github.com/cosmos/cosmos-sdk/types"
simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types"
@ -72,9 +73,14 @@ func TestFullAppSimulation(t *testing.T) {
// run randomized simulation
_, simParams, simErr := simulation.SimulateFromSeed(
t, os.Stdout, app.BaseApp, AppStateFn(app.AppCodec(), app.SimulationManager()),
t,
os.Stdout,
app.BaseApp,
AppStateFn(app.AppCodec(), app.SimulationManager()),
simtypes.RandomAccounts, // Replace with own random account function if using keys other than secp256k1
SimulationOperations(app, app.AppCodec(), config),
app.ModuleAccountAddrs(), config,
app.ModuleAccountAddrs(),
config,
)
// export state and simParams before the simulation error is checked
@ -104,9 +110,14 @@ func TestAppImportExport(t *testing.T) {
// Run randomized simulation
_, simParams, simErr := simulation.SimulateFromSeed(
t, os.Stdout, app.BaseApp, AppStateFn(app.AppCodec(), app.SimulationManager()),
t,
os.Stdout,
app.BaseApp,
AppStateFn(app.AppCodec(), app.SimulationManager()),
simtypes.RandomAccounts, // Replace with own random account function if using keys other than secp256k1
SimulationOperations(app, app.AppCodec(), config),
app.ModuleAccountAddrs(), config,
app.ModuleAccountAddrs(),
config,
)
// export state and simParams before the simulation error is checked
@ -195,9 +206,14 @@ func TestAppSimulationAfterImport(t *testing.T) {
// Run randomized simulation
stopEarly, simParams, simErr := simulation.SimulateFromSeed(
t, os.Stdout, app.BaseApp, AppStateFn(app.AppCodec(), app.SimulationManager()),
t,
os.Stdout,
app.BaseApp,
AppStateFn(app.AppCodec(), app.SimulationManager()),
simtypes.RandomAccounts, // Replace with own random account function if using keys other than secp256k1
SimulationOperations(app, app.AppCodec(), config),
app.ModuleAccountAddrs(), config,
app.ModuleAccountAddrs(),
config,
)
// export state and simParams before the simulation error is checked
@ -237,9 +253,14 @@ func TestAppSimulationAfterImport(t *testing.T) {
})
_, _, err = simulation.SimulateFromSeed(
t, os.Stdout, newApp.BaseApp, AppStateFn(app.AppCodec(), app.SimulationManager()),
SimulationOperations(newApp, newApp.AppCodec(), config),
newApp.ModuleAccountAddrs(), config,
t,
os.Stdout,
app.BaseApp,
AppStateFn(app.AppCodec(), app.SimulationManager()),
simtypes.RandomAccounts, // Replace with own random account function if using keys other than secp256k1
SimulationOperations(app, app.AppCodec(), config),
app.ModuleAccountAddrs(),
config,
)
require.NoError(t, err)
}
@ -282,9 +303,14 @@ func TestAppStateDeterminism(t *testing.T) {
)
_, _, err := simulation.SimulateFromSeed(
t, os.Stdout, app.BaseApp, AppStateFn(app.AppCodec(), app.SimulationManager()),
t,
os.Stdout,
app.BaseApp,
AppStateFn(app.AppCodec(), app.SimulationManager()),
simtypes.RandomAccounts, // Replace with own random account function if using keys other than secp256k1
SimulationOperations(app, app.AppCodec(), config),
app.ModuleAccountAddrs(), config,
app.ModuleAccountAddrs(),
config,
)
require.NoError(t, err)

View File

@ -153,6 +153,9 @@ type AppStateFn func(r *rand.Rand, accs []Account, config Config) (
appState json.RawMessage, accounts []Account, chainId string, genesisTimestamp time.Time,
)
// RandomAccountFn returns a slice of n random simulation accounts
type RandomAccountFn func(r *rand.Rand, n int) []Account
type Params interface {
PastEvidenceFraction() float64
NumKeys() int

View File

@ -85,14 +85,16 @@ func (AppModuleBasic) RegisterInterfaces(registry codectypes.InterfaceRegistry)
type AppModule struct {
AppModuleBasic
accountKeeper keeper.AccountKeeper
accountKeeper keeper.AccountKeeper
randGenAccountsFn simulation.RandomGenesisAccountsFn
}
// NewAppModule creates a new AppModule object
func NewAppModule(cdc codec.Marshaler, accountKeeper keeper.AccountKeeper) AppModule {
func NewAppModule(cdc codec.Marshaler, accountKeeper keeper.AccountKeeper, randGenAccountsFn simulation.RandomGenesisAccountsFn) AppModule {
return AppModule{
AppModuleBasic: AppModuleBasic{},
accountKeeper: accountKeeper,
AppModuleBasic: AppModuleBasic{},
accountKeeper: accountKeeper,
randGenAccountsFn: randGenAccountsFn,
}
}
@ -153,8 +155,8 @@ func (AppModule) EndBlock(_ sdk.Context, _ abci.RequestEndBlock) []abci.Validato
// AppModuleSimulation functions
// GenerateGenesisState creates a randomized GenState of the auth module
func (AppModule) GenerateGenesisState(simState *module.SimulationState) {
simulation.RandomizedGenState(simState)
func (am AppModule) GenerateGenesisState(simState *module.SimulationState) {
simulation.RandomizedGenState(simState, am.randGenAccountsFn)
}
// ProposalContents doesn't return any content functions for governance proposals.

View File

@ -1,7 +1,5 @@
package simulation
// DONTCOVER
import (
"fmt"
"math/rand"
@ -23,6 +21,48 @@ const (
SigVerifyCostSECP256K1 = "sig_verify_cost_secp256k1"
)
// RandomGenesisAccountsFn defines the function required to generate custom account types
// on the auth module simulation.
type RandomGenesisAccountsFn func(simState *module.SimulationState) types.GenesisAccounts
// RandomGenesisAccounts defines the default RandomGenesisAccountsFn used on the SDK.
// It creates a slice of BaseAccount, ContinuousVestingAccount and DelayedVestingAccount.
func RandomGenesisAccounts(simState *module.SimulationState) types.GenesisAccounts {
genesisAccs := make(types.GenesisAccounts, len(simState.Accounts))
for i, acc := range simState.Accounts {
bacc := types.NewBaseAccountWithAddress(acc.Address)
// Only consider making a vesting account once the initial bonded validator
// set is exhausted due to needing to track DelegatedVesting.
if !(int64(i) > simState.NumBonded && simState.Rand.Intn(100) < 50) {
genesisAccs[i] = bacc
continue
}
initialVesting := sdk.NewCoins(sdk.NewInt64Coin(sdk.DefaultBondDenom, simState.Rand.Int63n(simState.InitialStake)))
var endTime int64
startTime := simState.GenTimestamp.Unix()
// Allow for some vesting accounts to vest very quickly while others very slowly.
if simState.Rand.Intn(100) < 50 {
endTime = int64(simulation.RandIntBetween(simState.Rand, int(startTime)+1, int(startTime+(60*60*24*30))))
} else {
endTime = int64(simulation.RandIntBetween(simState.Rand, int(startTime)+1, int(startTime+(60*60*12))))
}
bva := vestingtypes.NewBaseVestingAccount(bacc, initialVesting, endTime)
if simState.Rand.Intn(100) < 50 {
genesisAccs[i] = vestingtypes.NewContinuousVestingAccountRaw(bva, startTime)
} else {
genesisAccs[i] = vestingtypes.NewDelayedVestingAccountRaw(bva)
}
}
return genesisAccs
}
// GenMaxMemoChars randomized MaxMemoChars
func GenMaxMemoChars(r *rand.Rand) uint64 {
return uint64(simulation.RandIntBetween(r, 100, 200))
@ -52,7 +92,7 @@ func GenSigVerifyCostSECP256K1(r *rand.Rand) uint64 {
}
// RandomizedGenState generates a random GenesisState for auth
func RandomizedGenState(simState *module.SimulationState) {
func RandomizedGenState(simState *module.SimulationState, randGenAccountsFn RandomGenesisAccountsFn) {
var maxMemoChars uint64
simState.AppParams.GetOrGenerate(
simState.Cdc, MaxMemoChars, &maxMemoChars, simState.Rand,
@ -85,46 +125,10 @@ func RandomizedGenState(simState *module.SimulationState) {
params := types.NewParams(maxMemoChars, txSigLimit, txSizeCostPerByte,
sigVerifyCostED25519, sigVerifyCostSECP256K1)
genesisAccs := RandomGenesisAccounts(simState)
genesisAccs := randGenAccountsFn(simState)
authGenesis := types.NewGenesisState(params, genesisAccs)
fmt.Printf("Selected randomly generated auth parameters:\n%s\n", codec.MustMarshalJSONIndent(simState.Cdc, &authGenesis.Params))
simState.GenState[types.ModuleName] = simState.Cdc.MustMarshalJSON(authGenesis)
}
// RandomGenesisAccounts returns randomly generated genesis accounts
func RandomGenesisAccounts(simState *module.SimulationState) (genesisAccs types.GenesisAccounts) {
for i, acc := range simState.Accounts {
bacc := types.NewBaseAccountWithAddress(acc.Address)
var gacc types.GenesisAccount = bacc
// Only consider making a vesting account once the initial bonded validator
// set is exhausted due to needing to track DelegatedVesting.
if int64(i) > simState.NumBonded && simState.Rand.Intn(100) < 50 {
initialVesting := sdk.NewCoins(sdk.NewInt64Coin(sdk.DefaultBondDenom, simState.Rand.Int63n(simState.InitialStake)))
var endTime int64
startTime := simState.GenTimestamp.Unix()
// Allow for some vesting accounts to vest very quickly while others very slowly.
if simState.Rand.Intn(100) < 50 {
endTime = int64(simulation.RandIntBetween(simState.Rand, int(startTime)+1, int(startTime+(60*60*24*30))))
} else {
endTime = int64(simulation.RandIntBetween(simState.Rand, int(startTime)+1, int(startTime+(60*60*12))))
}
bva := vestingtypes.NewBaseVestingAccount(bacc, initialVesting, endTime)
if simState.Rand.Intn(100) < 50 {
gacc = vestingtypes.NewContinuousVestingAccountRaw(bva, startTime)
} else {
gacc = vestingtypes.NewDelayedVestingAccountRaw(bva)
}
}
genesisAccs = append(genesisAccs, gacc)
}
return genesisAccs
}

View File

@ -35,7 +35,7 @@ func TestRandomizedGenState(t *testing.T) {
GenState: make(map[string]json.RawMessage),
}
simulation.RandomizedGenState(&simState)
simulation.RandomizedGenState(&simState, simulation.RandomGenesisAccounts)
var authGenesis types.GenesisState
simState.Cdc.MustUnmarshalJSON(simState.GenState[types.ModuleName], &authGenesis)

View File

@ -35,7 +35,7 @@ func RandomGenesisSendParams(r *rand.Rand) types.SendEnabledParams {
return params.SendEnabled
}
// RandomGenesisAccounts returns a slice of account balances. Each account has
// RandomGenesisBalances returns a slice of account balances. Each account has
// a balance of simState.InitialStake for sdk.DefaultBondDenom.
func RandomGenesisBalances(simState *module.SimulationState) []types.Balance {
genesisBalances := []types.Balance{}

View File

@ -44,9 +44,14 @@ func initChain(
// operations, testing the provided invariants, but using the provided config.Seed.
// TODO: split this monster function up
func SimulateFromSeed(
tb testing.TB, w io.Writer, app *baseapp.BaseApp,
appStateFn simulation.AppStateFn, ops WeightedOperations,
blackListedAccs map[string]bool, config simulation.Config,
tb testing.TB,
w io.Writer,
app *baseapp.BaseApp,
appStateFn simulation.AppStateFn,
randAccFn simulation.RandomAccountFn,
ops WeightedOperations,
blackListedAccs map[string]bool,
config simulation.Config,
) (stopEarly bool, exportedParams Params, err error) {
// in case we have to end early, don't os.Exit so that we can run cleanup code.
testingMode, _, b := getTestingMode(tb)
@ -57,7 +62,7 @@ func SimulateFromSeed(
fmt.Fprintf(w, "Randomized simulation params: \n%s\n", mustMarshalJSONIndent(params))
timeDiff := maxTimePerBlock - minTimePerBlock
accs := simulation.RandomAccounts(r, params.NumKeys())
accs := randAccFn(r, params.NumKeys())
eventStats := NewEventStats()
// Second variable to keep pending validator set (delayed one block since