Merge PR #4838: Sim refactor 2 - Move GenesisState generators to modules
This commit is contained in:
parent
a131570cdc
commit
45b25ceaae
|
@ -26,9 +26,9 @@ commands:
|
|||
- go-src-v1-{{ .Revision }}
|
||||
- checkout
|
||||
- restore_cache:
|
||||
name: "Restore go modules cache"
|
||||
keys:
|
||||
- go-mod-v2-{{ checksum "go.sum" }}
|
||||
name: "Restore go modules cache"
|
||||
keys:
|
||||
- go-mod-v2-{{ checksum "go.sum" }}
|
||||
- run:
|
||||
name: << parameters.description >>
|
||||
command: |
|
||||
|
@ -40,7 +40,7 @@ jobs:
|
|||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
Name : "Build docs"
|
||||
name: "Build docs"
|
||||
command: make build-docs
|
||||
- run:
|
||||
name: "Upload docs to S3"
|
||||
|
@ -87,13 +87,6 @@ jobs:
|
|||
- make:
|
||||
target: test_sim_import_export
|
||||
description: "Test application import/export simulation"
|
||||
- run:
|
||||
command: |
|
||||
mkdir -p /tmp/errors
|
||||
cp /tmp/**/app-simulation-seed* /tmp/errors/
|
||||
when: on_fail
|
||||
- store_artifacts:
|
||||
path: /tmp/errors
|
||||
|
||||
test_sim_after_import:
|
||||
executor: golang
|
||||
|
@ -101,13 +94,6 @@ jobs:
|
|||
- make:
|
||||
target: test_sim_after_import
|
||||
description: "Test simulation after import"
|
||||
- run:
|
||||
command: |
|
||||
mkdir -p /tmp/errors
|
||||
cp /tmp/**/app-simulation-seed* /tmp/errors/
|
||||
when: on_fail
|
||||
- store_artifacts:
|
||||
path: /tmp/errors
|
||||
|
||||
test_sim_multi_seed_long:
|
||||
executor: golang
|
||||
|
@ -115,13 +101,6 @@ jobs:
|
|||
- make:
|
||||
target: test_sim_multi_seed_long
|
||||
description: "Test multi-seed simulation (long)"
|
||||
- run:
|
||||
command: |
|
||||
mkdir -p /tmp/errors
|
||||
cp /tmp/**/app-simulation-seed* /tmp/errors/
|
||||
when: on_fail
|
||||
- store_artifacts:
|
||||
path: /tmp/errors
|
||||
|
||||
test_sim_multi_seed_short:
|
||||
executor: golang
|
||||
|
@ -129,14 +108,6 @@ jobs:
|
|||
- make:
|
||||
target: test_sim_multi_seed_short
|
||||
description: "Test multi-seed simulation (short)"
|
||||
- run:
|
||||
command: |
|
||||
mkdir -p /tmp/errors
|
||||
cp /tmp/**/app-simulation-seed* /tmp/errors/
|
||||
when: on_fail
|
||||
|
||||
- store_artifacts:
|
||||
path: /tmp/errors
|
||||
|
||||
test_cover:
|
||||
executor: golang
|
||||
|
|
|
@ -61,9 +61,12 @@ longer panics if the store to load contains substores that we didn't explicitly
|
|||
* (simulation) [\#4824](https://github.com/cosmos/cosmos-sdk/issues/4824) PrintAllInvariants flag will print all failed invariants
|
||||
* (simulation) [\#4490](https://github.com/cosmos/cosmos-sdk/issues/4490) add `InitialBlockHeight` flag to resume a simulation from a given block
|
||||
* Support exporting the simulation stats to a given JSON file
|
||||
* (simulation) [\#4847](https://github.com/cosmos/cosmos-sdk/issues/4847) `SimApp` and simulation refactors
|
||||
* (simulation) [\#4847](https://github.com/cosmos/cosmos-sdk/issues/4847), [\#4838](https://github.com/cosmos/cosmos-sdk/pull/4838) `SimApp` and simulation refactors
|
||||
* Implement `SimulationManager` for executing modules' simulation functionalities in a modularized way
|
||||
* Add `DecodeStore` to the `SimulationManager` for decoding each module's types
|
||||
* Add `RegisterStoreDecoders` to the `SimulationManager` for decoding each module's types
|
||||
* Add `GenerateGenesisStates` to the `SimulationManager` to generate a randomized `GenState` for each module
|
||||
* Add `RandomizedParams` to the `SimulationManager` that registers each modules' parameters `Content` to simulate
|
||||
`ParamChangeProposal`s
|
||||
* (simulation) [\#4893](https://github.com/cosmos/cosmos-sdk/issues/4893) Change SimApp keepers to be public and add getter functions for keys and codec
|
||||
* (simulation) [\#4906](https://github.com/cosmos/cosmos-sdk/issues/4906) Add simulation `Config` struct that wraps simulation flags
|
||||
* (store) [\#4792](https://github.com/cosmos/cosmos-sdk/issues/4792) panic on non-registered store
|
||||
|
|
2
Makefile
2
Makefile
|
@ -105,7 +105,7 @@ test_race:
|
|||
test_sim_nondeterminism:
|
||||
@echo "Running non-determinism test..."
|
||||
@go test -mod=readonly $(SIMAPP) -run TestAppStateDeterminism -Enabled=true \
|
||||
-NumBlocks=100 -BlockSize=200 -Commit=true -v -timeout 24h
|
||||
-NumBlocks=100 -BlockSize=200 -Commit=true -Period=0 -v -timeout 24h
|
||||
|
||||
test_sim_custom_genesis_fast:
|
||||
@echo "Running custom genesis simulation..."
|
||||
|
|
1
go.mod
1
go.mod
|
@ -6,7 +6,6 @@ require (
|
|||
github.com/btcsuite/btcd v0.0.0-20190115013929-ed77733ec07d
|
||||
github.com/cosmos/go-bip39 v0.0.0-20180618194314-52158e4697b8
|
||||
github.com/cosmos/ledger-cosmos-go v0.10.3
|
||||
github.com/cosmos/tools v0.0.0-20190729191304-444fa9c55188 // indirect
|
||||
github.com/fortytw2/leaktest v1.3.0 // indirect
|
||||
github.com/gogo/protobuf v1.2.1
|
||||
github.com/golang/mock v1.3.1-0.20190508161146-9fa652df1129
|
||||
|
|
4
go.sum
4
go.sum
|
@ -33,10 +33,6 @@ github.com/cosmos/ledger-cosmos-go v0.10.3 h1:Qhi5yTR5Pg1CaTpd00pxlGwNl4sFRdtK1J
|
|||
github.com/cosmos/ledger-cosmos-go v0.10.3/go.mod h1:J8//BsAGTo3OC/vDLjMRFLW6q0WAaXvHnVc7ZmE8iUY=
|
||||
github.com/cosmos/ledger-go v0.9.2 h1:Nnao/dLwaVTk1Q5U9THldpUMMXU94BOTWPddSmVB6pI=
|
||||
github.com/cosmos/ledger-go v0.9.2/go.mod h1:oZJ2hHAZROdlHiwTg4t7kP+GKIIkBT+o6c9QWFanOyI=
|
||||
github.com/cosmos/tools v0.0.0-20190729191304-444fa9c55188 h1:KZsNQXLq7ZUURaBjVrztEqZX+d7qpjQkS4a0jbCMHIY=
|
||||
github.com/cosmos/tools v0.0.0-20190729191304-444fa9c55188/go.mod h1:ycjJZ351OX/Y/DYgZqNn1WLCgpmVH7j29THN8vjbb9U=
|
||||
github.com/cosmos/tools/cmd/clog v0.0.0-20190722180430-ea942c183cba h1:YhVnGzBkE2TvfBW5fAYBdNVK/3bwTPYVbMaOIGRHFRY=
|
||||
github.com/cosmos/tools/cmd/clog v0.0.0-20190722180430-ea942c183cba/go.mod h1:TdPuAVaU2rc6K24ejr/AnGznt9Fd2qjtMoRrTO4uFrI=
|
||||
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
|
||||
github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
|
|
|
@ -184,9 +184,9 @@ func NewSimApp(
|
|||
bank.NewAppModule(app.BankKeeper, app.AccountKeeper),
|
||||
crisis.NewAppModule(&app.CrisisKeeper),
|
||||
supply.NewAppModule(app.SupplyKeeper, app.AccountKeeper),
|
||||
distr.NewAppModule(app.DistrKeeper, app.SupplyKeeper),
|
||||
gov.NewAppModule(app.GovKeeper, app.SupplyKeeper),
|
||||
mint.NewAppModule(app.MintKeeper),
|
||||
distr.NewAppModule(app.DistrKeeper, app.SupplyKeeper),
|
||||
slashing.NewAppModule(app.SlashingKeeper, app.StakingKeeper),
|
||||
staking.NewAppModule(app.StakingKeeper, app.AccountKeeper, app.SupplyKeeper),
|
||||
nft.NewAppModule(app.NFTKeeper),
|
||||
|
@ -204,13 +204,30 @@ func NewSimApp(
|
|||
app.mm.SetOrderInitGenesis(
|
||||
genaccounts.ModuleName, distr.ModuleName, staking.ModuleName,
|
||||
auth.ModuleName, bank.ModuleName, slashing.ModuleName, gov.ModuleName,
|
||||
mint.ModuleName, supply.ModuleName, crisis.ModuleName, genutil.ModuleName,
|
||||
mint.ModuleName, supply.ModuleName, crisis.ModuleName, nft.ModuleName,
|
||||
genutil.ModuleName,
|
||||
)
|
||||
|
||||
app.mm.RegisterInvariants(&app.CrisisKeeper)
|
||||
app.mm.RegisterRoutes(app.Router(), app.QueryRouter())
|
||||
|
||||
app.sm = module.NewSimulationManager(app.mm.Modules)
|
||||
// create the simulation manager and define the order of the modules for deterministic simulations
|
||||
//
|
||||
// NOTE: this is not required apps that don't use the simulator for fuzz testing
|
||||
// transactions
|
||||
app.sm = module.NewSimulationManager(
|
||||
genaccounts.NewAppModule(app.AccountKeeper),
|
||||
auth.NewAppModule(app.AccountKeeper),
|
||||
bank.NewAppModule(app.BankKeeper, app.AccountKeeper),
|
||||
supply.NewAppModule(app.SupplyKeeper, app.AccountKeeper),
|
||||
gov.NewAppModule(app.GovKeeper, app.SupplyKeeper),
|
||||
mint.NewAppModule(app.MintKeeper),
|
||||
distr.NewAppModule(app.DistrKeeper, app.SupplyKeeper),
|
||||
staking.NewAppModule(app.StakingKeeper, app.AccountKeeper, app.SupplyKeeper),
|
||||
slashing.NewAppModule(app.SlashingKeeper, app.StakingKeeper),
|
||||
// nft.NewAppModule(app.NFTKeeper),
|
||||
)
|
||||
|
||||
app.sm.RegisterStoreDecoders()
|
||||
|
||||
// initialize stores
|
||||
|
|
121
simapp/doc.go
121
simapp/doc.go
|
@ -1,121 +0,0 @@
|
|||
/*
|
||||
Package simapp implements a full fledged Cosmos SDK application used for executing
|
||||
simulation test suites.
|
||||
|
||||
Simulation App
|
||||
|
||||
The SimApp type defines an application used for running extensive simulation
|
||||
testing suites. It contains all core modules, including governance, staking,
|
||||
slashing, and distribution.
|
||||
|
||||
Simulation is executed with various inputs including the number of blocks to
|
||||
simulate, the block size, whether the app should commit or not, the invariant
|
||||
checking period, and a seed which is used as a source of pseudo-randomness.
|
||||
|
||||
In addition to the various inputs, simulation runs mainly in three modes:
|
||||
|
||||
1. Completely random where the initial state, module parameters and simulation
|
||||
parameters are pseudo-randomly generated.
|
||||
|
||||
2. From a genesis file where the initial state and the module parameters are defined.
|
||||
This mode is helpful for running simulations on a known state such as a live
|
||||
network export where a new (mostly likely breaking) version of the application
|
||||
needs to be tested.
|
||||
|
||||
3. From a params file where the initial state is pseudo-randomly generated but the
|
||||
module and simulation parameters can be provided manually. This allows for a more
|
||||
controlled and deterministic simulation setup while allowing the state space to
|
||||
still be pseudo-randomly simulated.
|
||||
|
||||
The simulation test suite also supports testing determinism and import/export
|
||||
functionality.
|
||||
|
||||
Randomness
|
||||
|
||||
Currently, simulation uses a single seed (integer) as a source for a PRNG by
|
||||
which all random operations are executed from. Any call to the PRNG changes all
|
||||
future operations as the internal state of the PRNG is modified. For example,
|
||||
if a new message type is created and needs to be simulated, the new introduced
|
||||
PRNG call will change all subsequent operations.
|
||||
|
||||
This may can often be problematic when testing fixes to simulation faults. One
|
||||
current solution to this is to use a params file as mentioned above. In the future
|
||||
the simulation suite is expected to support a series of PRNGs that can be used
|
||||
uniquely per module and simulation component so that they will not effect each
|
||||
others state execution outcome.
|
||||
|
||||
Usage
|
||||
|
||||
To execute a completely pseudo-random simulation:
|
||||
|
||||
$ go test -mod=readonly github.com/cosmos/cosmos-sdk/simapp \
|
||||
-run=TestFullAppSimulation \
|
||||
-Enabled=true \
|
||||
-NumBlocks=100 \
|
||||
-BlockSize=200 \
|
||||
-Commit=true \
|
||||
-Seed=99 \
|
||||
-Period=5 \
|
||||
-v -timeout 24h
|
||||
|
||||
To execute simulation from a genesis file:
|
||||
|
||||
$ go test -mod=readonly github.com/cosmos/cosmos-sdk/simapp \
|
||||
-run=TestFullAppSimulation \
|
||||
-Enabled=true \
|
||||
-NumBlocks=100 \
|
||||
-BlockSize=200 \
|
||||
-Commit=true \
|
||||
-Seed=99 \
|
||||
-Period=5 \
|
||||
-Genesis=/path/to/genesis.json \
|
||||
-v -timeout 24h
|
||||
|
||||
To execute simulation from a simulation params file:
|
||||
|
||||
$ go test -mod=readonly github.com/cosmos/cosmos-sdk/simapp \
|
||||
-run=TestFullAppSimulation \
|
||||
-Enabled=true \
|
||||
-NumBlocks=100 \
|
||||
-BlockSize=200 \
|
||||
-Commit=true \
|
||||
-Seed=99 \
|
||||
-Period=5 \
|
||||
-Params=/path/to/params.json \
|
||||
-v -timeout 24h
|
||||
|
||||
To export the simulation params to a file at a given block height:
|
||||
|
||||
$ go test -mod=readonly github.com/cosmos/cosmos-sdk/simapp \
|
||||
-run=TestFullAppSimulation \
|
||||
-Enabled=true \
|
||||
-NumBlocks=100 \
|
||||
-BlockSize=200 \
|
||||
-Commit=true \
|
||||
-Seed=99 \
|
||||
-Period=5 \
|
||||
-ExportParamsPath=/path/to/params.json \
|
||||
-ExportParamsHeight=50 \
|
||||
-v -timeout 24h
|
||||
|
||||
|
||||
To export the simulation app state (i.e genesis) to a file:
|
||||
|
||||
$ go test -mod=readonly github.com/cosmos/cosmos-sdk/simapp \
|
||||
-run=TestFullAppSimulation \
|
||||
-Enabled=true \
|
||||
-NumBlocks=100 \
|
||||
-BlockSize=200 \
|
||||
-Commit=true \
|
||||
-Seed=99 \
|
||||
-Period=5 \
|
||||
-ExportStatePath=/path/to/genesis.json \
|
||||
v -timeout 24h
|
||||
|
||||
Params
|
||||
|
||||
Params that are provided to simulation from a JSON file are used to used to set
|
||||
both module parameters and simulation parameters. See sim_test.go for the full
|
||||
set of parameters that can be provided.
|
||||
*/
|
||||
package simapp
|
|
@ -24,7 +24,6 @@ import (
|
|||
"github.com/cosmos/cosmos-sdk/x/gov"
|
||||
govsimops "github.com/cosmos/cosmos-sdk/x/gov/simulation/operations"
|
||||
"github.com/cosmos/cosmos-sdk/x/mint"
|
||||
nftsimops "github.com/cosmos/cosmos-sdk/x/nft/simulation/operations"
|
||||
"github.com/cosmos/cosmos-sdk/x/params"
|
||||
paramsimops "github.com/cosmos/cosmos-sdk/x/params/simulation/operations"
|
||||
"github.com/cosmos/cosmos-sdk/x/simulation"
|
||||
|
@ -35,23 +34,24 @@ import (
|
|||
"github.com/cosmos/cosmos-sdk/x/supply"
|
||||
)
|
||||
|
||||
// Get flags every time the simulator is run
|
||||
func init() {
|
||||
GetSimulatorFlags()
|
||||
}
|
||||
|
||||
// TODO: add description
|
||||
func testAndRunTxs(app *SimApp, config simulation.Config) []simulation.WeightedOperation {
|
||||
|
||||
cdc := MakeCodec()
|
||||
ap := make(simulation.AppParams)
|
||||
|
||||
paramChanges := app.sm.GenerateParamChanges(config.Seed)
|
||||
|
||||
if config.ParamsFile != "" {
|
||||
bz, err := ioutil.ReadFile(config.ParamsFile)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
cdc.MustUnmarshalJSON(bz, &ap)
|
||||
app.cdc.MustUnmarshalJSON(bz, &ap)
|
||||
}
|
||||
|
||||
// nolint: govet
|
||||
|
@ -59,7 +59,7 @@ func testAndRunTxs(app *SimApp, config simulation.Config) []simulation.WeightedO
|
|||
{
|
||||
func(_ *rand.Rand) int {
|
||||
var v int
|
||||
ap.GetOrGenerate(cdc, OpWeightDeductFee, &v, nil,
|
||||
ap.GetOrGenerate(app.cdc, OpWeightDeductFee, &v, nil,
|
||||
func(_ *rand.Rand) {
|
||||
v = 5
|
||||
})
|
||||
|
@ -70,7 +70,7 @@ func testAndRunTxs(app *SimApp, config simulation.Config) []simulation.WeightedO
|
|||
{
|
||||
func(_ *rand.Rand) int {
|
||||
var v int
|
||||
ap.GetOrGenerate(cdc, OpWeightMsgSend, &v, nil,
|
||||
ap.GetOrGenerate(app.cdc, OpWeightMsgSend, &v, nil,
|
||||
func(_ *rand.Rand) {
|
||||
v = 100
|
||||
})
|
||||
|
@ -81,7 +81,7 @@ func testAndRunTxs(app *SimApp, config simulation.Config) []simulation.WeightedO
|
|||
{
|
||||
func(_ *rand.Rand) int {
|
||||
var v int
|
||||
ap.GetOrGenerate(cdc, OpWeightSingleInputMsgMultiSend, &v, nil,
|
||||
ap.GetOrGenerate(app.cdc, OpWeightSingleInputMsgMultiSend, &v, nil,
|
||||
func(_ *rand.Rand) {
|
||||
v = 10
|
||||
})
|
||||
|
@ -92,7 +92,7 @@ func testAndRunTxs(app *SimApp, config simulation.Config) []simulation.WeightedO
|
|||
{
|
||||
func(_ *rand.Rand) int {
|
||||
var v int
|
||||
ap.GetOrGenerate(cdc, OpWeightMsgSetWithdrawAddress, &v, nil,
|
||||
ap.GetOrGenerate(app.cdc, OpWeightMsgSetWithdrawAddress, &v, nil,
|
||||
func(_ *rand.Rand) {
|
||||
v = 50
|
||||
})
|
||||
|
@ -103,7 +103,7 @@ func testAndRunTxs(app *SimApp, config simulation.Config) []simulation.WeightedO
|
|||
{
|
||||
func(_ *rand.Rand) int {
|
||||
var v int
|
||||
ap.GetOrGenerate(cdc, OpWeightMsgWithdrawDelegationReward, &v, nil,
|
||||
ap.GetOrGenerate(app.cdc, OpWeightMsgWithdrawDelegationReward, &v, nil,
|
||||
func(_ *rand.Rand) {
|
||||
v = 50
|
||||
})
|
||||
|
@ -114,7 +114,7 @@ func testAndRunTxs(app *SimApp, config simulation.Config) []simulation.WeightedO
|
|||
{
|
||||
func(_ *rand.Rand) int {
|
||||
var v int
|
||||
ap.GetOrGenerate(cdc, OpWeightMsgWithdrawValidatorCommission, &v, nil,
|
||||
ap.GetOrGenerate(app.cdc, OpWeightMsgWithdrawValidatorCommission, &v, nil,
|
||||
func(_ *rand.Rand) {
|
||||
v = 50
|
||||
})
|
||||
|
@ -125,7 +125,7 @@ func testAndRunTxs(app *SimApp, config simulation.Config) []simulation.WeightedO
|
|||
{
|
||||
func(_ *rand.Rand) int {
|
||||
var v int
|
||||
ap.GetOrGenerate(cdc, OpWeightSubmitVotingSlashingTextProposal, &v, nil,
|
||||
ap.GetOrGenerate(app.cdc, OpWeightSubmitVotingSlashingTextProposal, &v, nil,
|
||||
func(_ *rand.Rand) {
|
||||
v = 5
|
||||
})
|
||||
|
@ -136,7 +136,7 @@ func testAndRunTxs(app *SimApp, config simulation.Config) []simulation.WeightedO
|
|||
{
|
||||
func(_ *rand.Rand) int {
|
||||
var v int
|
||||
ap.GetOrGenerate(cdc, OpWeightSubmitVotingSlashingCommunitySpendProposal, &v, nil,
|
||||
ap.GetOrGenerate(app.cdc, OpWeightSubmitVotingSlashingCommunitySpendProposal, &v, nil,
|
||||
func(_ *rand.Rand) {
|
||||
v = 5
|
||||
})
|
||||
|
@ -147,18 +147,18 @@ func testAndRunTxs(app *SimApp, config simulation.Config) []simulation.WeightedO
|
|||
{
|
||||
func(_ *rand.Rand) int {
|
||||
var v int
|
||||
ap.GetOrGenerate(cdc, OpWeightSubmitVotingSlashingParamChangeProposal, &v, nil,
|
||||
ap.GetOrGenerate(app.cdc, OpWeightSubmitVotingSlashingParamChangeProposal, &v, nil,
|
||||
func(_ *rand.Rand) {
|
||||
v = 5
|
||||
})
|
||||
return v
|
||||
}(nil),
|
||||
govsimops.SimulateSubmittingVotingAndSlashingForProposal(app.GovKeeper, paramsimops.SimulateParamChangeProposalContent),
|
||||
govsimops.SimulateSubmittingVotingAndSlashingForProposal(app.GovKeeper, paramsimops.SimulateParamChangeProposalContent(paramChanges)),
|
||||
},
|
||||
{
|
||||
func(_ *rand.Rand) int {
|
||||
var v int
|
||||
ap.GetOrGenerate(cdc, OpWeightMsgDeposit, &v, nil,
|
||||
ap.GetOrGenerate(app.cdc, OpWeightMsgDeposit, &v, nil,
|
||||
func(_ *rand.Rand) {
|
||||
v = 100
|
||||
})
|
||||
|
@ -169,7 +169,7 @@ func testAndRunTxs(app *SimApp, config simulation.Config) []simulation.WeightedO
|
|||
{
|
||||
func(_ *rand.Rand) int {
|
||||
var v int
|
||||
ap.GetOrGenerate(cdc, OpWeightMsgCreateValidator, &v, nil,
|
||||
ap.GetOrGenerate(app.cdc, OpWeightMsgCreateValidator, &v, nil,
|
||||
func(_ *rand.Rand) {
|
||||
v = 100
|
||||
})
|
||||
|
@ -180,7 +180,7 @@ func testAndRunTxs(app *SimApp, config simulation.Config) []simulation.WeightedO
|
|||
{
|
||||
func(_ *rand.Rand) int {
|
||||
var v int
|
||||
ap.GetOrGenerate(cdc, OpWeightMsgEditValidator, &v, nil,
|
||||
ap.GetOrGenerate(app.cdc, OpWeightMsgEditValidator, &v, nil,
|
||||
func(_ *rand.Rand) {
|
||||
v = 5
|
||||
})
|
||||
|
@ -191,7 +191,7 @@ func testAndRunTxs(app *SimApp, config simulation.Config) []simulation.WeightedO
|
|||
{
|
||||
func(_ *rand.Rand) int {
|
||||
var v int
|
||||
ap.GetOrGenerate(cdc, OpWeightMsgDelegate, &v, nil,
|
||||
ap.GetOrGenerate(app.cdc, OpWeightMsgDelegate, &v, nil,
|
||||
func(_ *rand.Rand) {
|
||||
v = 100
|
||||
})
|
||||
|
@ -202,7 +202,7 @@ func testAndRunTxs(app *SimApp, config simulation.Config) []simulation.WeightedO
|
|||
{
|
||||
func(_ *rand.Rand) int {
|
||||
var v int
|
||||
ap.GetOrGenerate(cdc, OpWeightMsgUndelegate, &v, nil,
|
||||
ap.GetOrGenerate(app.cdc, OpWeightMsgUndelegate, &v, nil,
|
||||
func(_ *rand.Rand) {
|
||||
v = 100
|
||||
})
|
||||
|
@ -213,7 +213,7 @@ func testAndRunTxs(app *SimApp, config simulation.Config) []simulation.WeightedO
|
|||
{
|
||||
func(_ *rand.Rand) int {
|
||||
var v int
|
||||
ap.GetOrGenerate(cdc, OpWeightMsgBeginRedelegate, &v, nil,
|
||||
ap.GetOrGenerate(app.cdc, OpWeightMsgBeginRedelegate, &v, nil,
|
||||
func(_ *rand.Rand) {
|
||||
v = 100
|
||||
})
|
||||
|
@ -224,7 +224,7 @@ func testAndRunTxs(app *SimApp, config simulation.Config) []simulation.WeightedO
|
|||
{
|
||||
func(_ *rand.Rand) int {
|
||||
var v int
|
||||
ap.GetOrGenerate(cdc, OpWeightMsgUnjail, &v, nil,
|
||||
ap.GetOrGenerate(app.cdc, OpWeightMsgUnjail, &v, nil,
|
||||
func(_ *rand.Rand) {
|
||||
v = 100
|
||||
})
|
||||
|
@ -232,50 +232,50 @@ func testAndRunTxs(app *SimApp, config simulation.Config) []simulation.WeightedO
|
|||
}(nil),
|
||||
slashingsimops.SimulateMsgUnjail(app.SlashingKeeper),
|
||||
},
|
||||
{
|
||||
func(_ *rand.Rand) int {
|
||||
var v int
|
||||
ap.GetOrGenerate(cdc, OpWeightMsgTransferNFT, &v, nil,
|
||||
func(_ *rand.Rand) {
|
||||
v = 100
|
||||
})
|
||||
return v
|
||||
}(nil),
|
||||
nftsimops.SimulateMsgTransferNFT(app.NFTKeeper),
|
||||
},
|
||||
{
|
||||
func(_ *rand.Rand) int {
|
||||
var v int
|
||||
ap.GetOrGenerate(cdc, OpWeightMsgEditNFTMetadata, &v, nil,
|
||||
func(_ *rand.Rand) {
|
||||
v = 100
|
||||
})
|
||||
return v
|
||||
}(nil),
|
||||
nftsimops.SimulateMsgEditNFTMetadata(app.NFTKeeper),
|
||||
},
|
||||
{
|
||||
func(_ *rand.Rand) int {
|
||||
var v int
|
||||
ap.GetOrGenerate(cdc, OpWeightMsgMintNFT, &v, nil,
|
||||
func(_ *rand.Rand) {
|
||||
v = 100
|
||||
})
|
||||
return v
|
||||
}(nil),
|
||||
nftsimops.SimulateMsgMintNFT(app.NFTKeeper),
|
||||
},
|
||||
{
|
||||
func(_ *rand.Rand) int {
|
||||
var v int
|
||||
ap.GetOrGenerate(cdc, OpWeightMsgBurnNFT, &v, nil,
|
||||
func(_ *rand.Rand) {
|
||||
v = 100
|
||||
})
|
||||
return v
|
||||
}(nil),
|
||||
nftsimops.SimulateMsgBurnNFT(app.NFTKeeper),
|
||||
},
|
||||
// {
|
||||
// func(_ *rand.Rand) int {
|
||||
// var v int
|
||||
// ap.GetOrGenerate(app.cdc, OpWeightMsgTransferNFT, &v, nil,
|
||||
// func(_ *rand.Rand) {
|
||||
// v = 33
|
||||
// })
|
||||
// return v
|
||||
// }(nil),
|
||||
// nftsimops.SimulateMsgTransferNFT(app.NFTKeeper),
|
||||
// },
|
||||
// {
|
||||
// func(_ *rand.Rand) int {
|
||||
// var v int
|
||||
// ap.GetOrGenerate(app.cdc, OpWeightMsgEditNFTMetadata, &v, nil,
|
||||
// func(_ *rand.Rand) {
|
||||
// v = 5
|
||||
// })
|
||||
// return v
|
||||
// }(nil),
|
||||
// nftsimops.SimulateMsgEditNFTMetadata(app.NFTKeeper),
|
||||
// },
|
||||
// {
|
||||
// func(_ *rand.Rand) int {
|
||||
// var v int
|
||||
// ap.GetOrGenerate(app.cdc, OpWeightMsgMintNFT, &v, nil,
|
||||
// func(_ *rand.Rand) {
|
||||
// v = 10
|
||||
// })
|
||||
// return v
|
||||
// }(nil),
|
||||
// nftsimops.SimulateMsgMintNFT(app.NFTKeeper),
|
||||
// },
|
||||
// {
|
||||
// func(_ *rand.Rand) int {
|
||||
// var v int
|
||||
// ap.GetOrGenerate(app.cdc, OpWeightMsgBurnNFT, &v, nil,
|
||||
// func(_ *rand.Rand) {
|
||||
// v = 5
|
||||
// })
|
||||
// return v
|
||||
// }(nil),
|
||||
// nftsimops.SimulateMsgBurnNFT(app.NFTKeeper),
|
||||
// },
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -310,37 +310,22 @@ func BenchmarkFullAppSimulation(b *testing.B) {
|
|||
|
||||
// Run randomized simulation
|
||||
// TODO: parameterize numbers, save for a later PR
|
||||
_, params, simErr := simulation.SimulateFromSeed(
|
||||
b, os.Stdout, app.BaseApp, AppStateFn,
|
||||
_, simParams, simErr := simulation.SimulateFromSeed(
|
||||
b, os.Stdout, app.BaseApp, AppStateFn(app.Codec(), app.sm),
|
||||
testAndRunTxs(app, config), invariants(app),
|
||||
app.ModuleAccountAddrs(), config,
|
||||
)
|
||||
|
||||
// export state and params before the simulation error is checked
|
||||
if config.ExportStatePath != "" {
|
||||
fmt.Println("Exporting app state...")
|
||||
appState, _, err := app.ExportAppStateAndValidators(false, nil)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
b.Fail()
|
||||
}
|
||||
err = ioutil.WriteFile(config.ExportStatePath, []byte(appState), 0644)
|
||||
if err != nil {
|
||||
if err := ExportStateToJSON(app, config.ExportStatePath); err != nil {
|
||||
fmt.Println(err)
|
||||
b.Fail()
|
||||
}
|
||||
}
|
||||
|
||||
if config.ExportParamsPath != "" {
|
||||
fmt.Println("Exporting simulation params...")
|
||||
paramsBz, err := json.MarshalIndent(params, "", " ")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
b.Fail()
|
||||
}
|
||||
|
||||
err = ioutil.WriteFile(config.ExportParamsPath, paramsBz, 0644)
|
||||
if err != nil {
|
||||
if err := ExportParamsToJSON(simParams, config.ExportParamsPath); err != nil {
|
||||
fmt.Println(err)
|
||||
b.Fail()
|
||||
}
|
||||
|
@ -360,71 +345,7 @@ func BenchmarkFullAppSimulation(b *testing.B) {
|
|||
|
||||
func TestFullAppSimulation(t *testing.T) {
|
||||
if !flagEnabledValue {
|
||||
t.Skip("Skipping application simulation")
|
||||
}
|
||||
|
||||
var logger log.Logger
|
||||
config := NewConfigFromFlags()
|
||||
|
||||
if flagVerboseValue {
|
||||
logger = log.TestingLogger()
|
||||
} else {
|
||||
logger = log.NewNopLogger()
|
||||
}
|
||||
|
||||
var db dbm.DB
|
||||
dir, _ := ioutil.TempDir("", "goleveldb-app-sim")
|
||||
db, _ = sdk.NewLevelDB("Simulation", dir)
|
||||
|
||||
defer func() {
|
||||
db.Close()
|
||||
os.RemoveAll(dir)
|
||||
}()
|
||||
|
||||
app := NewSimApp(logger, db, nil, true, 0, fauxMerkleModeOpt)
|
||||
require.Equal(t, "SimApp", app.Name())
|
||||
|
||||
// Run randomized simulation
|
||||
_, params, simErr := simulation.SimulateFromSeed(
|
||||
t, os.Stdout, app.BaseApp, AppStateFn,
|
||||
testAndRunTxs(app, config), invariants(app),
|
||||
app.ModuleAccountAddrs(), config,
|
||||
)
|
||||
|
||||
// export state and params before the simulation error is checked
|
||||
if config.ExportStatePath != "" {
|
||||
fmt.Println("Exporting app state...")
|
||||
appState, _, err := app.ExportAppStateAndValidators(false, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = ioutil.WriteFile(config.ExportStatePath, []byte(appState), 0644)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
if config.ExportParamsPath != "" {
|
||||
fmt.Println("Exporting simulation params...")
|
||||
fmt.Println(params)
|
||||
paramsBz, err := json.MarshalIndent(params, "", " ")
|
||||
require.NoError(t, err)
|
||||
|
||||
err = ioutil.WriteFile(config.ExportParamsPath, paramsBz, 0644)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
require.NoError(t, simErr)
|
||||
|
||||
if config.Commit {
|
||||
// for memdb:
|
||||
// fmt.Println("Database Size", db.Stats()["database.size"])
|
||||
fmt.Println("\nGoLevelDB Stats")
|
||||
fmt.Println(db.Stats()["leveldb.stats"])
|
||||
fmt.Println("GoLevelDB cached block size", db.Stats()["leveldb.cachedblock"])
|
||||
}
|
||||
}
|
||||
|
||||
func TestAppImportExport(t *testing.T) {
|
||||
if !flagEnabledValue {
|
||||
t.Skip("Skipping application import/export simulation")
|
||||
t.Skip("skipping application simulation")
|
||||
}
|
||||
|
||||
var logger log.Logger
|
||||
|
@ -450,27 +371,74 @@ func TestAppImportExport(t *testing.T) {
|
|||
|
||||
// Run randomized simulation
|
||||
_, simParams, simErr := simulation.SimulateFromSeed(
|
||||
t, os.Stdout, app.BaseApp, AppStateFn,
|
||||
t, os.Stdout, app.BaseApp, AppStateFn(app.Codec(), app.sm),
|
||||
testAndRunTxs(app, config), invariants(app),
|
||||
app.ModuleAccountAddrs(), config,
|
||||
)
|
||||
|
||||
// export state and params before the simulation error is checked
|
||||
if config.ExportStatePath != "" {
|
||||
err := ExportStateToJSON(app, config.ExportStatePath)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
if config.ExportParamsPath != "" {
|
||||
err := ExportParamsToJSON(simParams, config.ExportParamsPath)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
require.NoError(t, simErr)
|
||||
|
||||
if config.Commit {
|
||||
// for memdb:
|
||||
// fmt.Println("Database Size", db.Stats()["database.size"])
|
||||
fmt.Println("\nGoLevelDB Stats")
|
||||
fmt.Println(db.Stats()["leveldb.stats"])
|
||||
fmt.Println("GoLevelDB cached block size", db.Stats()["leveldb.cachedblock"])
|
||||
}
|
||||
}
|
||||
|
||||
func TestAppImportExport(t *testing.T) {
|
||||
if !flagEnabledValue {
|
||||
t.Skip("skipping application import/export simulation")
|
||||
}
|
||||
|
||||
var logger log.Logger
|
||||
config := NewConfigFromFlags()
|
||||
|
||||
if flagVerboseValue {
|
||||
logger = log.TestingLogger()
|
||||
} else {
|
||||
logger = log.NewNopLogger()
|
||||
}
|
||||
|
||||
var db dbm.DB
|
||||
dir, _ := ioutil.TempDir("", "goleveldb-app-sim")
|
||||
db, _ = sdk.NewLevelDB("Simulation", dir)
|
||||
|
||||
defer func() {
|
||||
db.Close()
|
||||
os.RemoveAll(dir)
|
||||
}()
|
||||
|
||||
app := NewSimApp(logger, db, nil, true, 0, fauxMerkleModeOpt)
|
||||
require.Equal(t, "SimApp", app.Name())
|
||||
|
||||
// Run randomized simulation
|
||||
_, simParams, simErr := simulation.SimulateFromSeed(
|
||||
t, os.Stdout, app.BaseApp, AppStateFn(app.Codec(), app.sm),
|
||||
testAndRunTxs(app, config), invariants(app),
|
||||
app.ModuleAccountAddrs(), config,
|
||||
)
|
||||
|
||||
// export state and simParams before the simulation error is checked
|
||||
if config.ExportStatePath != "" {
|
||||
fmt.Println("Exporting app state...")
|
||||
appState, _, err := app.ExportAppStateAndValidators(false, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = ioutil.WriteFile(config.ExportStatePath, []byte(appState), 0644)
|
||||
err := ExportStateToJSON(app, config.ExportStatePath)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
if config.ExportParamsPath != "" {
|
||||
fmt.Println("Exporting simulation params...")
|
||||
simParamsBz, err := json.MarshalIndent(simParams, "", " ")
|
||||
require.NoError(t, err)
|
||||
|
||||
err = ioutil.WriteFile(config.ExportParamsPath, simParamsBz, 0644)
|
||||
err := ExportParamsToJSON(simParams, config.ExportParamsPath)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
|
@ -484,11 +452,11 @@ func TestAppImportExport(t *testing.T) {
|
|||
fmt.Println("GoLevelDB cached block size", db.Stats()["leveldb.cachedblock"])
|
||||
}
|
||||
|
||||
fmt.Printf("Exporting genesis...\n")
|
||||
fmt.Printf("exporting genesis...\n")
|
||||
|
||||
appState, _, err := app.ExportAppStateAndValidators(false, []string{})
|
||||
require.NoError(t, err)
|
||||
fmt.Printf("Importing genesis...\n")
|
||||
fmt.Printf("importing genesis...\n")
|
||||
|
||||
newDir, _ := ioutil.TempDir("", "goleveldb-app-sim-2")
|
||||
newDB, _ := sdk.NewLevelDB("Simulation-2", dir)
|
||||
|
@ -508,7 +476,7 @@ func TestAppImportExport(t *testing.T) {
|
|||
ctxB := newApp.NewContext(true, abci.Header{Height: app.LastBlockHeight()})
|
||||
newApp.mm.InitGenesis(ctxB, genesisState)
|
||||
|
||||
fmt.Printf("Comparing stores...\n")
|
||||
fmt.Printf("comparing stores...\n")
|
||||
ctxA := app.NewContext(true, abci.Header{Height: app.LastBlockHeight()})
|
||||
|
||||
type StoreKeysPrefixes struct {
|
||||
|
@ -543,7 +511,7 @@ func TestAppImportExport(t *testing.T) {
|
|||
failedKVAs, failedKVBs := sdk.DiffKVStores(storeA, storeB, prefixes)
|
||||
require.Equal(t, len(failedKVAs), len(failedKVBs), "unequal sets of key-values to compare")
|
||||
|
||||
fmt.Printf("Compared %d key/value pairs between %s and %s\n", len(failedKVAs), storeKeyA, storeKeyB)
|
||||
fmt.Printf("compared %d key/value pairs between %s and %s\n", len(failedKVAs), storeKeyA, storeKeyB)
|
||||
require.Len(t, failedKVAs, 0, GetSimulationLog(storeKeyA.Name(), app.sm.StoreDecoders, app.cdc, failedKVAs, failedKVBs))
|
||||
}
|
||||
|
||||
|
@ -551,7 +519,7 @@ func TestAppImportExport(t *testing.T) {
|
|||
|
||||
func TestAppSimulationAfterImport(t *testing.T) {
|
||||
if !flagEnabledValue {
|
||||
t.Skip("Skipping application simulation after import")
|
||||
t.Skip("skipping application simulation after import")
|
||||
}
|
||||
|
||||
var logger log.Logger
|
||||
|
@ -575,28 +543,20 @@ func TestAppSimulationAfterImport(t *testing.T) {
|
|||
require.Equal(t, "SimApp", app.Name())
|
||||
|
||||
// Run randomized simulation
|
||||
stopEarly, params, simErr := simulation.SimulateFromSeed(
|
||||
t, os.Stdout, app.BaseApp, AppStateFn,
|
||||
stopEarly, simParams, simErr := simulation.SimulateFromSeed(
|
||||
t, os.Stdout, app.BaseApp, AppStateFn(app.Codec(), app.sm),
|
||||
testAndRunTxs(app, config), invariants(app),
|
||||
app.ModuleAccountAddrs(), config,
|
||||
)
|
||||
|
||||
// export state and params before the simulation error is checked
|
||||
if config.ExportStatePath != "" {
|
||||
fmt.Println("Exporting app state...")
|
||||
appState, _, err := app.ExportAppStateAndValidators(false, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = ioutil.WriteFile(config.ExportStatePath, []byte(appState), 0644)
|
||||
err := ExportStateToJSON(app, config.ExportStatePath)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
if config.ExportParamsPath != "" {
|
||||
fmt.Println("Exporting simulation params...")
|
||||
paramsBz, err := json.MarshalIndent(params, "", " ")
|
||||
require.NoError(t, err)
|
||||
|
||||
err = ioutil.WriteFile(config.ExportParamsPath, paramsBz, 0644)
|
||||
err := ExportParamsToJSON(simParams, config.ExportParamsPath)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
|
@ -612,16 +572,16 @@ func TestAppSimulationAfterImport(t *testing.T) {
|
|||
|
||||
if stopEarly {
|
||||
// we can't export or import a zero-validator genesis
|
||||
fmt.Printf("We can't export or import a zero-validator genesis, exiting test...\n")
|
||||
fmt.Printf("we can't export or import a zero-validator genesis, exiting test...\n")
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Printf("Exporting genesis...\n")
|
||||
fmt.Printf("exporting genesis...\n")
|
||||
|
||||
appState, _, err := app.ExportAppStateAndValidators(true, []string{})
|
||||
require.NoError(t, err)
|
||||
|
||||
fmt.Printf("Importing genesis...\n")
|
||||
fmt.Printf("importing genesis...\n")
|
||||
|
||||
newDir, _ := ioutil.TempDir("", "goleveldb-app-sim-2")
|
||||
newDB, _ := sdk.NewLevelDB("Simulation-2", dir)
|
||||
|
@ -639,7 +599,7 @@ func TestAppSimulationAfterImport(t *testing.T) {
|
|||
|
||||
// Run randomized simulation on imported app
|
||||
_, _, err = simulation.SimulateFromSeed(
|
||||
t, os.Stdout, newApp.BaseApp, AppStateFn,
|
||||
t, os.Stdout, newApp.BaseApp, AppStateFn(app.Codec(), app.sm),
|
||||
testAndRunTxs(newApp, config), invariants(newApp),
|
||||
newApp.ModuleAccountAddrs(), config,
|
||||
)
|
||||
|
@ -651,7 +611,7 @@ func TestAppSimulationAfterImport(t *testing.T) {
|
|||
// and doesn't depend on the application.
|
||||
func TestAppStateDeterminism(t *testing.T) {
|
||||
if !flagEnabledValue {
|
||||
t.Skip("Skipping application simulation")
|
||||
t.Skip("skipping application simulation")
|
||||
}
|
||||
|
||||
config := NewConfigFromFlags()
|
||||
|
@ -673,12 +633,12 @@ func TestAppStateDeterminism(t *testing.T) {
|
|||
app := NewSimApp(logger, db, nil, true, 0)
|
||||
|
||||
fmt.Printf(
|
||||
"Running non-determinism simulation; seed: %d/%d (%d), attempt: %d/%d\n",
|
||||
i+1, numSeeds, config.Seed, j+1, numTimesToRunPerSeed,
|
||||
"running non-determinism simulation; seed %d: %d/%d, attempt: %d/%d\n",
|
||||
config.Seed, i+1, numSeeds, j+1, numTimesToRunPerSeed,
|
||||
)
|
||||
|
||||
_, _, err := simulation.SimulateFromSeed(
|
||||
t, os.Stdout, app.BaseApp, AppStateFn,
|
||||
t, os.Stdout, app.BaseApp, AppStateFn(app.Codec(), app.sm),
|
||||
testAndRunTxs(app, config), []sdk.Invariant{},
|
||||
app.ModuleAccountAddrs(), config,
|
||||
)
|
||||
|
@ -688,7 +648,10 @@ func TestAppStateDeterminism(t *testing.T) {
|
|||
appHashList[j] = appHash
|
||||
|
||||
if j != 0 {
|
||||
require.Equal(t, appHashList[0], appHashList[j], "appHash list: %v", appHashList)
|
||||
require.Equal(
|
||||
t, appHashList[0], appHashList[j],
|
||||
"non-determinism in seed %d: %d/%d, attempt: %d/%d\n", config.Seed, i+1, numSeeds, j+1, numTimesToRunPerSeed,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -696,7 +659,9 @@ func TestAppStateDeterminism(t *testing.T) {
|
|||
|
||||
func BenchmarkInvariants(b *testing.B) {
|
||||
logger := log.NewNopLogger()
|
||||
|
||||
config := NewConfigFromFlags()
|
||||
config.AllInvariants = false
|
||||
|
||||
dir, _ := ioutil.TempDir("", "goleveldb-app-invariant-bench")
|
||||
db, _ := sdk.NewLevelDB("simulation", dir)
|
||||
|
@ -709,37 +674,22 @@ func BenchmarkInvariants(b *testing.B) {
|
|||
app := NewSimApp(logger, db, nil, true, 0)
|
||||
|
||||
// 2. Run parameterized simulation (w/o invariants)
|
||||
_, params, simErr := simulation.SimulateFromSeed(
|
||||
b, ioutil.Discard, app.BaseApp, AppStateFn,
|
||||
_, simParams, simErr := simulation.SimulateFromSeed(
|
||||
b, ioutil.Discard, app.BaseApp, AppStateFn(app.Codec(), app.sm),
|
||||
testAndRunTxs(app, config), []sdk.Invariant{},
|
||||
app.ModuleAccountAddrs(), config,
|
||||
)
|
||||
|
||||
// export state and params before the simulation error is checked
|
||||
if config.ExportStatePath != "" {
|
||||
fmt.Println("Exporting app state...")
|
||||
appState, _, err := app.ExportAppStateAndValidators(false, nil)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
b.Fail()
|
||||
}
|
||||
err = ioutil.WriteFile(config.ExportStatePath, []byte(appState), 0644)
|
||||
if err != nil {
|
||||
if err := ExportStateToJSON(app, config.ExportStatePath); err != nil {
|
||||
fmt.Println(err)
|
||||
b.Fail()
|
||||
}
|
||||
}
|
||||
|
||||
if config.ExportParamsPath != "" {
|
||||
fmt.Println("Exporting simulation params...")
|
||||
paramsBz, err := json.MarshalIndent(params, "", " ")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
b.Fail()
|
||||
}
|
||||
|
||||
err = ioutil.WriteFile(config.ExportParamsPath, paramsBz, 0644)
|
||||
if err != nil {
|
||||
if err := ExportParamsToJSON(simParams, config.ExportParamsPath); err != nil {
|
||||
fmt.Println(err)
|
||||
b.Fail()
|
||||
}
|
||||
|
|
140
simapp/state.go
140
simapp/state.go
|
@ -1,7 +1,5 @@
|
|||
package simapp
|
||||
|
||||
// DONTCOVER
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
@ -12,71 +10,72 @@ import (
|
|||
"github.com/tendermint/tendermint/crypto/secp256k1"
|
||||
tmtypes "github.com/tendermint/tendermint/types"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
"github.com/cosmos/cosmos-sdk/types/module"
|
||||
"github.com/cosmos/cosmos-sdk/x/genaccounts"
|
||||
nftsim "github.com/cosmos/cosmos-sdk/x/nft/simulation"
|
||||
"github.com/cosmos/cosmos-sdk/x/simulation"
|
||||
)
|
||||
|
||||
// AppStateFn returns the initial application state using a genesis or the simulation parameters.
|
||||
// It panics if the user provides files for both of them.
|
||||
// If a file is not given for the genesis or the sim params, it creates a randomized one.
|
||||
func AppStateFn(
|
||||
r *rand.Rand, accs []simulation.Account, config simulation.Config,
|
||||
) (appState json.RawMessage, simAccs []simulation.Account, chainID string, genesisTimestamp time.Time) {
|
||||
func AppStateFn(cdc *codec.Codec, simManager *module.SimulationManager) simulation.AppStateFn {
|
||||
return func(r *rand.Rand, accs []simulation.Account, config simulation.Config,
|
||||
) (appState json.RawMessage, simAccs []simulation.Account, chainID string, genesisTimestamp time.Time) {
|
||||
|
||||
cdc := MakeCodec()
|
||||
|
||||
if flagGenesisTimeValue == 0 {
|
||||
genesisTimestamp = simulation.RandTimestamp(r)
|
||||
} else {
|
||||
genesisTimestamp = time.Unix(flagGenesisTimeValue, 0)
|
||||
}
|
||||
|
||||
switch {
|
||||
case config.ParamsFile != "" && config.GenesisFile != "":
|
||||
panic("cannot provide both a genesis file and a params file")
|
||||
|
||||
case config.GenesisFile != "":
|
||||
appState, simAccs, chainID = AppStateFromGenesisFileFn(r, config)
|
||||
|
||||
case config.ParamsFile != "":
|
||||
appParams := make(simulation.AppParams)
|
||||
bz, err := ioutil.ReadFile(config.ParamsFile)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
if flagGenesisTimeValue == 0 {
|
||||
genesisTimestamp = simulation.RandTimestamp(r)
|
||||
} else {
|
||||
genesisTimestamp = time.Unix(flagGenesisTimeValue, 0)
|
||||
}
|
||||
|
||||
cdc.MustUnmarshalJSON(bz, &appParams)
|
||||
appState, simAccs, chainID = AppStateRandomizedFn(r, accs, genesisTimestamp, appParams)
|
||||
switch {
|
||||
case config.ParamsFile != "" && config.GenesisFile != "":
|
||||
panic("cannot provide both a genesis file and a params file")
|
||||
|
||||
default:
|
||||
appParams := make(simulation.AppParams)
|
||||
appState, simAccs, chainID = AppStateRandomizedFn(r, accs, genesisTimestamp, appParams)
|
||||
case config.GenesisFile != "":
|
||||
appState, simAccs, chainID = AppStateFromGenesisFileFn(r, cdc, config.GenesisFile)
|
||||
|
||||
case config.ParamsFile != "":
|
||||
appParams := make(simulation.AppParams)
|
||||
bz, err := ioutil.ReadFile(config.ParamsFile)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
cdc.MustUnmarshalJSON(bz, &appParams)
|
||||
appState, simAccs, chainID = AppStateRandomizedFn(simManager, r, cdc, accs, genesisTimestamp, appParams)
|
||||
|
||||
default:
|
||||
appParams := make(simulation.AppParams)
|
||||
appState, simAccs, chainID = AppStateRandomizedFn(simManager, r, cdc, accs, genesisTimestamp, appParams)
|
||||
}
|
||||
|
||||
return appState, simAccs, chainID, genesisTimestamp
|
||||
}
|
||||
|
||||
return appState, simAccs, chainID, genesisTimestamp
|
||||
}
|
||||
|
||||
// AppStateRandomizedFn creates calls each module's GenesisState generator function
|
||||
// and creates
|
||||
// and creates the simulation params
|
||||
func AppStateRandomizedFn(
|
||||
r *rand.Rand, accs []simulation.Account, genesisTimestamp time.Time, appParams simulation.AppParams,
|
||||
simManager *module.SimulationManager, r *rand.Rand, cdc *codec.Codec,
|
||||
accs []simulation.Account, genesisTimestamp time.Time, appParams simulation.AppParams,
|
||||
) (json.RawMessage, []simulation.Account, string) {
|
||||
|
||||
cdc := MakeCodec()
|
||||
numAccs := int64(len(accs))
|
||||
genesisState := NewDefaultGenesisState()
|
||||
|
||||
var (
|
||||
amount int64
|
||||
numInitiallyBonded int64
|
||||
// generate a random amount of initial stake coins and a random initial
|
||||
// number of bonded accounts
|
||||
var initialStake, numInitiallyBonded int64
|
||||
appParams.GetOrGenerate(
|
||||
cdc, StakePerAccount, &initialStake, r,
|
||||
func(r *rand.Rand) { initialStake = int64(r.Intn(1e12)) },
|
||||
)
|
||||
appParams.GetOrGenerate(
|
||||
cdc, InitiallyBondedValidators, &numInitiallyBonded, r,
|
||||
func(r *rand.Rand) { numInitiallyBonded = int64(r.Intn(250)) },
|
||||
)
|
||||
|
||||
appParams.GetOrGenerate(cdc, StakePerAccount, &amount, r,
|
||||
func(r *rand.Rand) { amount = int64(r.Intn(1e12)) })
|
||||
appParams.GetOrGenerate(cdc, InitiallyBondedValidators, &amount, r,
|
||||
func(r *rand.Rand) { numInitiallyBonded = int64(r.Intn(250)) })
|
||||
|
||||
numAccs := int64(len(accs))
|
||||
if numInitiallyBonded > numAccs {
|
||||
numInitiallyBonded = numAccs
|
||||
}
|
||||
|
@ -84,24 +83,26 @@ func AppStateRandomizedFn(
|
|||
fmt.Printf(
|
||||
`Selected randomly generated parameters for simulated genesis:
|
||||
{
|
||||
stake_per_account: "%v",
|
||||
initially_bonded_validators: "%v"
|
||||
stake_per_account: "%d",
|
||||
initially_bonded_validators: "%d"
|
||||
}
|
||||
`, amount, numInitiallyBonded,
|
||||
`, initialStake, numInitiallyBonded,
|
||||
)
|
||||
|
||||
GenGenesisAccounts(cdc, r, accs, genesisTimestamp, amount, numInitiallyBonded, genesisState)
|
||||
GenAuthGenesisState(cdc, r, appParams, genesisState)
|
||||
GenBankGenesisState(cdc, r, appParams, genesisState)
|
||||
GenSupplyGenesisState(cdc, amount, numInitiallyBonded, int64(len(accs)), genesisState)
|
||||
GenGovGenesisState(cdc, r, appParams, genesisState)
|
||||
GenMintGenesisState(cdc, r, appParams, genesisState)
|
||||
nftsim.GenNFTGenesisState(cdc, r, accs, appParams, genesisState)
|
||||
GenDistrGenesisState(cdc, r, appParams, genesisState)
|
||||
stakingGen := GenStakingGenesisState(cdc, r, accs, amount, numAccs, numInitiallyBonded, appParams, genesisState)
|
||||
GenSlashingGenesisState(cdc, r, stakingGen, appParams, genesisState)
|
||||
simState := &module.SimulationState{
|
||||
AppParams: appParams,
|
||||
Cdc: cdc,
|
||||
Rand: r,
|
||||
GenState: genesisState,
|
||||
Accounts: accs,
|
||||
InitialStake: initialStake,
|
||||
NumBonded: numInitiallyBonded,
|
||||
GenTimestamp: genesisTimestamp,
|
||||
}
|
||||
|
||||
appState, err := MakeCodec().MarshalJSON(genesisState)
|
||||
simManager.GenerateGenesisStates(simState)
|
||||
|
||||
appState, err := cdc.MarshalJSON(genesisState)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
@ -111,16 +112,15 @@ func AppStateRandomizedFn(
|
|||
|
||||
// AppStateFromGenesisFileFn util function to generate the genesis AppState
|
||||
// from a genesis.json file
|
||||
func AppStateFromGenesisFileFn(r *rand.Rand, config simulation.Config) (json.RawMessage, []simulation.Account, string) {
|
||||
func AppStateFromGenesisFileFn(r *rand.Rand, cdc *codec.Codec, genesisFile string) (
|
||||
genState json.RawMessage, newAccs []simulation.Account, chainID string) {
|
||||
|
||||
var genesis tmtypes.GenesisDoc
|
||||
cdc := MakeCodec()
|
||||
|
||||
bytes, err := ioutil.ReadFile(config.GenesisFile)
|
||||
bytes, err := ioutil.ReadFile(genesisFile)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
var genesis tmtypes.GenesisDoc
|
||||
cdc.MustUnmarshalJSON(bytes, &genesis)
|
||||
|
||||
var appState GenesisState
|
||||
|
@ -128,16 +128,20 @@ func AppStateFromGenesisFileFn(r *rand.Rand, config simulation.Config) (json.Raw
|
|||
|
||||
accounts := genaccounts.GetGenesisStateFromAppState(cdc, appState)
|
||||
|
||||
var newAccs []simulation.Account
|
||||
for _, acc := range accounts {
|
||||
// Pick a random private key, since we don't know the actual key
|
||||
// This should be fine as it's only used for mock Tendermint validators
|
||||
// and these keys are never actually used to sign by mock Tendermint.
|
||||
privkeySeed := make([]byte, 15)
|
||||
r.Read(privkeySeed)
|
||||
if _, err := r.Read(privkeySeed); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
privKey := secp256k1.GenPrivKeySecp256k1(privkeySeed)
|
||||
newAccs = append(newAccs, simulation.Account{PrivKey: privKey, PubKey: privKey.PubKey(), Address: acc.Address})
|
||||
|
||||
// create simulator accounts
|
||||
simAcc := simulation.Account{PrivKey: privKey, PubKey: privKey.PubKey(), Address: acc.Address}
|
||||
newAccs = append(newAccs, simAcc)
|
||||
}
|
||||
|
||||
return genesis.AppState, newAccs, genesis.ChainID
|
||||
|
|
433
simapp/utils.go
433
simapp/utils.go
|
@ -1,33 +1,22 @@
|
|||
//nolint
|
||||
package simapp
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"time"
|
||||
"io/ioutil"
|
||||
|
||||
cmn "github.com/tendermint/tendermint/libs/common"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||
"github.com/cosmos/cosmos-sdk/x/bank"
|
||||
"github.com/cosmos/cosmos-sdk/x/distribution"
|
||||
"github.com/cosmos/cosmos-sdk/x/genaccounts"
|
||||
"github.com/cosmos/cosmos-sdk/x/gov"
|
||||
"github.com/cosmos/cosmos-sdk/x/mint"
|
||||
"github.com/cosmos/cosmos-sdk/x/simulation"
|
||||
"github.com/cosmos/cosmos-sdk/x/slashing"
|
||||
"github.com/cosmos/cosmos-sdk/x/staking"
|
||||
"github.com/cosmos/cosmos-sdk/x/supply"
|
||||
)
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// Flags
|
||||
|
||||
// List of SimApp flags for the simulator
|
||||
// List of available flags for the simulator
|
||||
var (
|
||||
flagGenesisFileValue string
|
||||
flagParamsFileValue string
|
||||
|
@ -96,405 +85,31 @@ func NewConfigFromFlags() simulation.Config {
|
|||
}
|
||||
}
|
||||
|
||||
// GenAuthGenesisState generates a random GenesisState for auth
|
||||
func GenAuthGenesisState(cdc *codec.Codec, r *rand.Rand, ap simulation.AppParams, genesisState map[string]json.RawMessage) {
|
||||
authGenesis := auth.NewGenesisState(
|
||||
auth.NewParams(
|
||||
func(r *rand.Rand) uint64 {
|
||||
var v uint64
|
||||
ap.GetOrGenerate(cdc, simulation.MaxMemoChars, &v, r,
|
||||
func(r *rand.Rand) {
|
||||
v = simulation.ModuleParamSimulator[simulation.MaxMemoChars](r).(uint64)
|
||||
})
|
||||
return v
|
||||
}(r),
|
||||
func(r *rand.Rand) uint64 {
|
||||
var v uint64
|
||||
ap.GetOrGenerate(cdc, simulation.TxSigLimit, &v, r,
|
||||
func(r *rand.Rand) {
|
||||
v = simulation.ModuleParamSimulator[simulation.TxSigLimit](r).(uint64)
|
||||
})
|
||||
return v
|
||||
}(r),
|
||||
func(r *rand.Rand) uint64 {
|
||||
var v uint64
|
||||
ap.GetOrGenerate(cdc, simulation.TxSizeCostPerByte, &v, r,
|
||||
func(r *rand.Rand) {
|
||||
v = simulation.ModuleParamSimulator[simulation.TxSizeCostPerByte](r).(uint64)
|
||||
})
|
||||
return v
|
||||
}(r),
|
||||
func(r *rand.Rand) uint64 {
|
||||
var v uint64
|
||||
ap.GetOrGenerate(cdc, simulation.SigVerifyCostED25519, &v, r,
|
||||
func(r *rand.Rand) {
|
||||
v = simulation.ModuleParamSimulator[simulation.SigVerifyCostED25519](r).(uint64)
|
||||
})
|
||||
return v
|
||||
}(r),
|
||||
func(r *rand.Rand) uint64 {
|
||||
var v uint64
|
||||
ap.GetOrGenerate(cdc, simulation.SigVerifyCostSECP256K1, &v, r,
|
||||
func(r *rand.Rand) {
|
||||
v = simulation.ModuleParamSimulator[simulation.SigVerifyCostSECP256K1](r).(uint64)
|
||||
})
|
||||
return v
|
||||
}(r),
|
||||
),
|
||||
)
|
||||
|
||||
fmt.Printf("Selected randomly generated auth parameters:\n%s\n", codec.MustMarshalJSONIndent(cdc, authGenesis.Params))
|
||||
genesisState[auth.ModuleName] = cdc.MustMarshalJSON(authGenesis)
|
||||
}
|
||||
|
||||
// GenBankGenesisState generates a random GenesisState for bank
|
||||
func GenBankGenesisState(cdc *codec.Codec, r *rand.Rand, ap simulation.AppParams, genesisState map[string]json.RawMessage) {
|
||||
bankGenesis := bank.NewGenesisState(
|
||||
func(r *rand.Rand) bool {
|
||||
var v bool
|
||||
ap.GetOrGenerate(cdc, simulation.SendEnabled, &v, r,
|
||||
func(r *rand.Rand) {
|
||||
v = simulation.ModuleParamSimulator[simulation.SendEnabled](r).(bool)
|
||||
})
|
||||
return v
|
||||
}(r),
|
||||
)
|
||||
|
||||
fmt.Printf("Selected randomly generated bank parameters:\n%s\n", codec.MustMarshalJSONIndent(cdc, bankGenesis))
|
||||
genesisState[bank.ModuleName] = cdc.MustMarshalJSON(bankGenesis)
|
||||
}
|
||||
|
||||
// GenSupplyGenesisState generates a random GenesisState for supply
|
||||
func GenSupplyGenesisState(cdc *codec.Codec, amount, numInitiallyBonded, numAccs int64, genesisState map[string]json.RawMessage) {
|
||||
totalSupply := sdk.NewInt(amount * (numAccs + numInitiallyBonded))
|
||||
supplyGenesis := supply.NewGenesisState(
|
||||
sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, totalSupply)),
|
||||
)
|
||||
|
||||
fmt.Printf("Generated supply parameters:\n%s\n", codec.MustMarshalJSONIndent(cdc, supplyGenesis))
|
||||
genesisState[supply.ModuleName] = cdc.MustMarshalJSON(supplyGenesis)
|
||||
}
|
||||
|
||||
// GenGenesisAccounts generates a random GenesisState for the genesis accounts
|
||||
func GenGenesisAccounts(
|
||||
cdc *codec.Codec, r *rand.Rand, accs []simulation.Account,
|
||||
genesisTimestamp time.Time, amount, numInitiallyBonded int64,
|
||||
genesisState map[string]json.RawMessage,
|
||||
) {
|
||||
|
||||
var genesisAccounts []genaccounts.GenesisAccount
|
||||
|
||||
// randomly generate some genesis accounts
|
||||
for i, acc := range accs {
|
||||
coins := sdk.Coins{sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(amount))}
|
||||
bacc := auth.NewBaseAccountWithAddress(acc.Address)
|
||||
bacc.SetCoins(coins)
|
||||
|
||||
var gacc genaccounts.GenesisAccount
|
||||
|
||||
// Only consider making a vesting account once the initial bonded validator
|
||||
// set is exhausted due to needing to track DelegatedVesting.
|
||||
if int64(i) > numInitiallyBonded && r.Intn(100) < 50 {
|
||||
var (
|
||||
vacc auth.VestingAccount
|
||||
endTime int64
|
||||
)
|
||||
|
||||
startTime := genesisTimestamp.Unix()
|
||||
|
||||
// Allow for some vesting accounts to vest very quickly while others very slowly.
|
||||
if r.Intn(100) < 50 {
|
||||
endTime = int64(simulation.RandIntBetween(r, int(startTime), int(startTime+(60*60*24*30))))
|
||||
} else {
|
||||
endTime = int64(simulation.RandIntBetween(r, int(startTime), int(startTime+(60*60*12))))
|
||||
}
|
||||
|
||||
if startTime == endTime {
|
||||
endTime++
|
||||
}
|
||||
|
||||
if r.Intn(100) < 50 {
|
||||
vacc = auth.NewContinuousVestingAccount(&bacc, startTime, endTime)
|
||||
} else {
|
||||
vacc = auth.NewDelayedVestingAccount(&bacc, endTime)
|
||||
}
|
||||
|
||||
var err error
|
||||
gacc, err = genaccounts.NewGenesisAccountI(vacc)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
} else {
|
||||
gacc = genaccounts.NewGenesisAccount(&bacc)
|
||||
}
|
||||
|
||||
genesisAccounts = append(genesisAccounts, gacc)
|
||||
}
|
||||
|
||||
genesisState[genaccounts.ModuleName] = cdc.MustMarshalJSON(genesisAccounts)
|
||||
}
|
||||
|
||||
// GenGovGenesisState generates a random GenesisState for gov
|
||||
func GenGovGenesisState(cdc *codec.Codec, r *rand.Rand, ap simulation.AppParams, genesisState map[string]json.RawMessage) {
|
||||
var vp time.Duration
|
||||
ap.GetOrGenerate(cdc, simulation.VotingParamsVotingPeriod, &vp, r,
|
||||
func(r *rand.Rand) {
|
||||
vp = simulation.ModuleParamSimulator[simulation.VotingParamsVotingPeriod](r).(time.Duration)
|
||||
})
|
||||
|
||||
govGenesis := gov.NewGenesisState(
|
||||
uint64(r.Intn(100)),
|
||||
gov.NewDepositParams(
|
||||
func(r *rand.Rand) sdk.Coins {
|
||||
var v sdk.Coins
|
||||
ap.GetOrGenerate(cdc, simulation.DepositParamsMinDeposit, &v, r,
|
||||
func(r *rand.Rand) {
|
||||
v = simulation.ModuleParamSimulator[simulation.DepositParamsMinDeposit](r).(sdk.Coins)
|
||||
})
|
||||
return v
|
||||
}(r),
|
||||
vp,
|
||||
),
|
||||
gov.NewVotingParams(vp),
|
||||
gov.NewTallyParams(
|
||||
func(r *rand.Rand) sdk.Dec {
|
||||
var v sdk.Dec
|
||||
ap.GetOrGenerate(cdc, simulation.TallyParamsQuorum, &v, r,
|
||||
func(r *rand.Rand) {
|
||||
v = simulation.ModuleParamSimulator[simulation.TallyParamsQuorum](r).(sdk.Dec)
|
||||
})
|
||||
return v
|
||||
}(r),
|
||||
func(r *rand.Rand) sdk.Dec {
|
||||
var v sdk.Dec
|
||||
ap.GetOrGenerate(cdc, simulation.TallyParamsThreshold, &v, r,
|
||||
func(r *rand.Rand) {
|
||||
v = simulation.ModuleParamSimulator[simulation.TallyParamsThreshold](r).(sdk.Dec)
|
||||
})
|
||||
return v
|
||||
}(r),
|
||||
func(r *rand.Rand) sdk.Dec {
|
||||
var v sdk.Dec
|
||||
ap.GetOrGenerate(cdc, simulation.TallyParamsVeto, &v, r,
|
||||
func(r *rand.Rand) {
|
||||
v = simulation.ModuleParamSimulator[simulation.TallyParamsVeto](r).(sdk.Dec)
|
||||
})
|
||||
return v
|
||||
}(r),
|
||||
),
|
||||
)
|
||||
|
||||
fmt.Printf("Selected randomly generated governance parameters:\n%s\n", codec.MustMarshalJSONIndent(cdc, govGenesis))
|
||||
genesisState[gov.ModuleName] = cdc.MustMarshalJSON(govGenesis)
|
||||
}
|
||||
|
||||
// GenMintGenesisState generates a random GenesisState for mint
|
||||
func GenMintGenesisState(cdc *codec.Codec, r *rand.Rand, ap simulation.AppParams, genesisState map[string]json.RawMessage) {
|
||||
mintGenesis := mint.NewGenesisState(
|
||||
mint.InitialMinter(
|
||||
func(r *rand.Rand) sdk.Dec {
|
||||
var v sdk.Dec
|
||||
ap.GetOrGenerate(cdc, simulation.Inflation, &v, r,
|
||||
func(r *rand.Rand) {
|
||||
v = simulation.ModuleParamSimulator[simulation.Inflation](r).(sdk.Dec)
|
||||
})
|
||||
return v
|
||||
}(r),
|
||||
),
|
||||
mint.NewParams(
|
||||
sdk.DefaultBondDenom,
|
||||
func(r *rand.Rand) sdk.Dec {
|
||||
var v sdk.Dec
|
||||
ap.GetOrGenerate(cdc, simulation.InflationRateChange, &v, r,
|
||||
func(r *rand.Rand) {
|
||||
v = simulation.ModuleParamSimulator[simulation.InflationRateChange](r).(sdk.Dec)
|
||||
})
|
||||
return v
|
||||
}(r),
|
||||
func(r *rand.Rand) sdk.Dec {
|
||||
var v sdk.Dec
|
||||
ap.GetOrGenerate(cdc, simulation.InflationMax, &v, r,
|
||||
func(r *rand.Rand) {
|
||||
v = simulation.ModuleParamSimulator[simulation.InflationMax](r).(sdk.Dec)
|
||||
})
|
||||
return v
|
||||
}(r),
|
||||
func(r *rand.Rand) sdk.Dec {
|
||||
var v sdk.Dec
|
||||
ap.GetOrGenerate(cdc, simulation.InflationMin, &v, r,
|
||||
func(r *rand.Rand) {
|
||||
v = simulation.ModuleParamSimulator[simulation.InflationMin](r).(sdk.Dec)
|
||||
})
|
||||
return v
|
||||
}(r),
|
||||
func(r *rand.Rand) sdk.Dec {
|
||||
var v sdk.Dec
|
||||
ap.GetOrGenerate(cdc, simulation.GoalBonded, &v, r,
|
||||
func(r *rand.Rand) {
|
||||
v = simulation.ModuleParamSimulator[simulation.GoalBonded](r).(sdk.Dec)
|
||||
})
|
||||
return v
|
||||
}(r),
|
||||
uint64(60*60*8766/5),
|
||||
),
|
||||
)
|
||||
|
||||
fmt.Printf("Selected randomly generated minting parameters:\n%s\n", codec.MustMarshalJSONIndent(cdc, mintGenesis.Params))
|
||||
genesisState[mint.ModuleName] = cdc.MustMarshalJSON(mintGenesis)
|
||||
}
|
||||
|
||||
// GenDistrGenesisState generates a random GenesisState for distribution
|
||||
func GenDistrGenesisState(cdc *codec.Codec, r *rand.Rand, ap simulation.AppParams, genesisState map[string]json.RawMessage) {
|
||||
distrGenesis := distribution.GenesisState{
|
||||
FeePool: distribution.InitialFeePool(),
|
||||
CommunityTax: func(r *rand.Rand) sdk.Dec {
|
||||
var v sdk.Dec
|
||||
ap.GetOrGenerate(cdc, simulation.CommunityTax, &v, r,
|
||||
func(r *rand.Rand) {
|
||||
v = simulation.ModuleParamSimulator[simulation.CommunityTax](r).(sdk.Dec)
|
||||
})
|
||||
return v
|
||||
}(r),
|
||||
BaseProposerReward: func(r *rand.Rand) sdk.Dec {
|
||||
var v sdk.Dec
|
||||
ap.GetOrGenerate(cdc, simulation.BaseProposerReward, &v, r,
|
||||
func(r *rand.Rand) {
|
||||
v = simulation.ModuleParamSimulator[simulation.BaseProposerReward](r).(sdk.Dec)
|
||||
})
|
||||
return v
|
||||
}(r),
|
||||
BonusProposerReward: func(r *rand.Rand) sdk.Dec {
|
||||
var v sdk.Dec
|
||||
ap.GetOrGenerate(cdc, simulation.BonusProposerReward, &v, r,
|
||||
func(r *rand.Rand) {
|
||||
v = simulation.ModuleParamSimulator[simulation.BonusProposerReward](r).(sdk.Dec)
|
||||
})
|
||||
return v
|
||||
}(r),
|
||||
}
|
||||
|
||||
fmt.Printf("Selected randomly generated distribution parameters:\n%s\n", codec.MustMarshalJSONIndent(cdc, distrGenesis))
|
||||
genesisState[distribution.ModuleName] = cdc.MustMarshalJSON(distrGenesis)
|
||||
}
|
||||
|
||||
// GenSlashingGenesisState generates a random GenesisState for slashing
|
||||
func GenSlashingGenesisState(
|
||||
cdc *codec.Codec, r *rand.Rand, stakingGen staking.GenesisState,
|
||||
ap simulation.AppParams, genesisState map[string]json.RawMessage,
|
||||
) {
|
||||
slashingGenesis := slashing.NewGenesisState(
|
||||
slashing.NewParams(
|
||||
stakingGen.Params.UnbondingTime,
|
||||
func(r *rand.Rand) int64 {
|
||||
var v int64
|
||||
ap.GetOrGenerate(cdc, simulation.SignedBlocksWindow, &v, r,
|
||||
func(r *rand.Rand) {
|
||||
v = simulation.ModuleParamSimulator[simulation.SignedBlocksWindow](r).(int64)
|
||||
})
|
||||
return v
|
||||
}(r),
|
||||
func(r *rand.Rand) sdk.Dec {
|
||||
var v sdk.Dec
|
||||
ap.GetOrGenerate(cdc, simulation.MinSignedPerWindow, &v, r,
|
||||
func(r *rand.Rand) {
|
||||
v = simulation.ModuleParamSimulator[simulation.MinSignedPerWindow](r).(sdk.Dec)
|
||||
})
|
||||
return v
|
||||
}(r),
|
||||
func(r *rand.Rand) time.Duration {
|
||||
var v time.Duration
|
||||
ap.GetOrGenerate(cdc, simulation.DowntimeJailDuration, &v, r,
|
||||
func(r *rand.Rand) {
|
||||
v = simulation.ModuleParamSimulator[simulation.DowntimeJailDuration](r).(time.Duration)
|
||||
})
|
||||
return v
|
||||
}(r),
|
||||
func(r *rand.Rand) sdk.Dec {
|
||||
var v sdk.Dec
|
||||
ap.GetOrGenerate(cdc, simulation.SlashFractionDoubleSign, &v, r,
|
||||
func(r *rand.Rand) {
|
||||
v = simulation.ModuleParamSimulator[simulation.SlashFractionDoubleSign](r).(sdk.Dec)
|
||||
})
|
||||
return v
|
||||
}(r),
|
||||
func(r *rand.Rand) sdk.Dec {
|
||||
var v sdk.Dec
|
||||
ap.GetOrGenerate(cdc, simulation.SlashFractionDowntime, &v, r,
|
||||
func(r *rand.Rand) {
|
||||
v = simulation.ModuleParamSimulator[simulation.SlashFractionDowntime](r).(sdk.Dec)
|
||||
})
|
||||
return v
|
||||
}(r),
|
||||
),
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
|
||||
fmt.Printf("Selected randomly generated slashing parameters:\n%s\n", codec.MustMarshalJSONIndent(cdc, slashingGenesis.Params))
|
||||
genesisState[slashing.ModuleName] = cdc.MustMarshalJSON(slashingGenesis)
|
||||
}
|
||||
|
||||
// GenStakingGenesisState generates a random GenesisState for staking
|
||||
func GenStakingGenesisState(
|
||||
cdc *codec.Codec, r *rand.Rand, accs []simulation.Account, amount, numAccs, numInitiallyBonded int64,
|
||||
ap simulation.AppParams, genesisState map[string]json.RawMessage,
|
||||
) staking.GenesisState {
|
||||
|
||||
stakingGenesis := staking.NewGenesisState(
|
||||
staking.NewParams(
|
||||
func(r *rand.Rand) time.Duration {
|
||||
var v time.Duration
|
||||
ap.GetOrGenerate(cdc, simulation.UnbondingTime, &v, r,
|
||||
func(r *rand.Rand) {
|
||||
v = simulation.ModuleParamSimulator[simulation.UnbondingTime](r).(time.Duration)
|
||||
})
|
||||
return v
|
||||
}(r),
|
||||
func(r *rand.Rand) uint16 {
|
||||
var v uint16
|
||||
ap.GetOrGenerate(cdc, simulation.MaxValidators, &v, r,
|
||||
func(r *rand.Rand) {
|
||||
v = simulation.ModuleParamSimulator[simulation.MaxValidators](r).(uint16)
|
||||
})
|
||||
return v
|
||||
}(r),
|
||||
7,
|
||||
sdk.DefaultBondDenom,
|
||||
),
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
|
||||
var (
|
||||
validators []staking.Validator
|
||||
delegations []staking.Delegation
|
||||
)
|
||||
|
||||
valAddrs := make([]sdk.ValAddress, numInitiallyBonded)
|
||||
for i := 0; i < int(numInitiallyBonded); i++ {
|
||||
valAddr := sdk.ValAddress(accs[i].Address)
|
||||
valAddrs[i] = valAddr
|
||||
|
||||
validator := staking.NewValidator(valAddr, accs[i].PubKey, staking.Description{})
|
||||
validator.Tokens = sdk.NewInt(amount)
|
||||
validator.DelegatorShares = sdk.NewDec(amount)
|
||||
delegation := staking.NewDelegation(accs[i].Address, valAddr, sdk.NewDec(amount))
|
||||
validators = append(validators, validator)
|
||||
delegations = append(delegations, delegation)
|
||||
}
|
||||
|
||||
stakingGenesis.Validators = validators
|
||||
stakingGenesis.Delegations = delegations
|
||||
|
||||
fmt.Printf("Selected randomly generated staking parameters:\n%s\n", codec.MustMarshalJSONIndent(cdc, stakingGenesis.Params))
|
||||
genesisState[staking.ModuleName] = cdc.MustMarshalJSON(stakingGenesis)
|
||||
|
||||
return stakingGenesis
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// Simulation Utils
|
||||
|
||||
// ExportStateToJSON util function to export the app state to JSON
|
||||
func ExportStateToJSON(app *SimApp, path string) error {
|
||||
fmt.Println("exporting app state...")
|
||||
appState, _, err := app.ExportAppStateAndValidators(false, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return ioutil.WriteFile(path, []byte(appState), 0644)
|
||||
}
|
||||
|
||||
// ExportParamsToJSON util function to export the simulation parameters to JSON
|
||||
func ExportParamsToJSON(params simulation.Params, path string) error {
|
||||
fmt.Println("exporting simulation params...")
|
||||
paramsBz, err := json.MarshalIndent(params, "", " ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return ioutil.WriteFile(path, paramsBz, 0644)
|
||||
}
|
||||
|
||||
// GetSimulationLog unmarshals the KVPair's Value to the corresponding type based on the
|
||||
// each's module store key and the prefix bytes of the KVPair's key.
|
||||
func GetSimulationLog(storeName string, sdr sdk.StoreDecoderRegistry, cdc *codec.Codec, kvAs, kvBs []cmn.KVPair) (log string) {
|
||||
|
|
|
@ -15,16 +15,8 @@ import (
|
|||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
func makeTestCodec() (cdc *codec.Codec) {
|
||||
cdc = codec.New()
|
||||
sdk.RegisterCodec(cdc)
|
||||
codec.RegisterCrypto(cdc)
|
||||
auth.RegisterCodec(cdc)
|
||||
return
|
||||
}
|
||||
|
||||
func TestGetSimulationLog(t *testing.T) {
|
||||
cdc := makeTestCodec()
|
||||
cdc := MakeCodec()
|
||||
|
||||
decoders := make(sdk.StoreDecoderRegistry)
|
||||
decoders[auth.StoreKey] = func(cdc *codec.Codec, kvAs, kvBs cmn.KVPair) string { return "10" }
|
||||
|
|
|
@ -130,17 +130,9 @@ type AppModuleGenesis interface {
|
|||
ExportGenesis(sdk.Context) json.RawMessage
|
||||
}
|
||||
|
||||
// AppModuleSimulation defines the standard functions that every module should expose
|
||||
// for the SDK blockchain simulator
|
||||
type AppModuleSimulation interface {
|
||||
// register a func to decode the each module's defined types from their corresponding store key
|
||||
RegisterStoreDecoder(sdk.StoreDecoderRegistry)
|
||||
}
|
||||
|
||||
// AppModule is the standard form for an application module
|
||||
type AppModule interface {
|
||||
AppModuleGenesis
|
||||
AppModuleSimulation
|
||||
|
||||
// registers
|
||||
RegisterInvariants(sdk.InvariantRegistry)
|
||||
|
@ -173,9 +165,6 @@ func NewGenesisOnlyAppModule(amg AppModuleGenesis) AppModule {
|
|||
// RegisterInvariants is a placeholder function register no invariants
|
||||
func (GenesisOnlyAppModule) RegisterInvariants(_ sdk.InvariantRegistry) {}
|
||||
|
||||
// RegisterStoreDecoder empty store decoder registry
|
||||
func (GenesisOnlyAppModule) RegisterStoreDecoder(_ sdk.StoreDecoderRegistry) {}
|
||||
|
||||
// Route empty module message route
|
||||
func (GenesisOnlyAppModule) Route() string { return "" }
|
||||
|
||||
|
|
|
@ -1,20 +1,41 @@
|
|||
package module
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"math/rand"
|
||||
"time"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/simulation"
|
||||
)
|
||||
|
||||
// AppModuleSimulation defines the standard functions that every module should expose
|
||||
// for the SDK blockchain simulator
|
||||
type AppModuleSimulation interface {
|
||||
// register a func to decode the each module's defined types from their corresponding store key
|
||||
RegisterStoreDecoder(sdk.StoreDecoderRegistry)
|
||||
|
||||
// randomized genesis states
|
||||
GenerateGenesisState(input *SimulationState)
|
||||
|
||||
// randomized module parameters for param change proposals
|
||||
RandomizedParams(r *rand.Rand) []simulation.ParamChange
|
||||
}
|
||||
|
||||
// SimulationManager defines a simulation manager that provides the high level utility
|
||||
// for managing and executing simulation functionalities for a group of modules
|
||||
type SimulationManager struct {
|
||||
Modules map[string]AppModule
|
||||
StoreDecoders sdk.StoreDecoderRegistry
|
||||
Modules []AppModuleSimulation // array of app modules; we use an array for deterministic simulation tests
|
||||
StoreDecoders sdk.StoreDecoderRegistry // functions to decode the key-value pairs from each module's store
|
||||
}
|
||||
|
||||
// NewSimulationManager creates a new SimulationManager object
|
||||
func NewSimulationManager(moduleMap map[string]AppModule) *SimulationManager {
|
||||
//
|
||||
// CONTRACT: All the modules provided must be also registered on the module Manager
|
||||
func NewSimulationManager(modules ...AppModuleSimulation) *SimulationManager {
|
||||
return &SimulationManager{
|
||||
Modules: moduleMap,
|
||||
Modules: modules,
|
||||
StoreDecoders: make(sdk.StoreDecoderRegistry),
|
||||
}
|
||||
}
|
||||
|
@ -25,3 +46,37 @@ func (sm *SimulationManager) RegisterStoreDecoders() {
|
|||
module.RegisterStoreDecoder(sm.StoreDecoders)
|
||||
}
|
||||
}
|
||||
|
||||
// GenerateGenesisStates generates a randomized GenesisState for each of the
|
||||
// registered modules
|
||||
func (sm *SimulationManager) GenerateGenesisStates(input *SimulationState) {
|
||||
for _, module := range sm.Modules {
|
||||
module.GenerateGenesisState(input)
|
||||
}
|
||||
}
|
||||
|
||||
// GenerateParamChanges generates randomized contents for creating params change
|
||||
// proposal transactions
|
||||
func (sm *SimulationManager) GenerateParamChanges(seed int64) (paramChanges []simulation.ParamChange) {
|
||||
r := rand.New(rand.NewSource(seed))
|
||||
|
||||
for _, module := range sm.Modules {
|
||||
paramChanges = append(paramChanges, module.RandomizedParams(r)...)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// SimulationState is the input parameters used on each of the module's randomized
|
||||
// GenesisState generator function
|
||||
type SimulationState struct {
|
||||
AppParams simulation.AppParams
|
||||
Cdc *codec.Codec // application codec
|
||||
Rand *rand.Rand // random number
|
||||
GenState map[string]json.RawMessage // genesis state
|
||||
Accounts []simulation.Account // simulation accounts
|
||||
InitialStake int64 // initial coins per account
|
||||
NumBonded int64 // number of initially bonded acconts
|
||||
GenTimestamp time.Time // genesis timestamp
|
||||
UnbondTime time.Duration // staking unbond time stored to use it as the slashing maximum evidence duration
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ package auth
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"math/rand"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/spf13/cobra"
|
||||
|
@ -15,6 +16,7 @@ import (
|
|||
"github.com/cosmos/cosmos-sdk/x/auth/client/rest"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth/simulation"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||
sim "github.com/cosmos/cosmos-sdk/x/simulation"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -77,6 +79,16 @@ func (AppModuleSimulation) RegisterStoreDecoder(sdr sdk.StoreDecoderRegistry) {
|
|||
sdr[StoreKey] = simulation.DecodeStore
|
||||
}
|
||||
|
||||
// GenerateGenesisState creates a randomized GenState of the auth module
|
||||
func (AppModuleSimulation) GenerateGenesisState(simState *module.SimulationState) {
|
||||
simulation.RandomizedGenState(simState)
|
||||
}
|
||||
|
||||
// RandomizedParams creates randomized auth param changes for the simulator.
|
||||
func (AppModuleSimulation) RandomizedParams(r *rand.Rand) []sim.ParamChange {
|
||||
return simulation.ParamChanges(r)
|
||||
}
|
||||
|
||||
//____________________________________________________________________________
|
||||
|
||||
// AppModule implements an application module for the auth module.
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
package simulation
|
||||
|
||||
// DONTCOVER
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
"github.com/cosmos/cosmos-sdk/types/module"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/simulation"
|
||||
)
|
||||
|
||||
// Simulation parameter constants
|
||||
const (
|
||||
MaxMemoChars = "max_memo_characters"
|
||||
TxSigLimit = "tx_sig_limit"
|
||||
TxSizeCostPerByte = "tx_size_cost_per_byte"
|
||||
SigVerifyCostED25519 = "sig_verify_cost_ed25519"
|
||||
SigVerifyCostSECP256K1 = "sig_verify_cost_secp256k1"
|
||||
)
|
||||
|
||||
// GenMaxMemoChars randomized MaxMemoChars
|
||||
func GenMaxMemoChars(r *rand.Rand) uint64 {
|
||||
return uint64(simulation.RandIntBetween(r, 100, 200))
|
||||
}
|
||||
|
||||
// GenTxSigLimit randomized TxSigLimit
|
||||
func GenTxSigLimit(r *rand.Rand) uint64 {
|
||||
return uint64(r.Intn(7) + 1)
|
||||
}
|
||||
|
||||
// GenTxSizeCostPerByte randomized TxSizeCostPerByte
|
||||
func GenTxSizeCostPerByte(r *rand.Rand) uint64 {
|
||||
return uint64(simulation.RandIntBetween(r, 5, 15))
|
||||
}
|
||||
|
||||
// GenSigVerifyCostED25519 randomized SigVerifyCostED25519
|
||||
func GenSigVerifyCostED25519(r *rand.Rand) uint64 {
|
||||
return uint64(simulation.RandIntBetween(r, 500, 1000))
|
||||
}
|
||||
|
||||
// GenSigVerifyCostSECP256K1 randomized SigVerifyCostSECP256K1
|
||||
func GenSigVerifyCostSECP256K1(r *rand.Rand) uint64 {
|
||||
return uint64(simulation.RandIntBetween(r, 500, 1000))
|
||||
}
|
||||
|
||||
// RandomizedGenState generates a random GenesisState for auth
|
||||
func RandomizedGenState(simState *module.SimulationState) {
|
||||
var maxMemoChars uint64
|
||||
simState.AppParams.GetOrGenerate(
|
||||
simState.Cdc, MaxMemoChars, &maxMemoChars, simState.Rand,
|
||||
func(r *rand.Rand) { maxMemoChars = GenMaxMemoChars(r) },
|
||||
)
|
||||
|
||||
var txSigLimit uint64
|
||||
simState.AppParams.GetOrGenerate(
|
||||
simState.Cdc, TxSigLimit, &txSigLimit, simState.Rand,
|
||||
func(r *rand.Rand) { txSigLimit = GenTxSigLimit(r) },
|
||||
)
|
||||
|
||||
var txSizeCostPerByte uint64
|
||||
simState.AppParams.GetOrGenerate(
|
||||
simState.Cdc, TxSizeCostPerByte, &txSizeCostPerByte, simState.Rand,
|
||||
func(r *rand.Rand) { txSizeCostPerByte = GenTxSizeCostPerByte(r) },
|
||||
)
|
||||
|
||||
var sigVerifyCostED25519 uint64
|
||||
simState.AppParams.GetOrGenerate(
|
||||
simState.Cdc, SigVerifyCostED25519, &sigVerifyCostED25519, simState.Rand,
|
||||
func(r *rand.Rand) { sigVerifyCostED25519 = GenSigVerifyCostED25519(r) },
|
||||
)
|
||||
|
||||
var sigVerifyCostSECP256K1 uint64
|
||||
simState.AppParams.GetOrGenerate(
|
||||
simState.Cdc, SigVerifyCostSECP256K1, &sigVerifyCostSECP256K1, simState.Rand,
|
||||
func(r *rand.Rand) { sigVerifyCostED25519 = GenSigVerifyCostSECP256K1(r) },
|
||||
)
|
||||
|
||||
authGenesis := types.NewGenesisState(
|
||||
types.NewParams(maxMemoChars, txSigLimit, txSizeCostPerByte,
|
||||
sigVerifyCostED25519, sigVerifyCostSECP256K1),
|
||||
)
|
||||
|
||||
fmt.Printf("Selected randomly generated auth parameters:\n%s\n", codec.MustMarshalJSONIndent(simState.Cdc, authGenesis.Params))
|
||||
simState.GenState[types.ModuleName] = simState.Cdc.MustMarshalJSON(authGenesis)
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
package simulation
|
||||
|
||||
// DONTCOVER
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/simulation"
|
||||
)
|
||||
|
||||
const (
|
||||
keyMaxMemoCharacters = "MaxMemoCharacters"
|
||||
keyTxSigLimit = "TxSigLimit"
|
||||
keyTxSizeCostPerByte = "TxSizeCostPerByte"
|
||||
)
|
||||
|
||||
// ParamChanges defines the parameters that can be modified by param change proposals
|
||||
// on the simulation
|
||||
func ParamChanges(r *rand.Rand) []simulation.ParamChange {
|
||||
return []simulation.ParamChange{
|
||||
simulation.NewSimParamChange(types.ModuleName, keyMaxMemoCharacters, "",
|
||||
func(r *rand.Rand) string {
|
||||
return fmt.Sprintf("\"%d\"", GenMaxMemoChars(r))
|
||||
},
|
||||
),
|
||||
simulation.NewSimParamChange(types.ModuleName, keyTxSigLimit, "",
|
||||
func(r *rand.Rand) string {
|
||||
return fmt.Sprintf("\"%d\"", GenTxSigLimit(r))
|
||||
},
|
||||
),
|
||||
simulation.NewSimParamChange(types.ModuleName, keyTxSizeCostPerByte, "",
|
||||
func(r *rand.Rand) string {
|
||||
return fmt.Sprintf("\"%d\"", GenTxSizeCostPerByte(r))
|
||||
},
|
||||
),
|
||||
}
|
||||
}
|
|
@ -1,7 +1,8 @@
|
|||
// nolint
|
||||
// autogenerated code using github.com/rigelrozanski/multitool
|
||||
// aliases generated for the following subdirectories:
|
||||
// ALIASGEN: github.com/cosmos/cosmos-sdk/x/bank/types
|
||||
// ALIASGEN: github.com/cosmos/cosmos-sdk/x/bank/internal/keeper
|
||||
// ALIASGEN: github.com/cosmos/cosmos-sdk/x/bank/internal/types
|
||||
package bank
|
||||
|
||||
import (
|
||||
|
@ -10,26 +11,40 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
QueryBalance = keeper.QueryBalance
|
||||
DefaultCodespace = types.DefaultCodespace
|
||||
CodeSendDisabled = types.CodeSendDisabled
|
||||
CodeInvalidInputsOutputs = types.CodeInvalidInputsOutputs
|
||||
ModuleName = types.ModuleName
|
||||
RouterKey = types.RouterKey
|
||||
QuerierRoute = types.QuerierRoute
|
||||
RouterKey = types.RouterKey
|
||||
DefaultParamspace = types.DefaultParamspace
|
||||
DefaultSendEnabled = types.DefaultSendEnabled
|
||||
)
|
||||
|
||||
var (
|
||||
// functions aliases
|
||||
RegisterCodec = types.RegisterCodec
|
||||
ErrNoInputs = types.ErrNoInputs
|
||||
ErrNoOutputs = types.ErrNoOutputs
|
||||
ErrInputOutputMismatch = types.ErrInputOutputMismatch
|
||||
ErrSendDisabled = types.ErrSendDisabled
|
||||
NewBaseKeeper = keeper.NewBaseKeeper
|
||||
NewInput = types.NewInput
|
||||
NewOutput = types.NewOutput
|
||||
ParamKeyTable = types.ParamKeyTable
|
||||
RegisterInvariants = keeper.RegisterInvariants
|
||||
NonnegativeBalanceInvariant = keeper.NonnegativeBalanceInvariant
|
||||
NewBaseKeeper = keeper.NewBaseKeeper
|
||||
NewBaseSendKeeper = keeper.NewBaseSendKeeper
|
||||
NewBaseViewKeeper = keeper.NewBaseViewKeeper
|
||||
NewQuerier = keeper.NewQuerier
|
||||
RegisterCodec = types.RegisterCodec
|
||||
ErrNoInputs = types.ErrNoInputs
|
||||
ErrNoOutputs = types.ErrNoOutputs
|
||||
ErrInputOutputMismatch = types.ErrInputOutputMismatch
|
||||
ErrSendDisabled = types.ErrSendDisabled
|
||||
NewGenesisState = types.NewGenesisState
|
||||
DefaultGenesisState = types.DefaultGenesisState
|
||||
ValidateGenesis = types.ValidateGenesis
|
||||
NewMsgSend = types.NewMsgSend
|
||||
NewMsgMultiSend = types.NewMsgMultiSend
|
||||
NewInput = types.NewInput
|
||||
NewOutput = types.NewOutput
|
||||
ValidateInputsOutputs = types.ValidateInputsOutputs
|
||||
ParamKeyTable = types.ParamKeyTable
|
||||
NewQueryBalanceParams = types.NewQueryBalanceParams
|
||||
|
||||
// variable aliases
|
||||
ModuleCdc = types.ModuleCdc
|
||||
|
@ -37,10 +52,16 @@ var (
|
|||
)
|
||||
|
||||
type (
|
||||
BaseKeeper = keeper.BaseKeeper // ibc module depends on this
|
||||
Keeper = keeper.Keeper
|
||||
MsgSend = types.MsgSend
|
||||
MsgMultiSend = types.MsgMultiSend
|
||||
Input = types.Input
|
||||
Output = types.Output
|
||||
Keeper = keeper.Keeper
|
||||
BaseKeeper = keeper.BaseKeeper
|
||||
SendKeeper = keeper.SendKeeper
|
||||
BaseSendKeeper = keeper.BaseSendKeeper
|
||||
ViewKeeper = keeper.ViewKeeper
|
||||
BaseViewKeeper = keeper.BaseViewKeeper
|
||||
GenesisState = types.GenesisState
|
||||
MsgSend = types.MsgSend
|
||||
MsgMultiSend = types.MsgMultiSend
|
||||
Input = types.Input
|
||||
Output = types.Output
|
||||
QueryBalanceParams = types.QueryBalanceParams
|
||||
)
|
||||
|
|
|
@ -4,19 +4,6 @@ import (
|
|||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
// GenesisState is the bank state that must be provided at genesis.
|
||||
type GenesisState struct {
|
||||
SendEnabled bool `json:"send_enabled" yaml:"send_enabled"`
|
||||
}
|
||||
|
||||
// NewGenesisState creates a new genesis state.
|
||||
func NewGenesisState(sendEnabled bool) GenesisState {
|
||||
return GenesisState{SendEnabled: sendEnabled}
|
||||
}
|
||||
|
||||
// DefaultGenesisState returns a default genesis state
|
||||
func DefaultGenesisState() GenesisState { return NewGenesisState(true) }
|
||||
|
||||
// InitGenesis sets distribution information for genesis.
|
||||
func InitGenesis(ctx sdk.Context, keeper Keeper, data GenesisState) {
|
||||
keeper.SetSendEnabled(ctx, data.SendEnabled)
|
||||
|
@ -26,7 +13,3 @@ func InitGenesis(ctx sdk.Context, keeper Keeper, data GenesisState) {
|
|||
func ExportGenesis(ctx sdk.Context, keeper Keeper) GenesisState {
|
||||
return NewGenesisState(keeper.GetSendEnabled(ctx))
|
||||
}
|
||||
|
||||
// ValidateGenesis performs basic validation of bank genesis data returning an
|
||||
// error for any failed validation criteria.
|
||||
func ValidateGenesis(data GenesisState) error { return nil }
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
package types
|
||||
|
||||
// GenesisState is the bank state that must be provided at genesis.
|
||||
type GenesisState struct {
|
||||
SendEnabled bool `json:"send_enabled" yaml:"send_enabled"`
|
||||
}
|
||||
|
||||
// NewGenesisState creates a new genesis state.
|
||||
func NewGenesisState(sendEnabled bool) GenesisState {
|
||||
return GenesisState{SendEnabled: sendEnabled}
|
||||
}
|
||||
|
||||
// DefaultGenesisState returns a default genesis state
|
||||
func DefaultGenesisState() GenesisState { return NewGenesisState(true) }
|
||||
|
||||
// ValidateGenesis performs basic validation of bank genesis data returning an
|
||||
// error for any failed validation criteria.
|
||||
func ValidateGenesis(data GenesisState) error { return nil }
|
|
@ -2,6 +2,7 @@ package bank
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"math/rand"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/spf13/cobra"
|
||||
|
@ -16,6 +17,8 @@ import (
|
|||
"github.com/cosmos/cosmos-sdk/x/bank/client/rest"
|
||||
"github.com/cosmos/cosmos-sdk/x/bank/internal/keeper"
|
||||
"github.com/cosmos/cosmos-sdk/x/bank/internal/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/bank/simulation"
|
||||
sim "github.com/cosmos/cosmos-sdk/x/simulation"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -70,6 +73,16 @@ type AppModuleSimulation struct{}
|
|||
// RegisterStoreDecoder performs a no-op.
|
||||
func (AppModuleSimulation) RegisterStoreDecoder(_ sdk.StoreDecoderRegistry) {}
|
||||
|
||||
// GenerateGenesisState creates a randomized GenState of the bank module.
|
||||
func (AppModuleSimulation) GenerateGenesisState(simState *module.SimulationState) {
|
||||
simulation.RandomizedGenState(simState)
|
||||
}
|
||||
|
||||
// RandomizedParams creates randomized bank param changes for the simulator.
|
||||
func (AppModuleSimulation) RandomizedParams(r *rand.Rand) []sim.ParamChange {
|
||||
return simulation.ParamChanges(r)
|
||||
}
|
||||
|
||||
//____________________________________________________________________________
|
||||
|
||||
// AppModule implements an application module for the bank module.
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
package simulation
|
||||
|
||||
// DONTCOVER
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
"github.com/cosmos/cosmos-sdk/types/module"
|
||||
"github.com/cosmos/cosmos-sdk/x/bank/internal/types"
|
||||
)
|
||||
|
||||
// Simulation parameter constants
|
||||
const (
|
||||
SendEnabled = "send_enabled"
|
||||
)
|
||||
|
||||
// GenSendEnabled randomized SendEnabled
|
||||
func GenSendEnabled(r *rand.Rand) bool {
|
||||
return r.Int63n(2) == 0
|
||||
}
|
||||
|
||||
// RandomizedGenState generates a random GenesisState for bank
|
||||
func RandomizedGenState(simState *module.SimulationState) {
|
||||
var sendEnabled bool
|
||||
simState.AppParams.GetOrGenerate(
|
||||
simState.Cdc, SendEnabled, &sendEnabled, simState.Rand,
|
||||
func(r *rand.Rand) { sendEnabled = GenSendEnabled(r) },
|
||||
)
|
||||
|
||||
bankGenesis := types.NewGenesisState(sendEnabled)
|
||||
|
||||
fmt.Printf("Selected randomly generated bank parameters:\n%s\n", codec.MustMarshalJSONIndent(simState.Cdc, bankGenesis))
|
||||
simState.GenState[types.ModuleName] = simState.Cdc.MustMarshalJSON(bankGenesis)
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package simulation
|
||||
|
||||
// DONTCOVER
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/x/bank/internal/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/simulation"
|
||||
)
|
||||
|
||||
const keySendEnabled = "sendenabled"
|
||||
|
||||
// ParamChanges defines the parameters that can be modified by param change proposals
|
||||
// on the simulation
|
||||
func ParamChanges(r *rand.Rand) []simulation.ParamChange {
|
||||
return []simulation.ParamChange{
|
||||
simulation.NewSimParamChange(types.ModuleName, keySendEnabled, "",
|
||||
func(r *rand.Rand) string {
|
||||
return fmt.Sprintf("%v", GenSendEnabled(r))
|
||||
},
|
||||
),
|
||||
}
|
||||
}
|
|
@ -18,9 +18,8 @@ import (
|
|||
)
|
||||
|
||||
var (
|
||||
_ module.AppModule = AppModule{}
|
||||
_ module.AppModuleBasic = AppModuleBasic{}
|
||||
_ module.AppModuleSimulation = AppModuleSimulation{}
|
||||
_ module.AppModule = AppModule{}
|
||||
_ module.AppModuleBasic = AppModuleBasic{}
|
||||
)
|
||||
|
||||
// AppModuleBasic defines the basic application module used by the crisis module.
|
||||
|
@ -64,18 +63,9 @@ func (AppModuleBasic) GetQueryCmd(_ *codec.Codec) *cobra.Command { return nil }
|
|||
|
||||
//____________________________________________________________________________
|
||||
|
||||
// AppModuleSimulation defines the module simulation functions used by the crisis module.
|
||||
type AppModuleSimulation struct{}
|
||||
|
||||
// RegisterStoreDecoder performs a no-op.
|
||||
func (AppModuleSimulation) RegisterStoreDecoder(_ sdk.StoreDecoderRegistry) {}
|
||||
|
||||
//____________________________________________________________________________
|
||||
|
||||
// AppModule implements an application module for the crisis module.
|
||||
type AppModule struct {
|
||||
AppModuleBasic
|
||||
AppModuleSimulation
|
||||
|
||||
// NOTE: We store a reference to the keeper here so that after a module
|
||||
// manager is created, the invariants can be properly registered and
|
||||
|
@ -86,9 +76,8 @@ type AppModule struct {
|
|||
// NewAppModule creates a new AppModule object
|
||||
func NewAppModule(keeper *keeper.Keeper) AppModule {
|
||||
return AppModule{
|
||||
AppModuleBasic: AppModuleBasic{},
|
||||
AppModuleSimulation: AppModuleSimulation{},
|
||||
keeper: keeper,
|
||||
AppModuleBasic: AppModuleBasic{},
|
||||
keeper: keeper,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ package distribution
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"math/rand"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/spf13/cobra"
|
||||
|
@ -16,6 +17,7 @@ import (
|
|||
"github.com/cosmos/cosmos-sdk/x/distribution/client/rest"
|
||||
"github.com/cosmos/cosmos-sdk/x/distribution/simulation"
|
||||
"github.com/cosmos/cosmos-sdk/x/distribution/types"
|
||||
sim "github.com/cosmos/cosmos-sdk/x/simulation"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -78,6 +80,16 @@ func (AppModuleSimulation) RegisterStoreDecoder(sdr sdk.StoreDecoderRegistry) {
|
|||
sdr[StoreKey] = simulation.DecodeStore
|
||||
}
|
||||
|
||||
// GenerateGenesisState creates a randomized GenState of the distribution module.
|
||||
func (AppModuleSimulation) GenerateGenesisState(simState *module.SimulationState) {
|
||||
simulation.RandomizedGenState(simState)
|
||||
}
|
||||
|
||||
// RandomizedParams creates randomized distribution param changes for the simulator.
|
||||
func (AppModuleSimulation) RandomizedParams(r *rand.Rand) []sim.ParamChange {
|
||||
return simulation.ParamChanges(r)
|
||||
}
|
||||
|
||||
//____________________________________________________________________________
|
||||
|
||||
// AppModule implements an application module for the distribution module.
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
package simulation
|
||||
|
||||
// DONTCOVER
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/module"
|
||||
"github.com/cosmos/cosmos-sdk/x/distribution/types"
|
||||
)
|
||||
|
||||
// Simulation parameter constants
|
||||
const (
|
||||
CommunityTax = "community_tax"
|
||||
BaseProposerReward = "base_proposer_reward"
|
||||
BonusProposerReward = "bonus_proposer_reward"
|
||||
)
|
||||
|
||||
// GenCommunityTax randomized CommunityTax
|
||||
func GenCommunityTax(r *rand.Rand) sdk.Dec {
|
||||
return sdk.NewDecWithPrec(1, 2).Add(sdk.NewDecWithPrec(int64(r.Intn(30)), 2))
|
||||
}
|
||||
|
||||
// GenBaseProposerReward randomized BaseProposerReward
|
||||
func GenBaseProposerReward(r *rand.Rand) sdk.Dec {
|
||||
return sdk.NewDecWithPrec(1, 2).Add(sdk.NewDecWithPrec(int64(r.Intn(30)), 2))
|
||||
}
|
||||
|
||||
// GenBonusProposerReward randomized BonusProposerReward
|
||||
func GenBonusProposerReward(r *rand.Rand) sdk.Dec {
|
||||
return sdk.NewDecWithPrec(1, 2).Add(sdk.NewDecWithPrec(int64(r.Intn(30)), 2))
|
||||
}
|
||||
|
||||
// RandomizedGenState generates a random GenesisState for distribution
|
||||
func RandomizedGenState(simState *module.SimulationState) {
|
||||
var communityTax sdk.Dec
|
||||
simState.AppParams.GetOrGenerate(
|
||||
simState.Cdc, CommunityTax, &communityTax, simState.Rand,
|
||||
func(r *rand.Rand) { communityTax = GenCommunityTax(r) },
|
||||
)
|
||||
|
||||
var baseProposerReward sdk.Dec
|
||||
simState.AppParams.GetOrGenerate(
|
||||
simState.Cdc, BaseProposerReward, &baseProposerReward, simState.Rand,
|
||||
func(r *rand.Rand) { baseProposerReward = GenBaseProposerReward(r) },
|
||||
)
|
||||
|
||||
var bonusProposerReward sdk.Dec
|
||||
simState.AppParams.GetOrGenerate(
|
||||
simState.Cdc, BonusProposerReward, &bonusProposerReward, simState.Rand,
|
||||
func(r *rand.Rand) { bonusProposerReward = GenBonusProposerReward(r) },
|
||||
)
|
||||
|
||||
distrGenesis := types.GenesisState{
|
||||
FeePool: types.InitialFeePool(),
|
||||
CommunityTax: communityTax,
|
||||
BaseProposerReward: baseProposerReward,
|
||||
BonusProposerReward: bonusProposerReward,
|
||||
}
|
||||
|
||||
fmt.Printf("Selected randomly generated distribution parameters:\n%s\n", codec.MustMarshalJSONIndent(simState.Cdc, distrGenesis))
|
||||
simState.GenState[types.ModuleName] = simState.Cdc.MustMarshalJSON(distrGenesis)
|
||||
}
|
|
@ -7,8 +7,8 @@ import (
|
|||
"github.com/cosmos/cosmos-sdk/baseapp"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/distribution"
|
||||
"github.com/cosmos/cosmos-sdk/x/gov"
|
||||
govsimops "github.com/cosmos/cosmos-sdk/x/gov/simulation/operations"
|
||||
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/simulation"
|
||||
)
|
||||
|
||||
|
@ -88,18 +88,22 @@ func SimulateMsgWithdrawValidatorCommission(k distribution.Keeper) simulation.Op
|
|||
|
||||
// SimulateCommunityPoolSpendProposalContent generates random community-pool-spend proposal content
|
||||
func SimulateCommunityPoolSpendProposalContent(k distribution.Keeper) govsimops.ContentSimulator {
|
||||
return func(r *rand.Rand, _ *baseapp.BaseApp, ctx sdk.Context, accs []simulation.Account) gov.Content {
|
||||
return func(r *rand.Rand, ctx sdk.Context, accs []simulation.Account) govtypes.Content {
|
||||
var coins sdk.Coins
|
||||
|
||||
recipientAcc := simulation.RandomAcc(r, accs)
|
||||
coins := sdk.Coins{}
|
||||
balance := k.GetFeePool(ctx).CommunityPool
|
||||
|
||||
if len(balance) > 0 {
|
||||
denomIndex := r.Intn(len(balance))
|
||||
amount, goErr := simulation.RandPositiveInt(r, balance[denomIndex].Amount.TruncateInt())
|
||||
if goErr == nil {
|
||||
amount, err := simulation.RandPositiveInt(r, balance[denomIndex].Amount.TruncateInt())
|
||||
|
||||
if err == nil {
|
||||
denom := balance[denomIndex].Denom
|
||||
coins = sdk.NewCoins(sdk.NewCoin(denom, amount.Mul(sdk.NewInt(2))))
|
||||
}
|
||||
}
|
||||
|
||||
return distribution.NewCommunityPoolSpendProposal(
|
||||
simulation.RandStringOfLength(r, 10),
|
||||
simulation.RandStringOfLength(r, 100),
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
package simulation
|
||||
|
||||
// DONTCOVER
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/x/distribution/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/simulation"
|
||||
)
|
||||
|
||||
const (
|
||||
keyCommunityTax = "communitytax"
|
||||
keyBaseProposerReward = "baseproposerreward"
|
||||
keyBonusProposerReward = "bonusproposerreward"
|
||||
)
|
||||
|
||||
// ParamChanges defines the parameters that can be modified by param change proposals
|
||||
// on the simulation
|
||||
func ParamChanges(r *rand.Rand) []simulation.ParamChange {
|
||||
return []simulation.ParamChange{
|
||||
simulation.NewSimParamChange(types.ModuleName, keyCommunityTax, "",
|
||||
func(r *rand.Rand) string {
|
||||
return fmt.Sprintf("\"%s\"", GenCommunityTax(r))
|
||||
},
|
||||
),
|
||||
simulation.NewSimParamChange(types.ModuleName, keyBaseProposerReward, "",
|
||||
func(r *rand.Rand) string {
|
||||
return fmt.Sprintf("\"%s\"", GenBaseProposerReward(r))
|
||||
},
|
||||
),
|
||||
simulation.NewSimParamChange(types.ModuleName, keyBonusProposerReward, "",
|
||||
func(r *rand.Rand) string {
|
||||
return fmt.Sprintf("\"%s\"", GenBonusProposerReward(r))
|
||||
},
|
||||
),
|
||||
}
|
||||
}
|
|
@ -2,6 +2,7 @@ package genaccounts
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"math/rand"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/spf13/cobra"
|
||||
|
@ -14,6 +15,8 @@ import (
|
|||
"github.com/cosmos/cosmos-sdk/types/module"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth/exported"
|
||||
"github.com/cosmos/cosmos-sdk/x/genaccounts/internal/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/genaccounts/simulation"
|
||||
sim "github.com/cosmos/cosmos-sdk/x/simulation"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -82,6 +85,16 @@ type AppModuleSimulation struct{}
|
|||
// RegisterStoreDecoder performs a no-op.
|
||||
func (AppModuleSimulation) RegisterStoreDecoder(_ sdk.StoreDecoderRegistry) {}
|
||||
|
||||
// GenerateGenesisState creates a randomized GenState of the genesis accounts module.
|
||||
func (AppModuleSimulation) GenerateGenesisState(simState *module.SimulationState) {
|
||||
simulation.RandomizedGenState(simState)
|
||||
}
|
||||
|
||||
// RandomizedParams doesn't create randomized genaccounts param changes for the simulator.
|
||||
func (AppModuleSimulation) RandomizedParams(_ *rand.Rand) []sim.ParamChange {
|
||||
return nil
|
||||
}
|
||||
|
||||
//____________________________________________________________________________
|
||||
|
||||
// AppModule implements an application module for the genesis accounts module.
|
||||
|
@ -93,15 +106,30 @@ type AppModule struct {
|
|||
}
|
||||
|
||||
// NewAppModule creates a new AppModule object
|
||||
func NewAppModule(accountKeeper types.AccountKeeper) module.AppModule {
|
||||
func NewAppModule(accountKeeper types.AccountKeeper) AppModule {
|
||||
|
||||
return module.NewGenesisOnlyAppModule(AppModule{
|
||||
return AppModule{
|
||||
AppModuleBasic: AppModuleBasic{},
|
||||
AppModuleSimulation: AppModuleSimulation{},
|
||||
accountKeeper: accountKeeper,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// RegisterInvariants is a placeholder function register no invariants
|
||||
func (AppModule) RegisterInvariants(_ sdk.InvariantRegistry) {}
|
||||
|
||||
// Route empty module message route
|
||||
func (AppModule) Route() string { return "" }
|
||||
|
||||
// NewHandler returns an empty module handler
|
||||
func (AppModule) NewHandler() sdk.Handler { return nil }
|
||||
|
||||
// QuerierRoute returns an empty module querier route
|
||||
func (AppModule) QuerierRoute() string { return "" }
|
||||
|
||||
// NewQuerierHandler returns an empty module querier
|
||||
func (AppModule) NewQuerierHandler() sdk.Querier { return nil }
|
||||
|
||||
// InitGenesis performs genesis initialization for the genesis accounts module. It returns
|
||||
// no validator updates.
|
||||
func (am AppModule) InitGenesis(ctx sdk.Context, data json.RawMessage) []abci.ValidatorUpdate {
|
||||
|
@ -117,3 +145,11 @@ func (am AppModule) ExportGenesis(ctx sdk.Context) json.RawMessage {
|
|||
gs := ExportGenesis(ctx, am.accountKeeper)
|
||||
return ModuleCdc.MustMarshalJSON(gs)
|
||||
}
|
||||
|
||||
// BeginBlock returns an empty module begin-block
|
||||
func (AppModule) BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) {}
|
||||
|
||||
// EndBlock returns an empty module end-block
|
||||
func (AppModule) EndBlock(_ sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate {
|
||||
return []abci.ValidatorUpdate{}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
package simulation
|
||||
|
||||
// DONTCOVER
|
||||
|
||||
import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/module"
|
||||
authexported "github.com/cosmos/cosmos-sdk/x/auth/exported"
|
||||
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/genaccounts/internal/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/simulation"
|
||||
)
|
||||
|
||||
// RandomizedGenState generates a random GenesisState for the genesis accounts
|
||||
func RandomizedGenState(simState *module.SimulationState) {
|
||||
var genesisAccounts []types.GenesisAccount
|
||||
|
||||
// randomly generate some genesis accounts
|
||||
for i, acc := range simState.Accounts {
|
||||
coins := sdk.Coins{sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(simState.InitialStake))}
|
||||
bacc := authtypes.NewBaseAccountWithAddress(acc.Address)
|
||||
if err := bacc.SetCoins(coins); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
var gacc types.GenesisAccount
|
||||
|
||||
// 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 {
|
||||
var (
|
||||
vacc authexported.VestingAccount
|
||||
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), int(startTime+(60*60*24*30))))
|
||||
} else {
|
||||
endTime = int64(simulation.RandIntBetween(simState.Rand, int(startTime), int(startTime+(60*60*12))))
|
||||
}
|
||||
|
||||
if startTime == endTime {
|
||||
endTime++
|
||||
}
|
||||
|
||||
if simState.Rand.Intn(100) < 50 {
|
||||
vacc = authtypes.NewContinuousVestingAccount(&bacc, startTime, endTime)
|
||||
} else {
|
||||
vacc = authtypes.NewDelayedVestingAccount(&bacc, endTime)
|
||||
}
|
||||
|
||||
var err error
|
||||
gacc, err = types.NewGenesisAccountI(vacc)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
} else {
|
||||
gacc = types.NewGenesisAccount(&bacc)
|
||||
}
|
||||
|
||||
genesisAccounts = append(genesisAccounts, gacc)
|
||||
}
|
||||
|
||||
simState.GenState[types.ModuleName] = simState.Cdc.MustMarshalJSON(genesisAccounts)
|
||||
}
|
|
@ -16,9 +16,8 @@ import (
|
|||
)
|
||||
|
||||
var (
|
||||
_ module.AppModuleGenesis = AppModule{}
|
||||
_ module.AppModuleBasic = AppModuleBasic{}
|
||||
_ module.AppModuleSimulation = AppModuleSimulation{}
|
||||
_ module.AppModuleGenesis = AppModule{}
|
||||
_ module.AppModuleBasic = AppModuleBasic{}
|
||||
)
|
||||
|
||||
// AppModuleBasic defines the basic application module used by the genutil module.
|
||||
|
@ -59,18 +58,9 @@ func (AppModuleBasic) GetQueryCmd(_ *codec.Codec) *cobra.Command { return nil }
|
|||
|
||||
//____________________________________________________________________________
|
||||
|
||||
// AppModuleSimulation defines the module simulation functions used by the auth module.
|
||||
type AppModuleSimulation struct{}
|
||||
|
||||
// RegisterStoreDecoder registers a decoder for genutil module's types
|
||||
func (AppModuleSimulation) RegisterStoreDecoder(_ sdk.StoreDecoderRegistry) {}
|
||||
|
||||
//____________________________________________________________________________
|
||||
|
||||
// AppModule implements an application module for the genutil module.
|
||||
type AppModule struct {
|
||||
AppModuleBasic
|
||||
AppModuleSimulation
|
||||
|
||||
accountKeeper types.AccountKeeper
|
||||
stakingKeeper types.StakingKeeper
|
||||
|
@ -82,11 +72,10 @@ func NewAppModule(accountKeeper types.AccountKeeper,
|
|||
stakingKeeper types.StakingKeeper, deliverTx deliverTxfn) module.AppModule {
|
||||
|
||||
return module.NewGenesisOnlyAppModule(AppModule{
|
||||
AppModuleBasic: AppModuleBasic{},
|
||||
AppModuleSimulation: AppModuleSimulation{},
|
||||
accountKeeper: accountKeeper,
|
||||
stakingKeeper: stakingKeeper,
|
||||
deliverTx: deliverTx,
|
||||
AppModuleBasic: AppModuleBasic{},
|
||||
accountKeeper: accountKeeper,
|
||||
stakingKeeper: stakingKeeper,
|
||||
deliverTx: deliverTx,
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ package gov
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"math/rand"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/spf13/cobra"
|
||||
|
@ -19,6 +20,7 @@ import (
|
|||
"github.com/cosmos/cosmos-sdk/x/gov/client/rest"
|
||||
"github.com/cosmos/cosmos-sdk/x/gov/simulation"
|
||||
"github.com/cosmos/cosmos-sdk/x/gov/types"
|
||||
sim "github.com/cosmos/cosmos-sdk/x/simulation"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -96,11 +98,21 @@ func (AppModuleBasic) GetQueryCmd(cdc *codec.Codec) *cobra.Command {
|
|||
// AppModuleSimulation defines the module simulation functions used by the gov module.
|
||||
type AppModuleSimulation struct{}
|
||||
|
||||
// RegisterStoreDecoder performs a no-op.
|
||||
// RegisterStoreDecoder registers a decoder for gov module's types
|
||||
func (AppModuleSimulation) RegisterStoreDecoder(sdr sdk.StoreDecoderRegistry) {
|
||||
sdr[StoreKey] = simulation.DecodeStore
|
||||
}
|
||||
|
||||
// GenerateGenesisState creates a randomized GenState of the gov module.
|
||||
func (AppModuleSimulation) GenerateGenesisState(simState *module.SimulationState) {
|
||||
simulation.RandomizedGenState(simState)
|
||||
}
|
||||
|
||||
// RandomizedParams creates randomized gov param changes for the simulator.
|
||||
func (AppModuleSimulation) RandomizedParams(r *rand.Rand) []sim.ParamChange {
|
||||
return simulation.ParamChanges(r)
|
||||
}
|
||||
|
||||
//____________________________________________________________________________
|
||||
|
||||
// AppModule implements an application module for the gov module.
|
||||
|
|
|
@ -0,0 +1,107 @@
|
|||
package simulation
|
||||
|
||||
// DONTCOVER
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"time"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/module"
|
||||
"github.com/cosmos/cosmos-sdk/x/gov/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/simulation"
|
||||
)
|
||||
|
||||
// Simulation parameter constants
|
||||
const (
|
||||
DepositParamsMinDeposit = "deposit_params_min_deposit"
|
||||
DepositParamsDepositPeriod = "deposit_params_deposit_period"
|
||||
VotingParamsVotingPeriod = "voting_params_voting_period"
|
||||
TallyParamsQuorum = "tally_params_quorum"
|
||||
TallyParamsThreshold = "tally_params_threshold"
|
||||
TallyParamsVeto = "tally_params_veto"
|
||||
)
|
||||
|
||||
// GenDepositParamsDepositPeriod randomized DepositParamsDepositPeriod
|
||||
func GenDepositParamsDepositPeriod(r *rand.Rand) time.Duration {
|
||||
return time.Duration(simulation.RandIntBetween(r, 1, 2*60*60*24*2)) * time.Second
|
||||
}
|
||||
|
||||
// GenDepositParamsMinDeposit randomized DepositParamsMinDeposit
|
||||
func GenDepositParamsMinDeposit(r *rand.Rand) sdk.Coins {
|
||||
return sdk.NewCoins(sdk.NewInt64Coin(sdk.DefaultBondDenom, int64(simulation.RandIntBetween(r, 1, 1e3))))
|
||||
}
|
||||
|
||||
// GenVotingParamsVotingPeriod randomized VotingParamsVotingPeriod
|
||||
func GenVotingParamsVotingPeriod(r *rand.Rand) time.Duration {
|
||||
return time.Duration(simulation.RandIntBetween(r, 1, 2*60*60*24*2)) * time.Second
|
||||
}
|
||||
|
||||
// GenTallyParamsQuorum randomized TallyParamsQuorum
|
||||
func GenTallyParamsQuorum(r *rand.Rand) sdk.Dec {
|
||||
return sdk.NewDecWithPrec(int64(simulation.RandIntBetween(r, 334, 500)), 3)
|
||||
}
|
||||
|
||||
// GenTallyParamsThreshold randomized TallyParamsThreshold
|
||||
func GenTallyParamsThreshold(r *rand.Rand) sdk.Dec {
|
||||
return sdk.NewDecWithPrec(int64(simulation.RandIntBetween(r, 450, 550)), 3)
|
||||
}
|
||||
|
||||
// GenTallyParamsVeto randomized TallyParamsVeto
|
||||
func GenTallyParamsVeto(r *rand.Rand) sdk.Dec {
|
||||
return sdk.NewDecWithPrec(int64(simulation.RandIntBetween(r, 250, 334)), 3)
|
||||
}
|
||||
|
||||
// RandomizedGenState generates a random GenesisState for gov
|
||||
func RandomizedGenState(simState *module.SimulationState) {
|
||||
startingProposalID := uint64(simState.Rand.Intn(100))
|
||||
|
||||
var minDeposit sdk.Coins
|
||||
simState.AppParams.GetOrGenerate(
|
||||
simState.Cdc, DepositParamsMinDeposit, &minDeposit, simState.Rand,
|
||||
func(r *rand.Rand) { minDeposit = GenDepositParamsMinDeposit(r) },
|
||||
)
|
||||
|
||||
var depositPeriod time.Duration
|
||||
simState.AppParams.GetOrGenerate(
|
||||
simState.Cdc, DepositParamsDepositPeriod, &depositPeriod, simState.Rand,
|
||||
func(r *rand.Rand) { depositPeriod = GenDepositParamsDepositPeriod(r) },
|
||||
)
|
||||
|
||||
var votingPeriod time.Duration
|
||||
simState.AppParams.GetOrGenerate(
|
||||
simState.Cdc, VotingParamsVotingPeriod, &votingPeriod, simState.Rand,
|
||||
func(r *rand.Rand) { votingPeriod = GenVotingParamsVotingPeriod(r) },
|
||||
)
|
||||
|
||||
var quorum sdk.Dec
|
||||
simState.AppParams.GetOrGenerate(
|
||||
simState.Cdc, TallyParamsQuorum, &quorum, simState.Rand,
|
||||
func(r *rand.Rand) { quorum = GenTallyParamsQuorum(r) },
|
||||
)
|
||||
|
||||
var threshold sdk.Dec
|
||||
simState.AppParams.GetOrGenerate(
|
||||
simState.Cdc, TallyParamsThreshold, &threshold, simState.Rand,
|
||||
func(r *rand.Rand) { threshold = GenTallyParamsThreshold(r) },
|
||||
)
|
||||
|
||||
var veto sdk.Dec
|
||||
simState.AppParams.GetOrGenerate(
|
||||
simState.Cdc, TallyParamsVeto, &veto, simState.Rand,
|
||||
func(r *rand.Rand) { veto = GenTallyParamsVeto(r) },
|
||||
)
|
||||
|
||||
govGenesis := types.NewGenesisState(
|
||||
startingProposalID,
|
||||
types.NewDepositParams(minDeposit, depositPeriod),
|
||||
types.NewVotingParams(votingPeriod),
|
||||
types.NewTallyParams(quorum, threshold, veto),
|
||||
)
|
||||
|
||||
fmt.Printf("Selected randomly generated governance parameters:\n%s\n", codec.MustMarshalJSONIndent(simState.Cdc, govGenesis))
|
||||
simState.GenState[types.ModuleName] = simState.Cdc.MustMarshalJSON(govGenesis)
|
||||
}
|
|
@ -14,7 +14,7 @@ import (
|
|||
|
||||
// ContentSimulator defines a function type alias for generating random proposal
|
||||
// content.
|
||||
type ContentSimulator func(r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accs []simulation.Account) gov.Content
|
||||
type ContentSimulator func(r *rand.Rand, ctx sdk.Context, accs []simulation.Account) gov.Content
|
||||
|
||||
// SimulateSubmittingVotingAndSlashingForProposal simulates creating a msg Submit Proposal
|
||||
// voting on the proposal, and subsequently slashing the proposal. It is implemented using
|
||||
|
@ -51,7 +51,7 @@ func SimulateSubmittingVotingAndSlashingForProposal(k gov.Keeper, contentSim Con
|
|||
|
||||
// 1) submit proposal now
|
||||
sender := simulation.RandomAcc(r, accs)
|
||||
content := contentSim(r, app, ctx, accs)
|
||||
content := contentSim(r, ctx, accs)
|
||||
msg, err := simulationCreateMsgSubmitProposal(r, content, sender)
|
||||
if err != nil {
|
||||
return simulation.NoOpMsg(gov.ModuleName), nil, err
|
||||
|
@ -107,7 +107,7 @@ func simulateHandleMsgSubmitProposal(msg gov.MsgSubmitProposal, handler sdk.Hand
|
|||
}
|
||||
|
||||
// SimulateTextProposalContent returns random text proposal content.
|
||||
func SimulateTextProposalContent(r *rand.Rand, _ *baseapp.BaseApp, _ sdk.Context, _ []simulation.Account) gov.Content {
|
||||
func SimulateTextProposalContent(r *rand.Rand, _ sdk.Context, _ []simulation.Account) gov.Content {
|
||||
return gov.NewTextProposal(
|
||||
simulation.RandStringOfLength(r, 140),
|
||||
simulation.RandStringOfLength(r, 5000),
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
package simulation
|
||||
|
||||
// DONTCOVER
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/gov/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/simulation"
|
||||
)
|
||||
|
||||
const (
|
||||
keyVotingParams = "votingparams"
|
||||
keyDepositParams = "depositparams"
|
||||
keyTallyParams = "tallyparams"
|
||||
subkeyQuorum = "quorum"
|
||||
subkeyThreshold = "threshold"
|
||||
subkeyVeto = "veto"
|
||||
)
|
||||
|
||||
// ParamChanges defines the parameters that can be modified by param change proposals
|
||||
// on the simulation
|
||||
func ParamChanges(r *rand.Rand) []simulation.ParamChange {
|
||||
return []simulation.ParamChange{
|
||||
simulation.NewSimParamChange(types.ModuleName, keyVotingParams, "",
|
||||
func(r *rand.Rand) string {
|
||||
return fmt.Sprintf(`{"voting_period": "%d"}`, GenVotingParamsVotingPeriod(r))
|
||||
},
|
||||
),
|
||||
simulation.NewSimParamChange(types.ModuleName, keyDepositParams, "",
|
||||
func(r *rand.Rand) string {
|
||||
return fmt.Sprintf(`{"max_deposit_period": "%d"}`, GenDepositParamsDepositPeriod(r))
|
||||
},
|
||||
),
|
||||
simulation.NewSimParamChange(types.ModuleName, keyTallyParams, "",
|
||||
func(r *rand.Rand) string {
|
||||
changes := []struct {
|
||||
key string
|
||||
value sdk.Dec
|
||||
}{
|
||||
{subkeyQuorum, GenTallyParamsQuorum(r)},
|
||||
{subkeyThreshold, GenTallyParamsThreshold(r)},
|
||||
{subkeyVeto, GenTallyParamsVeto(r)},
|
||||
}
|
||||
|
||||
pc := make(map[string]string)
|
||||
numChanges := simulation.RandIntBetween(r, 1, len(changes))
|
||||
for i := 0; i < numChanges; i++ {
|
||||
c := changes[r.Intn(len(changes))]
|
||||
|
||||
_, ok := pc[c.key]
|
||||
for ok {
|
||||
c := changes[r.Intn(len(changes))]
|
||||
_, ok = pc[c.key]
|
||||
}
|
||||
|
||||
pc[c.key] = c.value.String()
|
||||
}
|
||||
|
||||
bz, _ := json.Marshal(pc)
|
||||
return string(bz)
|
||||
},
|
||||
),
|
||||
}
|
||||
}
|
|
@ -24,6 +24,9 @@ var (
|
|||
// functions aliases
|
||||
NewKeeper = keeper.NewKeeper
|
||||
NewQuerier = keeper.NewQuerier
|
||||
NewGenesisState = types.NewGenesisState
|
||||
DefaultGenesisState = types.DefaultGenesisState
|
||||
ValidateGenesis = types.ValidateGenesis
|
||||
NewMinter = types.NewMinter
|
||||
InitialMinter = types.InitialMinter
|
||||
DefaultInitialMinter = types.DefaultInitialMinter
|
||||
|
@ -45,7 +48,8 @@ var (
|
|||
)
|
||||
|
||||
type (
|
||||
Keeper = keeper.Keeper
|
||||
Minter = types.Minter
|
||||
Params = types.Params
|
||||
Keeper = keeper.Keeper
|
||||
GenesisState = types.GenesisState
|
||||
Minter = types.Minter
|
||||
Params = types.Params
|
||||
)
|
||||
|
|
|
@ -4,28 +4,6 @@ import (
|
|||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
// GenesisState - minter state
|
||||
type GenesisState struct {
|
||||
Minter Minter `json:"minter" yaml:"minter"` // minter object
|
||||
Params Params `json:"params" yaml:"params"` // inflation params
|
||||
}
|
||||
|
||||
// NewGenesisState creates a new GenesisState object
|
||||
func NewGenesisState(minter Minter, params Params) GenesisState {
|
||||
return GenesisState{
|
||||
Minter: minter,
|
||||
Params: params,
|
||||
}
|
||||
}
|
||||
|
||||
// DefaultGenesisState creates a default GenesisState object
|
||||
func DefaultGenesisState() GenesisState {
|
||||
return GenesisState{
|
||||
Minter: DefaultInitialMinter(),
|
||||
Params: DefaultParams(),
|
||||
}
|
||||
}
|
||||
|
||||
// InitGenesis new mint genesis
|
||||
func InitGenesis(ctx sdk.Context, keeper Keeper, data GenesisState) {
|
||||
keeper.SetMinter(ctx, data.Minter)
|
||||
|
@ -38,19 +16,3 @@ func ExportGenesis(ctx sdk.Context, keeper Keeper) GenesisState {
|
|||
params := keeper.GetParams(ctx)
|
||||
return NewGenesisState(minter, params)
|
||||
}
|
||||
|
||||
// ValidateGenesis validates the provided genesis state to ensure the
|
||||
// expected invariants holds.
|
||||
func ValidateGenesis(data GenesisState) error {
|
||||
err := ValidateParams(data.Params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = ValidateMinter(data.Minter)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
package types
|
||||
|
||||
// GenesisState - minter state
|
||||
type GenesisState struct {
|
||||
Minter Minter `json:"minter" yaml:"minter"` // minter object
|
||||
Params Params `json:"params" yaml:"params"` // inflation params
|
||||
}
|
||||
|
||||
// NewGenesisState creates a new GenesisState object
|
||||
func NewGenesisState(minter Minter, params Params) GenesisState {
|
||||
return GenesisState{
|
||||
Minter: minter,
|
||||
Params: params,
|
||||
}
|
||||
}
|
||||
|
||||
// DefaultGenesisState creates a default GenesisState object
|
||||
func DefaultGenesisState() GenesisState {
|
||||
return GenesisState{
|
||||
Minter: DefaultInitialMinter(),
|
||||
Params: DefaultParams(),
|
||||
}
|
||||
}
|
||||
|
||||
// ValidateGenesis validates the provided genesis state to ensure the
|
||||
// expected invariants holds.
|
||||
func ValidateGenesis(data GenesisState) error {
|
||||
err := ValidateParams(data.Params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return ValidateMinter(data.Minter)
|
||||
}
|
|
@ -2,6 +2,7 @@ package mint
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"math/rand"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/spf13/cobra"
|
||||
|
@ -15,6 +16,7 @@ import (
|
|||
"github.com/cosmos/cosmos-sdk/x/mint/client/cli"
|
||||
"github.com/cosmos/cosmos-sdk/x/mint/client/rest"
|
||||
"github.com/cosmos/cosmos-sdk/x/mint/simulation"
|
||||
sim "github.com/cosmos/cosmos-sdk/x/simulation"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -75,6 +77,16 @@ func (AppModuleSimulation) RegisterStoreDecoder(sdr sdk.StoreDecoderRegistry) {
|
|||
sdr[StoreKey] = simulation.DecodeStore
|
||||
}
|
||||
|
||||
// GenerateGenesisState creates a randomized GenState of the mint module.
|
||||
func (AppModuleSimulation) GenerateGenesisState(simState *module.SimulationState) {
|
||||
simulation.RandomizedGenState(simState)
|
||||
}
|
||||
|
||||
// RandomizedParams creates randomized mint param changes for the simulator.
|
||||
func (AppModuleSimulation) RandomizedParams(r *rand.Rand) []sim.ParamChange {
|
||||
return simulation.ParamChanges(r)
|
||||
}
|
||||
|
||||
//____________________________________________________________________________
|
||||
|
||||
// AppModule implements an application module for the mint module.
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
package simulation
|
||||
|
||||
// DONTCOVER
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/module"
|
||||
"github.com/cosmos/cosmos-sdk/x/mint/internal/types"
|
||||
)
|
||||
|
||||
// Simulation parameter constants
|
||||
const (
|
||||
Inflation = "inflation"
|
||||
InflationRateChange = "inflation_rate_change"
|
||||
InflationMax = "inflation_max"
|
||||
InflationMin = "inflation_min"
|
||||
GoalBonded = "goal_bonded"
|
||||
)
|
||||
|
||||
// GenInflation randomized Inflation
|
||||
func GenInflation(r *rand.Rand) sdk.Dec {
|
||||
return sdk.NewDecWithPrec(int64(r.Intn(99)), 2)
|
||||
}
|
||||
|
||||
// GenInflationRateChange randomized InflationRateChange
|
||||
func GenInflationRateChange(r *rand.Rand) sdk.Dec {
|
||||
return sdk.NewDecWithPrec(int64(r.Intn(99)), 2)
|
||||
}
|
||||
|
||||
// GenInflationMax randomized InflationMax
|
||||
func GenInflationMax(r *rand.Rand) sdk.Dec {
|
||||
return sdk.NewDecWithPrec(20, 2)
|
||||
}
|
||||
|
||||
// GenInflationMin randomized InflationMin
|
||||
func GenInflationMin(r *rand.Rand) sdk.Dec {
|
||||
return sdk.NewDecWithPrec(7, 2)
|
||||
}
|
||||
|
||||
// GenGoalBonded randomized GoalBonded
|
||||
func GenGoalBonded(r *rand.Rand) sdk.Dec {
|
||||
return sdk.NewDecWithPrec(67, 2)
|
||||
}
|
||||
|
||||
// RandomizedGenState generates a random GenesisState for mint
|
||||
func RandomizedGenState(simState *module.SimulationState) {
|
||||
// minter
|
||||
var inflation sdk.Dec
|
||||
simState.AppParams.GetOrGenerate(
|
||||
simState.Cdc, Inflation, &inflation, simState.Rand,
|
||||
func(r *rand.Rand) { inflation = GenInflation(r) },
|
||||
)
|
||||
|
||||
// params
|
||||
var inflationRateChange sdk.Dec
|
||||
simState.AppParams.GetOrGenerate(
|
||||
simState.Cdc, InflationRateChange, &inflationRateChange, simState.Rand,
|
||||
func(r *rand.Rand) { inflationRateChange = GenInflationRateChange(r) },
|
||||
)
|
||||
|
||||
var inflationMax sdk.Dec
|
||||
simState.AppParams.GetOrGenerate(
|
||||
simState.Cdc, InflationMax, &inflationMax, simState.Rand,
|
||||
func(r *rand.Rand) { inflationMax = GenInflationMax(r) },
|
||||
)
|
||||
|
||||
var inflationMin sdk.Dec
|
||||
simState.AppParams.GetOrGenerate(
|
||||
simState.Cdc, InflationMin, &inflationMin, simState.Rand,
|
||||
func(r *rand.Rand) { inflationMin = GenInflationMin(r) },
|
||||
)
|
||||
|
||||
var goalBonded sdk.Dec
|
||||
simState.AppParams.GetOrGenerate(
|
||||
simState.Cdc, GoalBonded, &goalBonded, simState.Rand,
|
||||
func(r *rand.Rand) { goalBonded = GenGoalBonded(r) },
|
||||
)
|
||||
|
||||
mintDenom := sdk.DefaultBondDenom
|
||||
blocksPerYear := uint64(60 * 60 * 8766 / 5)
|
||||
params := types.NewParams(mintDenom, inflationRateChange, inflationMax, inflationMin, goalBonded, blocksPerYear)
|
||||
|
||||
mintGenesis := types.NewGenesisState(types.InitialMinter(inflation), params)
|
||||
|
||||
fmt.Printf("Selected randomly generated minting parameters:\n%s\n", codec.MustMarshalJSONIndent(simState.Cdc, mintGenesis))
|
||||
simState.GenState[types.ModuleName] = simState.Cdc.MustMarshalJSON(mintGenesis)
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
package simulation
|
||||
|
||||
// DONTCOVER
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/x/mint/internal/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/simulation"
|
||||
)
|
||||
|
||||
const (
|
||||
keyInflationRateChange = "InflationRateChange"
|
||||
keyInflationMax = "InflationMax"
|
||||
keyInflationMin = "InflationMin"
|
||||
keyGoalBonded = "GoalBonded"
|
||||
)
|
||||
|
||||
// ParamChanges defines the parameters that can be modified by param change proposals
|
||||
// on the simulation
|
||||
func ParamChanges(r *rand.Rand) []simulation.ParamChange {
|
||||
return []simulation.ParamChange{
|
||||
simulation.NewSimParamChange(types.ModuleName, keyInflationRateChange, "",
|
||||
func(r *rand.Rand) string {
|
||||
return fmt.Sprintf("\"%s\"", GenInflationRateChange(r))
|
||||
},
|
||||
),
|
||||
simulation.NewSimParamChange(types.ModuleName, keyInflationMax, "",
|
||||
func(r *rand.Rand) string {
|
||||
return fmt.Sprintf("\"%s\"", GenInflationMax(r))
|
||||
},
|
||||
),
|
||||
simulation.NewSimParamChange(types.ModuleName, keyInflationMin, "",
|
||||
func(r *rand.Rand) string {
|
||||
return fmt.Sprintf("\"%s\"", GenInflationMin(r))
|
||||
},
|
||||
),
|
||||
simulation.NewSimParamChange(types.ModuleName, keyGoalBonded, "",
|
||||
func(r *rand.Rand) string {
|
||||
return fmt.Sprintf("\"%s\"", GenGoalBonded(r))
|
||||
},
|
||||
),
|
||||
}
|
||||
}
|
|
@ -13,7 +13,7 @@ import (
|
|||
|
||||
// nolint: deadcode unused
|
||||
var (
|
||||
denom1 = "test-denom"
|
||||
denom1 = "test-denom"
|
||||
denom2 = "test-denom2"
|
||||
denom3 = "test-denom3"
|
||||
id = "1"
|
||||
|
@ -22,7 +22,7 @@ var (
|
|||
address = types.CreateTestAddrs(1)[0]
|
||||
address2 = types.CreateTestAddrs(2)[1]
|
||||
address3 = types.CreateTestAddrs(3)[2]
|
||||
tokenURI1 = "https://google.com/token-1.json"
|
||||
tokenURI1 = "https://google.com/token-1.json"
|
||||
tokenURI2 = "https://google.com/token-2.json"
|
||||
)
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ package nft
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"math/rand"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/spf13/cobra"
|
||||
|
@ -17,6 +18,7 @@ import (
|
|||
"github.com/cosmos/cosmos-sdk/x/nft/client/cli"
|
||||
"github.com/cosmos/cosmos-sdk/x/nft/client/rest"
|
||||
"github.com/cosmos/cosmos-sdk/x/nft/simulation"
|
||||
sim "github.com/cosmos/cosmos-sdk/x/simulation"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -76,11 +78,21 @@ func (AppModuleBasic) GetQueryCmd(cdc *codec.Codec) *cobra.Command {
|
|||
// AppModuleSimulation defines the module simulation functions used by the gov module.
|
||||
type AppModuleSimulation struct{}
|
||||
|
||||
// RegisterStoreDecoder performs a no-op.
|
||||
// RegisterStoreDecoder registers a decoder for nft module's types
|
||||
func (AppModuleSimulation) RegisterStoreDecoder(sdr sdk.StoreDecoderRegistry) {
|
||||
sdr[StoreKey] = simulation.DecodeStore
|
||||
}
|
||||
|
||||
// GenerateGenesisState creates a randomized GenState of the nft module.
|
||||
func (AppModuleSimulation) GenerateGenesisState(simState *module.SimulationState) {
|
||||
simulation.RandomizedGenState(simState)
|
||||
}
|
||||
|
||||
// RandomizedParams doesn't create randomized nft param changes for the simulator.
|
||||
func (AppModuleSimulation) RandomizedParams(_ *rand.Rand) []sim.ParamChange {
|
||||
return nil
|
||||
}
|
||||
|
||||
//____________________________________________________________________________
|
||||
|
||||
// AppModule supply app module
|
||||
|
|
|
@ -1,48 +1,53 @@
|
|||
package simulation
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
"github.com/cosmos/cosmos-sdk/types/module"
|
||||
"github.com/cosmos/cosmos-sdk/x/nft/internal/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/simulation"
|
||||
)
|
||||
|
||||
// GenNFTGenesisState generates a random GenesisState for nft
|
||||
func GenNFTGenesisState(cdc *codec.Codec, r *rand.Rand, accs []simulation.Account, ap simulation.AppParams, genesisState map[string]json.RawMessage) {
|
||||
const (
|
||||
Kitties = "crypto-kitties"
|
||||
Doggos = "crypto-doggos"
|
||||
)
|
||||
const (
|
||||
kities = "crypto-kities"
|
||||
doggos = "crypto-doggos"
|
||||
)
|
||||
|
||||
collections := types.NewCollections(types.NewCollection(Kitties, types.NFTs{}), types.NewCollection(Doggos, types.NFTs{}))
|
||||
// RandomizedGenState generates a random GenesisState for nft
|
||||
func RandomizedGenState(simState *module.SimulationState) {
|
||||
collections := types.NewCollections(types.NewCollection(kities, types.NFTs{}), types.NewCollection(doggos, types.NFTs{}))
|
||||
var ownerships []types.Owner
|
||||
|
||||
for _, acc := range accs {
|
||||
if r.Intn(100) < 50 {
|
||||
for _, acc := range simState.Accounts {
|
||||
// 10% of accounts own an NFT
|
||||
if simState.Rand.Intn(100) < 10 {
|
||||
baseNFT := types.NewBaseNFT(
|
||||
simulation.RandStringOfLength(r, 10), // id
|
||||
simulation.RandStringOfLength(simState.Rand, 10), // id
|
||||
acc.Address,
|
||||
simulation.RandStringOfLength(r, 45), // tokenURI
|
||||
simulation.RandStringOfLength(simState.Rand, 45), // tokenURI
|
||||
)
|
||||
|
||||
var idCollection types.IDCollection
|
||||
var err error
|
||||
if r.Intn(100) < 50 {
|
||||
var (
|
||||
idCollection types.IDCollection
|
||||
err error
|
||||
)
|
||||
|
||||
// 50% doggos and 50% kitties
|
||||
if simState.Rand.Intn(100) < 50 {
|
||||
collections[0], err = collections[0].AddNFT(&baseNFT)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
idCollection = types.NewIDCollection(Kitties, []string{baseNFT.ID})
|
||||
idCollection = types.NewIDCollection(kities, []string{baseNFT.ID})
|
||||
} else {
|
||||
collections[1], err = collections[1].AddNFT(&baseNFT)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
idCollection = types.NewIDCollection(Doggos, []string{baseNFT.ID})
|
||||
idCollection = types.NewIDCollection(doggos, []string{baseNFT.ID})
|
||||
}
|
||||
|
||||
ownership := types.NewOwner(acc.Address, idCollection)
|
||||
ownerships = append(ownerships, ownership)
|
||||
}
|
||||
|
@ -50,6 +55,6 @@ func GenNFTGenesisState(cdc *codec.Codec, r *rand.Rand, accs []simulation.Accoun
|
|||
|
||||
nftGenesis := types.NewGenesisState(ownerships, collections)
|
||||
|
||||
fmt.Printf("Selected randomly generated NFT parameters:\n%s\n", codec.MustMarshalJSONIndent(cdc, nftGenesis))
|
||||
genesisState[types.ModuleName] = cdc.MustMarshalJSON(nftGenesis)
|
||||
fmt.Printf("Selected randomly generated NFT genesis state:\n%s\n", codec.MustMarshalJSONIndent(simState.Cdc, nftGenesis))
|
||||
simState.GenState[types.ModuleName] = simState.Cdc.MustMarshalJSON(nftGenesis)
|
||||
}
|
||||
|
|
|
@ -1,185 +1,53 @@
|
|||
package operations
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"time"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/baseapp"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
govsimops "github.com/cosmos/cosmos-sdk/x/gov/simulation/operations"
|
||||
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/params"
|
||||
"github.com/cosmos/cosmos-sdk/x/simulation"
|
||||
)
|
||||
|
||||
type simParamChange struct {
|
||||
subspace string
|
||||
key string
|
||||
subkey string
|
||||
simValue func(r *rand.Rand) string
|
||||
}
|
||||
|
||||
func (spc simParamChange) compKey() string {
|
||||
return fmt.Sprintf("%s/%s/%s", spc.subkey, spc.key, spc.subkey)
|
||||
}
|
||||
|
||||
// paramChangePool defines a static slice of possible simulated parameter changes
|
||||
// where each simParamChange corresponds to a ParamChange with a simValue
|
||||
// function to generate a simulated new value.
|
||||
var paramChangePool = []simParamChange{
|
||||
// staking parameters
|
||||
{
|
||||
"staking",
|
||||
"MaxValidators",
|
||||
"",
|
||||
func(r *rand.Rand) string {
|
||||
return fmt.Sprintf("%d", simulation.ModuleParamSimulator[simulation.MaxValidators](r).(uint16))
|
||||
},
|
||||
},
|
||||
{
|
||||
"staking",
|
||||
"UnbondingTime",
|
||||
"",
|
||||
func(r *rand.Rand) string {
|
||||
return fmt.Sprintf("\"%d\"", simulation.ModuleParamSimulator[simulation.UnbondingTime](r).(time.Duration))
|
||||
},
|
||||
},
|
||||
// slashing parameters
|
||||
{
|
||||
"slashing",
|
||||
"SignedBlocksWindow",
|
||||
"",
|
||||
func(r *rand.Rand) string {
|
||||
return fmt.Sprintf("\"%d\"", simulation.ModuleParamSimulator[simulation.SignedBlocksWindow](r).(int64))
|
||||
},
|
||||
},
|
||||
{
|
||||
"slashing",
|
||||
"MinSignedPerWindow",
|
||||
"",
|
||||
func(r *rand.Rand) string {
|
||||
return fmt.Sprintf("\"%s\"", simulation.ModuleParamSimulator[simulation.MinSignedPerWindow](r).(sdk.Dec))
|
||||
},
|
||||
},
|
||||
{
|
||||
"slashing",
|
||||
"SlashFractionDowntime",
|
||||
"",
|
||||
func(r *rand.Rand) string {
|
||||
return fmt.Sprintf("\"%s\"", simulation.ModuleParamSimulator[simulation.SlashFractionDowntime](r).(sdk.Dec))
|
||||
},
|
||||
},
|
||||
// minting parameters
|
||||
{
|
||||
"mint",
|
||||
"InflationRateChange",
|
||||
"",
|
||||
func(r *rand.Rand) string {
|
||||
return fmt.Sprintf("\"%s\"", simulation.ModuleParamSimulator[simulation.InflationRateChange](r).(sdk.Dec))
|
||||
},
|
||||
},
|
||||
// gov parameters
|
||||
{
|
||||
"gov",
|
||||
"votingparams",
|
||||
"",
|
||||
func(r *rand.Rand) string {
|
||||
return fmt.Sprintf(`{"voting_period": "%d"}`, simulation.ModuleParamSimulator[simulation.VotingParamsVotingPeriod](r).(time.Duration))
|
||||
},
|
||||
},
|
||||
{
|
||||
"gov",
|
||||
"depositparams",
|
||||
"",
|
||||
func(r *rand.Rand) string {
|
||||
return fmt.Sprintf(`{"max_deposit_period": "%d"}`, simulation.ModuleParamSimulator[simulation.VotingParamsVotingPeriod](r).(time.Duration))
|
||||
},
|
||||
},
|
||||
{
|
||||
"gov",
|
||||
"tallyparams",
|
||||
"",
|
||||
func(r *rand.Rand) string {
|
||||
changes := []struct {
|
||||
key string
|
||||
value sdk.Dec
|
||||
}{
|
||||
{"quorum", simulation.ModuleParamSimulator[simulation.TallyParamsQuorum](r).(sdk.Dec)},
|
||||
{"threshold", simulation.ModuleParamSimulator[simulation.TallyParamsThreshold](r).(sdk.Dec)},
|
||||
{"veto", simulation.ModuleParamSimulator[simulation.TallyParamsVeto](r).(sdk.Dec)},
|
||||
}
|
||||
|
||||
pc := make(map[string]string)
|
||||
numChanges := simulation.RandIntBetween(r, 1, len(changes))
|
||||
for i := 0; i < numChanges; i++ {
|
||||
c := changes[r.Intn(len(changes))]
|
||||
|
||||
_, ok := pc[c.key]
|
||||
for ok {
|
||||
c := changes[r.Intn(len(changes))]
|
||||
_, ok = pc[c.key]
|
||||
}
|
||||
|
||||
pc[c.key] = c.value.String()
|
||||
}
|
||||
|
||||
bz, _ := json.Marshal(pc)
|
||||
return string(bz)
|
||||
},
|
||||
},
|
||||
// auth parameters
|
||||
{
|
||||
"auth",
|
||||
"MaxMemoCharacters",
|
||||
"",
|
||||
func(r *rand.Rand) string {
|
||||
return fmt.Sprintf("\"%d\"", simulation.ModuleParamSimulator[simulation.MaxMemoChars](r).(uint64))
|
||||
},
|
||||
},
|
||||
{
|
||||
"auth",
|
||||
"TxSigLimit",
|
||||
"",
|
||||
func(r *rand.Rand) string {
|
||||
return fmt.Sprintf("\"%d\"", simulation.ModuleParamSimulator[simulation.TxSigLimit](r).(uint64))
|
||||
},
|
||||
},
|
||||
{
|
||||
"auth",
|
||||
"TxSizeCostPerByte",
|
||||
"",
|
||||
func(r *rand.Rand) string {
|
||||
return fmt.Sprintf("\"%d\"", simulation.ModuleParamSimulator[simulation.TxSizeCostPerByte](r).(uint64))
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// SimulateParamChangeProposalContent returns random parameter change content.
|
||||
// It will generate a ParameterChangeProposal object with anywhere between 1 and
|
||||
// 3 parameter changes all of which have random, but valid values.
|
||||
func SimulateParamChangeProposalContent(r *rand.Rand, _ *baseapp.BaseApp, _ sdk.Context, _ []simulation.Account) govtypes.Content {
|
||||
numChanges := simulation.RandIntBetween(r, 1, len(paramChangePool)/2)
|
||||
paramChanges := make([]params.ParamChange, numChanges, numChanges)
|
||||
paramChangesKeys := make(map[string]struct{})
|
||||
// the total amount of defined parameters changes, all of which have random valid values.
|
||||
func SimulateParamChangeProposalContent(paramChangePool []simulation.ParamChange) govsimops.ContentSimulator {
|
||||
return func(r *rand.Rand, _ sdk.Context, _ []simulation.Account) govtypes.Content {
|
||||
|
||||
for i := 0; i < numChanges; i++ {
|
||||
spc := paramChangePool[r.Intn(len(paramChangePool))]
|
||||
|
||||
// do not include duplicate parameter changes for a given subspace/key
|
||||
_, ok := paramChangesKeys[spc.compKey()]
|
||||
for ok {
|
||||
spc = paramChangePool[r.Intn(len(paramChangePool))]
|
||||
_, ok = paramChangesKeys[spc.compKey()]
|
||||
lenParamChange := len(paramChangePool)
|
||||
if lenParamChange == 0 {
|
||||
panic("param changes array is empty")
|
||||
}
|
||||
|
||||
paramChangesKeys[spc.compKey()] = struct{}{}
|
||||
paramChanges[i] = params.NewParamChangeWithSubkey(spc.subspace, spc.key, spc.subkey, spc.simValue(r))
|
||||
}
|
||||
numChanges := simulation.RandIntBetween(r, 1, lenParamChange)
|
||||
paramChanges := make([]params.ParamChange, numChanges, numChanges)
|
||||
|
||||
return params.NewParameterChangeProposal(
|
||||
simulation.RandStringOfLength(r, 140),
|
||||
simulation.RandStringOfLength(r, 5000),
|
||||
paramChanges,
|
||||
)
|
||||
// map from key to empty struct; used only for look-up of the keys of the
|
||||
// parameters that are already in the random set of changes.
|
||||
paramChangesKeys := make(map[string]struct{})
|
||||
|
||||
for i := 0; i < numChanges; i++ {
|
||||
spc := paramChangePool[r.Intn(len(paramChangePool))]
|
||||
|
||||
// do not include duplicate parameter changes for a given subspace/key
|
||||
_, ok := paramChangesKeys[spc.ComposedKey()]
|
||||
for ok {
|
||||
spc = paramChangePool[r.Intn(len(paramChangePool))]
|
||||
_, ok = paramChangesKeys[spc.ComposedKey()]
|
||||
}
|
||||
|
||||
// add a new distinct parameter to the set of changes and register the key
|
||||
// to avoid further duplicates
|
||||
paramChangesKeys[spc.ComposedKey()] = struct{}{}
|
||||
paramChanges[i] = params.NewParamChangeWithSubkey(spc.Subspace, spc.Key, spc.Subkey, spc.SimValue(r))
|
||||
}
|
||||
|
||||
return params.NewParameterChangeProposal(
|
||||
simulation.RandStringOfLength(r, 140), // title
|
||||
simulation.RandStringOfLength(r, 5000), // description
|
||||
paramChanges, // set of changes
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package subspace
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
|
@ -145,7 +145,7 @@ func (s Subspace) Modified(ctx sdk.Context, key []byte) bool {
|
|||
func (s Subspace) checkType(store sdk.KVStore, key []byte, param interface{}) {
|
||||
attr, ok := s.table.m[string(key)]
|
||||
if !ok {
|
||||
panic("Parameter not registered")
|
||||
panic(fmt.Sprintf("parameter %s not registered", string(key)))
|
||||
}
|
||||
|
||||
ty := attr.ty
|
||||
|
@ -183,7 +183,7 @@ func (s Subspace) Set(ctx sdk.Context, key []byte, param interface{}) {
|
|||
func (s Subspace) Update(ctx sdk.Context, key []byte, param []byte) error {
|
||||
attr, ok := s.table.m[string(key)]
|
||||
if !ok {
|
||||
panic("Parameter not registered")
|
||||
panic(fmt.Sprintf("parameter %s not registered", string(key)))
|
||||
}
|
||||
|
||||
ty := attr.ty
|
||||
|
@ -227,7 +227,7 @@ func (s Subspace) UpdateWithSubkey(ctx sdk.Context, key []byte, subkey []byte, p
|
|||
|
||||
attr, ok := s.table.m[string(concatkey)]
|
||||
if !ok {
|
||||
return errors.New("parameter not registered")
|
||||
return fmt.Errorf("parameter %s not registered", string(key))
|
||||
}
|
||||
|
||||
ty := attr.ty
|
||||
|
|
|
@ -1,25 +1,121 @@
|
|||
/*
|
||||
Package simulation implements a simulation framework for any state machine
|
||||
built on the SDK which utilizes auth.
|
||||
Package simulation implements a full fledged Cosmos SDK application used for executing
|
||||
simulation test suites.
|
||||
|
||||
It is primarily intended for fuzz testing the integration of modules. It will
|
||||
test that the provided operations are interoperable, and that the desired
|
||||
invariants hold. It can additionally be used to detect what the performance
|
||||
benchmarks in the system are, by using benchmarking mode and cpu / mem
|
||||
profiling. If it detects a failure, it provides the entire log of what was ran.
|
||||
Simulation App
|
||||
|
||||
The simulator takes as input: a random seed, the set of operations to run, the
|
||||
invariants to test, and additional parameters to configure how long to run, and
|
||||
misc. parameters that affect simulation speed.
|
||||
The SimApp type defines an application used for running extensive simulation
|
||||
testing suites. It contains all core modules, including governance, staking,
|
||||
slashing, and distribution.
|
||||
|
||||
It is intended that every module provides a list of Operations which will
|
||||
randomly create and run a message / tx in a manner that is interesting to fuzz,
|
||||
and verify that the state transition was executed as exported. Each module
|
||||
should additionally provide methods to assert that the desired invariants hold.
|
||||
Simulation is executed with various inputs including the number of blocks to
|
||||
simulate, the block size, whether the app should commit or not, the invariant
|
||||
checking period, and a seed which is used as a source of pseudo-randomness.
|
||||
|
||||
Then to perform a randomized simulation, select the set of desired operations,
|
||||
the weightings for each, the invariants you want to test, and how long to run
|
||||
it for. Then run simulation.Simulate! The simulator will handle things like
|
||||
ensuring that validators periodically double signing, or go offline.
|
||||
In addition to the various inputs, simulation runs mainly in three modes:
|
||||
|
||||
1. Completely random where the initial state, module parameters and simulation
|
||||
parameters are pseudo-randomly generated.
|
||||
|
||||
2. From a genesis file where the initial state and the module parameters are defined.
|
||||
This mode is helpful for running simulations on a known state such as a live
|
||||
network export where a new (mostly likely breaking) version of the application
|
||||
needs to be tested.
|
||||
|
||||
3. From a params file where the initial state is pseudo-randomly generated but the
|
||||
module and simulation parameters can be provided manually. This allows for a more
|
||||
controlled and deterministic simulation setup while allowing the state space to
|
||||
still be pseudo-randomly simulated.
|
||||
|
||||
The simulation test suite also supports testing determinism and import/export
|
||||
functionality.
|
||||
|
||||
Randomness
|
||||
|
||||
Currently, simulation uses a single seed (integer) as a source for a PRNG by
|
||||
which all random operations are executed from. Any call to the PRNG changes all
|
||||
future operations as the internal state of the PRNG is modified. For example,
|
||||
if a new message type is created and needs to be simulated, the new introduced
|
||||
PRNG call will change all subsequent operations.
|
||||
|
||||
This may can often be problematic when testing fixes to simulation faults. One
|
||||
current solution to this is to use a params file as mentioned above. In the future
|
||||
the simulation suite is expected to support a series of PRNGs that can be used
|
||||
uniquely per module and simulation component so that they will not effect each
|
||||
others state execution outcome.
|
||||
|
||||
Usage
|
||||
|
||||
To execute a completely pseudo-random simulation:
|
||||
|
||||
$ go test -mod=readonly github.com/cosmos/cosmos-sdk/simapp \
|
||||
-run=TestFullAppSimulation \
|
||||
-Enabled=true \
|
||||
-NumBlocks=100 \
|
||||
-BlockSize=200 \
|
||||
-Commit=true \
|
||||
-Seed=99 \
|
||||
-Period=5 \
|
||||
-v -timeout 24h
|
||||
|
||||
To execute simulation from a genesis file:
|
||||
|
||||
$ go test -mod=readonly github.com/cosmos/cosmos-sdk/simapp \
|
||||
-run=TestFullAppSimulation \
|
||||
-Enabled=true \
|
||||
-NumBlocks=100 \
|
||||
-BlockSize=200 \
|
||||
-Commit=true \
|
||||
-Seed=99 \
|
||||
-Period=5 \
|
||||
-Genesis=/path/to/genesis.json \
|
||||
-v -timeout 24h
|
||||
|
||||
To execute simulation from a simulation params file:
|
||||
|
||||
$ go test -mod=readonly github.com/cosmos/cosmos-sdk/simapp \
|
||||
-run=TestFullAppSimulation \
|
||||
-Enabled=true \
|
||||
-NumBlocks=100 \
|
||||
-BlockSize=200 \
|
||||
-Commit=true \
|
||||
-Seed=99 \
|
||||
-Period=5 \
|
||||
-Params=/path/to/params.json \
|
||||
-v -timeout 24h
|
||||
|
||||
To export the simulation params to a file at a given block height:
|
||||
|
||||
$ go test -mod=readonly github.com/cosmos/cosmos-sdk/simapp \
|
||||
-run=TestFullAppSimulation \
|
||||
-Enabled=true \
|
||||
-NumBlocks=100 \
|
||||
-BlockSize=200 \
|
||||
-Commit=true \
|
||||
-Seed=99 \
|
||||
-Period=5 \
|
||||
-ExportParamsPath=/path/to/params.json \
|
||||
-ExportParamsHeight=50 \
|
||||
-v -timeout 24h
|
||||
|
||||
|
||||
To export the simulation app state (i.e genesis) to a file:
|
||||
|
||||
$ go test -mod=readonly github.com/cosmos/cosmos-sdk/simapp \
|
||||
-run=TestFullAppSimulation \
|
||||
-Enabled=true \
|
||||
-NumBlocks=100 \
|
||||
-BlockSize=200 \
|
||||
-Commit=true \
|
||||
-Seed=99 \
|
||||
-Period=5 \
|
||||
-ExportStatePath=/path/to/genesis.json \
|
||||
v -timeout 24h
|
||||
|
||||
Params
|
||||
|
||||
Params that are provided to simulation from a JSON file are used to used to set
|
||||
both module parameters and simulation parameters. See sim_test.go for the full
|
||||
set of parameters that can be provided.
|
||||
*/
|
||||
package simulation
|
||||
|
|
|
@ -2,51 +2,21 @@ package simulation
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"time"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
// nolint
|
||||
const (
|
||||
// Minimum time per block
|
||||
minTimePerBlock int64 = 10000 / 2
|
||||
|
||||
// Maximum time per block
|
||||
maxTimePerBlock int64 = 10000
|
||||
|
||||
// Simulation parameter constants
|
||||
SendEnabled = "send_enabled"
|
||||
MaxMemoChars = "max_memo_characters"
|
||||
TxSigLimit = "tx_sig_limit"
|
||||
TxSizeCostPerByte = "tx_size_cost_per_byte"
|
||||
SigVerifyCostED25519 = "sig_verify_cost_ed25519"
|
||||
SigVerifyCostSECP256K1 = "sig_verify_cost_secp256k1"
|
||||
DepositParamsMinDeposit = "deposit_params_min_deposit"
|
||||
VotingParamsVotingPeriod = "voting_params_voting_period"
|
||||
TallyParamsQuorum = "tally_params_quorum"
|
||||
TallyParamsThreshold = "tally_params_threshold"
|
||||
TallyParamsVeto = "tally_params_veto"
|
||||
UnbondingTime = "unbonding_time"
|
||||
MaxValidators = "max_validators"
|
||||
SignedBlocksWindow = "signed_blocks_window"
|
||||
MinSignedPerWindow = "min_signed_per_window"
|
||||
DowntimeJailDuration = "downtime_jail_duration"
|
||||
SlashFractionDoubleSign = "slash_fraction_double_sign"
|
||||
SlashFractionDowntime = "slash_fraction_downtime"
|
||||
InflationRateChange = "inflation_rate_change"
|
||||
Inflation = "inflation"
|
||||
InflationMax = "inflation_max"
|
||||
InflationMin = "inflation_min"
|
||||
GoalBonded = "goal_bonded"
|
||||
CommunityTax = "community_tax"
|
||||
BaseProposerReward = "base_proposer_reward"
|
||||
BonusProposerReward = "bonus_proposer_reward"
|
||||
)
|
||||
|
||||
// TODO explain transitional matrix usage
|
||||
// TODO: explain transitional matrix usage
|
||||
var (
|
||||
// Currently there are 3 different liveness types,
|
||||
// fully online, spotty connection, offline.
|
||||
|
@ -63,97 +33,15 @@ var (
|
|||
{15, 92, 1},
|
||||
{0, 3, 99},
|
||||
})
|
||||
|
||||
// ModuleParamSimulator defines module parameter value simulators. All
|
||||
// values simulated should be within valid acceptable range for the given
|
||||
// parameter.
|
||||
ModuleParamSimulator = map[string]func(r *rand.Rand) interface{}{
|
||||
SendEnabled: func(r *rand.Rand) interface{} {
|
||||
return r.Int63n(2) == 0
|
||||
},
|
||||
MaxMemoChars: func(r *rand.Rand) interface{} {
|
||||
return uint64(RandIntBetween(r, 100, 200))
|
||||
},
|
||||
TxSigLimit: func(r *rand.Rand) interface{} {
|
||||
return uint64(r.Intn(7) + 1)
|
||||
},
|
||||
TxSizeCostPerByte: func(r *rand.Rand) interface{} {
|
||||
return uint64(RandIntBetween(r, 5, 15))
|
||||
},
|
||||
SigVerifyCostED25519: func(r *rand.Rand) interface{} {
|
||||
return uint64(RandIntBetween(r, 500, 1000))
|
||||
},
|
||||
SigVerifyCostSECP256K1: func(r *rand.Rand) interface{} {
|
||||
return uint64(RandIntBetween(r, 500, 1000))
|
||||
},
|
||||
DepositParamsMinDeposit: func(r *rand.Rand) interface{} {
|
||||
return sdk.Coins{sdk.NewInt64Coin(sdk.DefaultBondDenom, int64(RandIntBetween(r, 1, 1e3)))}
|
||||
},
|
||||
VotingParamsVotingPeriod: func(r *rand.Rand) interface{} {
|
||||
return time.Duration(RandIntBetween(r, 1, 2*60*60*24*2)) * time.Second
|
||||
},
|
||||
TallyParamsQuorum: func(r *rand.Rand) interface{} {
|
||||
return sdk.NewDecWithPrec(int64(RandIntBetween(r, 334, 500)), 3)
|
||||
},
|
||||
TallyParamsThreshold: func(r *rand.Rand) interface{} {
|
||||
return sdk.NewDecWithPrec(int64(RandIntBetween(r, 450, 550)), 3)
|
||||
},
|
||||
TallyParamsVeto: func(r *rand.Rand) interface{} {
|
||||
return sdk.NewDecWithPrec(int64(RandIntBetween(r, 250, 334)), 3)
|
||||
},
|
||||
UnbondingTime: func(r *rand.Rand) interface{} {
|
||||
return time.Duration(RandIntBetween(r, 60, 60*60*24*3*2)) * time.Second
|
||||
},
|
||||
MaxValidators: func(r *rand.Rand) interface{} {
|
||||
return uint16(r.Intn(250) + 1)
|
||||
},
|
||||
SignedBlocksWindow: func(r *rand.Rand) interface{} {
|
||||
return int64(RandIntBetween(r, 10, 1000))
|
||||
},
|
||||
MinSignedPerWindow: func(r *rand.Rand) interface{} {
|
||||
return sdk.NewDecWithPrec(int64(r.Intn(10)), 1)
|
||||
},
|
||||
DowntimeJailDuration: func(r *rand.Rand) interface{} {
|
||||
return time.Duration(RandIntBetween(r, 60, 60*60*24)) * time.Second
|
||||
},
|
||||
SlashFractionDoubleSign: func(r *rand.Rand) interface{} {
|
||||
return sdk.NewDec(1).Quo(sdk.NewDec(int64(r.Intn(50) + 1)))
|
||||
},
|
||||
SlashFractionDowntime: func(r *rand.Rand) interface{} {
|
||||
return sdk.NewDec(1).Quo(sdk.NewDec(int64(r.Intn(200) + 1)))
|
||||
},
|
||||
InflationRateChange: func(r *rand.Rand) interface{} {
|
||||
return sdk.NewDecWithPrec(int64(r.Intn(99)), 2)
|
||||
},
|
||||
Inflation: func(r *rand.Rand) interface{} {
|
||||
return sdk.NewDecWithPrec(int64(r.Intn(99)), 2)
|
||||
},
|
||||
InflationMax: func(r *rand.Rand) interface{} {
|
||||
return sdk.NewDecWithPrec(20, 2)
|
||||
},
|
||||
InflationMin: func(r *rand.Rand) interface{} {
|
||||
return sdk.NewDecWithPrec(7, 2)
|
||||
},
|
||||
GoalBonded: func(r *rand.Rand) interface{} {
|
||||
return sdk.NewDecWithPrec(67, 2)
|
||||
},
|
||||
CommunityTax: func(r *rand.Rand) interface{} {
|
||||
return sdk.NewDecWithPrec(1, 2).Add(sdk.NewDecWithPrec(int64(r.Intn(30)), 2))
|
||||
},
|
||||
BaseProposerReward: func(r *rand.Rand) interface{} {
|
||||
return sdk.NewDecWithPrec(1, 2).Add(sdk.NewDecWithPrec(int64(r.Intn(30)), 2))
|
||||
},
|
||||
BonusProposerReward: func(r *rand.Rand) interface{} {
|
||||
return sdk.NewDecWithPrec(1, 2).Add(sdk.NewDecWithPrec(int64(r.Intn(30)), 2))
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
// TODO add description
|
||||
type (
|
||||
AppParams map[string]json.RawMessage
|
||||
ParamSimulator func(r *rand.Rand)
|
||||
)
|
||||
// AppParams defines a flat JSON of key/values for all possible configurable
|
||||
// simulation parameters. It might contain: operation weights, simulation parameters
|
||||
// and flattened module state parameters (i.e not stored under it's respective module name).
|
||||
type AppParams map[string]json.RawMessage
|
||||
|
||||
// ParamSimulator creates a parameter value from a source of random number
|
||||
type ParamSimulator func(r *rand.Rand)
|
||||
|
||||
// GetOrGenerate attempts to get a given parameter by key from the AppParams
|
||||
// object. If it exists, it'll be decoded and returned. Otherwise, the provided
|
||||
|
@ -167,7 +55,7 @@ func (sp AppParams) GetOrGenerate(cdc *codec.Codec, key string, ptr interface{},
|
|||
ps(r)
|
||||
}
|
||||
|
||||
// Simulation parameters
|
||||
// Params define the parameters necessary for running the simulations
|
||||
type Params struct {
|
||||
PastEvidenceFraction float64
|
||||
NumKeys int
|
||||
|
@ -177,7 +65,7 @@ type Params struct {
|
|||
BlockSizeTransitionMatrix TransitionMatrix
|
||||
}
|
||||
|
||||
// Return random simulation parameters
|
||||
// RandomParams for simulation
|
||||
func RandomParams(r *rand.Rand) Params {
|
||||
return Params{
|
||||
PastEvidenceFraction: r.Float64(),
|
||||
|
@ -188,3 +76,32 @@ func RandomParams(r *rand.Rand) Params {
|
|||
BlockSizeTransitionMatrix: defaultBlockSizeTransitionMatrix,
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Param change proposals
|
||||
|
||||
// SimValFn function to generate the randomized parameter change value
|
||||
type SimValFn func(r *rand.Rand) string
|
||||
|
||||
// ParamChange defines the object used for simulating parameter change proposals
|
||||
type ParamChange struct {
|
||||
Subspace string
|
||||
Key string
|
||||
Subkey string
|
||||
SimValue SimValFn
|
||||
}
|
||||
|
||||
// NewSimParamChange creates a new ParamChange instance
|
||||
func NewSimParamChange(subspace, key, subkey string, simVal SimValFn) ParamChange {
|
||||
return ParamChange{
|
||||
Subspace: subspace,
|
||||
Key: key,
|
||||
Subkey: subkey,
|
||||
SimValue: simVal,
|
||||
}
|
||||
}
|
||||
|
||||
// ComposedKey creates a new composed key for the param change proposal
|
||||
func (spc ParamChange) ComposedKey() string {
|
||||
return fmt.Sprintf("%s/%s/%s", spc.Subspace, spc.Key, spc.Subkey)
|
||||
}
|
||||
|
|
|
@ -18,7 +18,8 @@ const (
|
|||
|
||||
// shamelessly copied from
|
||||
// https://stackoverflow.com/questions/22892120/how-to-generate-a-random-string-of-a-fixed-length-in-golang#31832326
|
||||
// Generate a random string of a particular length
|
||||
|
||||
// RandStringOfLength generates a random string of a particular length
|
||||
func RandStringOfLength(r *rand.Rand, n int) string {
|
||||
b := make([]byte, n)
|
||||
// A src.Int63() generates 63 random bits, enough for letterIdxMax characters!
|
||||
|
@ -36,7 +37,7 @@ func RandStringOfLength(r *rand.Rand, n int) string {
|
|||
return string(b)
|
||||
}
|
||||
|
||||
// get a rand positive sdk.Int
|
||||
// RandPositiveInt get a rand positive sdk.Int
|
||||
func RandPositiveInt(r *rand.Rand, max sdk.Int) (sdk.Int, error) {
|
||||
if !max.GT(sdk.OneInt()) {
|
||||
return sdk.Int{}, errors.New("max too small")
|
||||
|
@ -45,7 +46,7 @@ func RandPositiveInt(r *rand.Rand, max sdk.Int) (sdk.Int, error) {
|
|||
return sdk.NewIntFromBigInt(new(big.Int).Rand(r, max.BigInt())).Add(sdk.OneInt()), nil
|
||||
}
|
||||
|
||||
// Generate a random amount
|
||||
// RandomAmount generates a random amount
|
||||
// Note: The range of RandomAmount includes max, and is, in fact, biased to return max as well as 0.
|
||||
func RandomAmount(r *rand.Rand, max sdk.Int) sdk.Int {
|
||||
var randInt = big.NewInt(0)
|
||||
|
@ -87,9 +88,10 @@ func RandIntBetween(r *rand.Rand, min, max int) int {
|
|||
return r.Intn(max-min) + min
|
||||
}
|
||||
|
||||
// Derive a new rand deterministically from a rand.
|
||||
// DeriveRand derives a new Rand deterministically from another random source.
|
||||
// Unlike rand.New(rand.NewSource(seed)), the result is "more random"
|
||||
// depending on the source and state of r.
|
||||
//
|
||||
// NOTE: not crypto safe.
|
||||
func DeriveRand(r *rand.Rand) *rand.Rand {
|
||||
const num = 8 // TODO what's a good number? Too large is too slow.
|
||||
|
|
|
@ -52,7 +52,7 @@ type Params struct {
|
|||
// NewParams creates a new Params object
|
||||
func NewParams(maxEvidenceAge time.Duration, signedBlocksWindow int64,
|
||||
minSignedPerWindow sdk.Dec, downtimeJailDuration time.Duration,
|
||||
slashFractionDoubleSign sdk.Dec, slashFractionDowntime sdk.Dec) Params {
|
||||
slashFractionDoubleSign, slashFractionDowntime sdk.Dec) Params {
|
||||
|
||||
return Params{
|
||||
MaxEvidenceAge: maxEvidenceAge,
|
||||
|
|
|
@ -2,6 +2,7 @@ package slashing
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"math/rand"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/spf13/cobra"
|
||||
|
@ -12,6 +13,7 @@ import (
|
|||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/module"
|
||||
sim "github.com/cosmos/cosmos-sdk/x/simulation"
|
||||
"github.com/cosmos/cosmos-sdk/x/slashing/client/cli"
|
||||
"github.com/cosmos/cosmos-sdk/x/slashing/client/rest"
|
||||
"github.com/cosmos/cosmos-sdk/x/slashing/internal/types"
|
||||
|
@ -80,6 +82,16 @@ func (AppModuleSimulation) RegisterStoreDecoder(sdr sdk.StoreDecoderRegistry) {
|
|||
sdr[StoreKey] = simulation.DecodeStore
|
||||
}
|
||||
|
||||
// GenerateGenesisState creates a randomized GenState of the slashing module.
|
||||
func (AppModuleSimulation) GenerateGenesisState(simState *module.SimulationState) {
|
||||
simulation.RandomizedGenState(simState)
|
||||
}
|
||||
|
||||
// RandomizedParams creates randomized slashing param changes for the simulator.
|
||||
func (AppModuleSimulation) RandomizedParams(r *rand.Rand) []sim.ParamChange {
|
||||
return simulation.ParamChanges(r)
|
||||
}
|
||||
|
||||
//____________________________________________________________________________
|
||||
|
||||
// AppModule implements an application module for the slashing module.
|
||||
|
|
|
@ -0,0 +1,93 @@
|
|||
package simulation
|
||||
|
||||
// DONTCOVER
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"time"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/module"
|
||||
"github.com/cosmos/cosmos-sdk/x/simulation"
|
||||
"github.com/cosmos/cosmos-sdk/x/slashing/internal/types"
|
||||
)
|
||||
|
||||
// Simulation parameter constants
|
||||
const (
|
||||
SignedBlocksWindow = "signed_blocks_window"
|
||||
MinSignedPerWindow = "min_signed_per_window"
|
||||
DowntimeJailDuration = "downtime_jail_duration"
|
||||
SlashFractionDoubleSign = "slash_fraction_double_sign"
|
||||
SlashFractionDowntime = "slash_fraction_downtime"
|
||||
)
|
||||
|
||||
// GenSignedBlocksWindow randomized SignedBlocksWindow
|
||||
func GenSignedBlocksWindow(r *rand.Rand) int64 {
|
||||
return int64(simulation.RandIntBetween(r, 10, 1000))
|
||||
}
|
||||
|
||||
// GenMinSignedPerWindow randomized MinSignedPerWindow
|
||||
func GenMinSignedPerWindow(r *rand.Rand) sdk.Dec {
|
||||
return sdk.NewDecWithPrec(int64(r.Intn(10)), 1)
|
||||
}
|
||||
|
||||
// GenDowntimeJailDuration randomized DowntimeJailDuration
|
||||
func GenDowntimeJailDuration(r *rand.Rand) time.Duration {
|
||||
return time.Duration(simulation.RandIntBetween(r, 60, 60*60*24)) * time.Second
|
||||
}
|
||||
|
||||
// GenSlashFractionDoubleSign randomized SlashFractionDoubleSign
|
||||
func GenSlashFractionDoubleSign(r *rand.Rand) sdk.Dec {
|
||||
return sdk.NewDec(1).Quo(sdk.NewDec(int64(r.Intn(50) + 1)))
|
||||
}
|
||||
|
||||
// GenSlashFractionDowntime randomized SlashFractionDowntime
|
||||
func GenSlashFractionDowntime(r *rand.Rand) sdk.Dec {
|
||||
return sdk.NewDec(1).Quo(sdk.NewDec(int64(r.Intn(200) + 1)))
|
||||
}
|
||||
|
||||
// RandomizedGenState generates a random GenesisState for slashing
|
||||
func RandomizedGenState(simState *module.SimulationState) {
|
||||
var signedBlocksWindow int64
|
||||
simState.AppParams.GetOrGenerate(
|
||||
simState.Cdc, SignedBlocksWindow, &signedBlocksWindow, simState.Rand,
|
||||
func(r *rand.Rand) { signedBlocksWindow = GenSignedBlocksWindow(r) },
|
||||
)
|
||||
|
||||
var minSignedPerWindow sdk.Dec
|
||||
simState.AppParams.GetOrGenerate(
|
||||
simState.Cdc, MinSignedPerWindow, &minSignedPerWindow, simState.Rand,
|
||||
func(r *rand.Rand) { minSignedPerWindow = GenMinSignedPerWindow(r) },
|
||||
)
|
||||
|
||||
var downtimeJailDuration time.Duration
|
||||
simState.AppParams.GetOrGenerate(
|
||||
simState.Cdc, DowntimeJailDuration, &downtimeJailDuration, simState.Rand,
|
||||
func(r *rand.Rand) { downtimeJailDuration = GenDowntimeJailDuration(r) },
|
||||
)
|
||||
|
||||
var slashFractionDoubleSign sdk.Dec
|
||||
simState.AppParams.GetOrGenerate(
|
||||
simState.Cdc, SlashFractionDoubleSign, &slashFractionDoubleSign, simState.Rand,
|
||||
func(r *rand.Rand) { slashFractionDoubleSign = GenSlashFractionDoubleSign(r) },
|
||||
)
|
||||
|
||||
var slashFractionDowntime sdk.Dec
|
||||
simState.AppParams.GetOrGenerate(
|
||||
simState.Cdc, SlashFractionDowntime, &slashFractionDowntime, simState.Rand,
|
||||
func(r *rand.Rand) { slashFractionDowntime = GenSlashFractionDowntime(r) },
|
||||
)
|
||||
|
||||
params := types.NewParams(
|
||||
simState.UnbondTime, signedBlocksWindow, minSignedPerWindow,
|
||||
downtimeJailDuration, slashFractionDoubleSign, slashFractionDowntime,
|
||||
)
|
||||
|
||||
slashingGenesis := types.NewGenesisState(params, nil, nil)
|
||||
|
||||
fmt.Printf("Selected randomly generated slashing parameters:\n%s\n", codec.MustMarshalJSONIndent(simState.Cdc, slashingGenesis.Params))
|
||||
simState.GenState[types.ModuleName] = simState.Cdc.MustMarshalJSON(slashingGenesis)
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
package simulation
|
||||
|
||||
// DONTCOVER
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/x/simulation"
|
||||
"github.com/cosmos/cosmos-sdk/x/slashing/internal/types"
|
||||
)
|
||||
|
||||
const (
|
||||
keySignedBlocksWindow = "SignedBlocksWindow"
|
||||
keyMinSignedPerWindow = "MinSignedPerWindow"
|
||||
keySlashFractionDowntime = "SlashFractionDowntime"
|
||||
)
|
||||
|
||||
// ParamChanges defines the parameters that can be modified by param change proposals
|
||||
// on the simulation
|
||||
func ParamChanges(r *rand.Rand) []simulation.ParamChange {
|
||||
return []simulation.ParamChange{
|
||||
simulation.NewSimParamChange(types.ModuleName, keySignedBlocksWindow, "",
|
||||
func(r *rand.Rand) string {
|
||||
return fmt.Sprintf("\"%d\"", GenSignedBlocksWindow(r))
|
||||
},
|
||||
),
|
||||
simulation.NewSimParamChange(types.ModuleName, keyMinSignedPerWindow, "",
|
||||
func(r *rand.Rand) string {
|
||||
return fmt.Sprintf("\"%s\"", GenMinSignedPerWindow(r))
|
||||
},
|
||||
),
|
||||
simulation.NewSimParamChange(types.ModuleName, keySlashFractionDowntime, "",
|
||||
func(r *rand.Rand) string {
|
||||
return fmt.Sprintf("\"%s\"", GenSlashFractionDowntime(r))
|
||||
},
|
||||
),
|
||||
}
|
||||
}
|
|
@ -2,6 +2,7 @@ package staking
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"math/rand"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/spf13/cobra"
|
||||
|
@ -16,6 +17,7 @@ import (
|
|||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/module"
|
||||
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||
sim "github.com/cosmos/cosmos-sdk/x/simulation"
|
||||
"github.com/cosmos/cosmos-sdk/x/staking/client/cli"
|
||||
"github.com/cosmos/cosmos-sdk/x/staking/client/rest"
|
||||
"github.com/cosmos/cosmos-sdk/x/staking/simulation"
|
||||
|
@ -105,6 +107,16 @@ func (AppModuleSimulation) RegisterStoreDecoder(sdr sdk.StoreDecoderRegistry) {
|
|||
sdr[StoreKey] = simulation.DecodeStore
|
||||
}
|
||||
|
||||
// GenerateGenesisState creates a randomized GenState of the staking module.
|
||||
func (AppModuleSimulation) GenerateGenesisState(simState *module.SimulationState) {
|
||||
simulation.RandomizedGenState(simState)
|
||||
}
|
||||
|
||||
// RandomizedParams creates randomized staking param changes for the simulator.
|
||||
func (AppModuleSimulation) RandomizedParams(r *rand.Rand) []sim.ParamChange {
|
||||
return simulation.ParamChanges(r)
|
||||
}
|
||||
|
||||
//____________________________________________________________________________
|
||||
|
||||
// AppModule implements an application module for the staking module.
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
package simulation
|
||||
|
||||
// DONTCOVER
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"time"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/module"
|
||||
"github.com/cosmos/cosmos-sdk/x/simulation"
|
||||
"github.com/cosmos/cosmos-sdk/x/staking/types"
|
||||
)
|
||||
|
||||
// Simulation parameter constants
|
||||
const (
|
||||
UnbondingTime = "unbonding_time"
|
||||
MaxValidators = "max_validators"
|
||||
)
|
||||
|
||||
// GenUnbondingTime randomized UnbondingTime
|
||||
func GenUnbondingTime(r *rand.Rand) (ubdTime time.Duration) {
|
||||
return time.Duration(simulation.RandIntBetween(r, 60, 60*60*24*3*2)) * time.Second
|
||||
}
|
||||
|
||||
// GenMaxValidators randomized MaxValidators
|
||||
func GenMaxValidators(r *rand.Rand) (maxValidators uint16) {
|
||||
return uint16(r.Intn(250) + 1)
|
||||
}
|
||||
|
||||
// RandomizedGenState generates a random GenesisState for staking
|
||||
func RandomizedGenState(simState *module.SimulationState) {
|
||||
// params
|
||||
var unbondTime time.Duration
|
||||
simState.AppParams.GetOrGenerate(
|
||||
simState.Cdc, UnbondingTime, &unbondTime, simState.Rand,
|
||||
func(r *rand.Rand) { unbondTime = GenUnbondingTime(r) },
|
||||
)
|
||||
|
||||
var maxValidators uint16
|
||||
simState.AppParams.GetOrGenerate(
|
||||
simState.Cdc, MaxValidators, &maxValidators, simState.Rand,
|
||||
func(r *rand.Rand) { maxValidators = GenMaxValidators(r) },
|
||||
)
|
||||
|
||||
// NOTE: the slashing module need to be defined after the staking module on the
|
||||
// NewSimulationManager constructor for this to work
|
||||
simState.UnbondTime = unbondTime
|
||||
|
||||
params := types.NewParams(simState.UnbondTime, maxValidators, 7, sdk.DefaultBondDenom)
|
||||
|
||||
// validators & delegations
|
||||
var (
|
||||
validators []types.Validator
|
||||
delegations []types.Delegation
|
||||
)
|
||||
|
||||
valAddrs := make([]sdk.ValAddress, simState.NumBonded)
|
||||
for i := 0; i < int(simState.NumBonded); i++ {
|
||||
valAddr := sdk.ValAddress(simState.Accounts[i].Address)
|
||||
valAddrs[i] = valAddr
|
||||
|
||||
validator := types.NewValidator(valAddr, simState.Accounts[i].PubKey, types.Description{})
|
||||
validator.Tokens = sdk.NewInt(simState.InitialStake)
|
||||
validator.DelegatorShares = sdk.NewDec(simState.InitialStake)
|
||||
delegation := types.NewDelegation(simState.Accounts[i].Address, valAddr, sdk.NewDec(simState.InitialStake))
|
||||
validators = append(validators, validator)
|
||||
delegations = append(delegations, delegation)
|
||||
}
|
||||
|
||||
stakingGenesis := types.NewGenesisState(params, validators, delegations)
|
||||
|
||||
fmt.Printf("Selected randomly generated staking parameters:\n%s\n", codec.MustMarshalJSONIndent(simState.Cdc, stakingGenesis.Params))
|
||||
simState.GenState[types.ModuleName] = simState.Cdc.MustMarshalJSON(stakingGenesis)
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
package simulation
|
||||
|
||||
// DONTCOVER
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/x/simulation"
|
||||
"github.com/cosmos/cosmos-sdk/x/staking/types"
|
||||
)
|
||||
|
||||
const (
|
||||
keyMaxValidators = "MaxValidators"
|
||||
keyUnbondingTime = "UnbondingTime"
|
||||
)
|
||||
|
||||
// ParamChanges defines the parameters that can be modified by param change proposals
|
||||
// on the simulation
|
||||
func ParamChanges(r *rand.Rand) []simulation.ParamChange {
|
||||
return []simulation.ParamChange{
|
||||
simulation.NewSimParamChange(types.ModuleName, keyMaxValidators, "",
|
||||
func(r *rand.Rand) string {
|
||||
return fmt.Sprintf("%d", GenMaxValidators(r))
|
||||
},
|
||||
),
|
||||
simulation.NewSimParamChange(types.ModuleName, keyUnbondingTime, "",
|
||||
func(r *rand.Rand) string {
|
||||
return fmt.Sprintf("\"%d\"", GenUnbondingTime(r))
|
||||
},
|
||||
),
|
||||
}
|
||||
}
|
|
@ -2,6 +2,7 @@ package supply
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"math/rand"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/spf13/cobra"
|
||||
|
@ -12,6 +13,7 @@ import (
|
|||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/module"
|
||||
sim "github.com/cosmos/cosmos-sdk/x/simulation"
|
||||
"github.com/cosmos/cosmos-sdk/x/supply/client/cli"
|
||||
"github.com/cosmos/cosmos-sdk/x/supply/client/rest"
|
||||
"github.com/cosmos/cosmos-sdk/x/supply/internal/types"
|
||||
|
@ -21,7 +23,7 @@ import (
|
|||
var (
|
||||
_ module.AppModule = AppModule{}
|
||||
_ module.AppModuleBasic = AppModuleBasic{}
|
||||
_ module.AppModuleSimulation = AppModuleSimulation{}
|
||||
_ module.AppModuleSimulation = AppModule{}
|
||||
)
|
||||
|
||||
// AppModuleBasic defines the basic application module used by the supply module.
|
||||
|
@ -76,6 +78,16 @@ func (AppModuleSimulation) RegisterStoreDecoder(sdr sdk.StoreDecoderRegistry) {
|
|||
sdr[StoreKey] = simulation.DecodeStore
|
||||
}
|
||||
|
||||
// GenerateGenesisState creates a randomized GenState of the supply module.
|
||||
func (AppModuleSimulation) GenerateGenesisState(simState *module.SimulationState) {
|
||||
simulation.RandomizedGenState(simState)
|
||||
}
|
||||
|
||||
// RandomizedParams doesn't create any randomized supply param changes for the simulator.
|
||||
func (AppModuleSimulation) RandomizedParams(_ *rand.Rand) []sim.ParamChange {
|
||||
return nil
|
||||
}
|
||||
|
||||
//____________________________________________________________________________
|
||||
|
||||
// AppModule implements an application module for the supply module.
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
package simulation
|
||||
|
||||
// DONTCOVER
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/module"
|
||||
"github.com/cosmos/cosmos-sdk/x/supply/internal/types"
|
||||
)
|
||||
|
||||
// RandomizedGenState generates a random GenesisState for supply
|
||||
func RandomizedGenState(simState *module.SimulationState) {
|
||||
numAccs := int64(len(simState.Accounts))
|
||||
totalSupply := sdk.NewInt(simState.InitialStake * (numAccs + simState.NumBonded))
|
||||
supplyGenesis := types.NewGenesisState(sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, totalSupply)))
|
||||
|
||||
fmt.Printf("Generated supply parameters:\n%s\n", codec.MustMarshalJSONIndent(simState.Cdc, supplyGenesis))
|
||||
simState.GenState[types.ModuleName] = simState.Cdc.MustMarshalJSON(supplyGenesis)
|
||||
}
|
Loading…
Reference in New Issue