Merge PR #3428: Simulate from a genesis file
This commit is contained in:
parent
0ed6de0cbd
commit
9320dbb2da
20
Makefile
20
Makefile
@ -153,9 +153,15 @@ test_sim_gaia_nondeterminism:
|
||||
@echo "Running nondeterminism test..."
|
||||
@go test ./cmd/gaia/app -run TestAppStateDeterminism -SimulationEnabled=true -v -timeout 10m
|
||||
|
||||
test_sim_gaia_custom_genesis_fast:
|
||||
@echo "Running custom genesis simulation..."
|
||||
@echo "By default, ${HOME}/.gaiad/config/genesis.json will be used."
|
||||
@go test ./cmd/gaia/app -run TestFullGaiaSimulation -SimulationGenesis=${HOME}/.gaiad/config/genesis.json \
|
||||
-SimulationEnabled=true -SimulationNumBlocks=100 -SimulationBlockSize=200 -SimulationCommit=true -SimulationSeed=99 -SimulationPeriod=5 -v -timeout 24h
|
||||
|
||||
test_sim_gaia_fast:
|
||||
@echo "Running quick Gaia simulation. This may take several minutes..."
|
||||
@go test ./cmd/gaia/app -run TestFullGaiaSimulation -SimulationEnabled=true -SimulationNumBlocks=1000 -SimulationBlockSize=200 -SimulationCommit=true -SimulationSeed=99 -v -timeout 24h
|
||||
@go test ./cmd/gaia/app -run TestFullGaiaSimulation -SimulationEnabled=true -SimulationNumBlocks=100 -SimulationBlockSize=200 -SimulationCommit=true -SimulationSeed=99 -SimulationPeriod=5 -v -timeout 24h
|
||||
|
||||
test_sim_gaia_import_export:
|
||||
@echo "Running Gaia import/export simulation. This may take several minutes..."
|
||||
@ -165,6 +171,11 @@ test_sim_gaia_simulation_after_import:
|
||||
@echo "Running Gaia simulation-after-import. This may take several minutes..."
|
||||
@bash scripts/multisim.sh 50 5 TestGaiaSimulationAfterImport
|
||||
|
||||
test_sim_gaia_custom_genesis_multi_seed:
|
||||
@echo "Running multi-seed custom genesis simulation..."
|
||||
@echo "By default, ${HOME}/.gaiad/config/genesis.json will be used."
|
||||
@bash scripts/multisim.sh 400 5 TestFullGaiaSimulation ${HOME}/.gaiad/config/genesis.json
|
||||
|
||||
test_sim_gaia_multi_seed:
|
||||
@echo "Running multi-seed Gaia simulation. This may take awhile!"
|
||||
@bash scripts/multisim.sh 400 5 TestFullGaiaSimulation
|
||||
@ -174,11 +185,13 @@ SIM_BLOCK_SIZE ?= 200
|
||||
SIM_COMMIT ?= true
|
||||
test_sim_gaia_benchmark:
|
||||
@echo "Running Gaia benchmark for numBlocks=$(SIM_NUM_BLOCKS), blockSize=$(SIM_BLOCK_SIZE). This may take awhile!"
|
||||
@go test -benchmem -run=^$$ github.com/cosmos/cosmos-sdk/cmd/gaia/app -bench ^BenchmarkFullGaiaSimulation$$ -SimulationEnabled=true -SimulationNumBlocks=$(SIM_NUM_BLOCKS) -SimulationBlockSize=$(SIM_BLOCK_SIZE) -SimulationCommit=$(SIM_COMMIT) -timeout 24h
|
||||
@go test -benchmem -run=^$$ github.com/cosmos/cosmos-sdk/cmd/gaia/app -bench ^BenchmarkFullGaiaSimulation$$ \
|
||||
-SimulationEnabled=true -SimulationNumBlocks=$(SIM_NUM_BLOCKS) -SimulationBlockSize=$(SIM_BLOCK_SIZE) -SimulationCommit=$(SIM_COMMIT) -timeout 24h
|
||||
|
||||
test_sim_gaia_profile:
|
||||
@echo "Running Gaia benchmark for numBlocks=$(SIM_NUM_BLOCKS), blockSize=$(SIM_BLOCK_SIZE). This may take awhile!"
|
||||
@go test -benchmem -run=^$$ github.com/cosmos/cosmos-sdk/cmd/gaia/app -bench ^BenchmarkFullGaiaSimulation$$ -SimulationEnabled=true -SimulationNumBlocks=$(SIM_NUM_BLOCKS) -SimulationBlockSize=$(SIM_BLOCK_SIZE) -SimulationCommit=$(SIM_COMMIT) -timeout 24h -cpuprofile cpu.out -memprofile mem.out
|
||||
@go test -benchmem -run=^$$ github.com/cosmos/cosmos-sdk/cmd/gaia/app -bench ^BenchmarkFullGaiaSimulation$$ \
|
||||
-SimulationEnabled=true -SimulationNumBlocks=$(SIM_NUM_BLOCKS) -SimulationBlockSize=$(SIM_BLOCK_SIZE) -SimulationCommit=$(SIM_COMMIT) -timeout 24h -cpuprofile cpu.out -memprofile mem.out
|
||||
|
||||
test_cover:
|
||||
@export VERSION=$(VERSION); bash tests/test_cover.sh
|
||||
@ -258,5 +271,6 @@ check_tools check_dev_tools get_vendor_deps draw_deps test test_cli test_unit \
|
||||
test_cover test_lint benchmark devdoc_init devdoc devdoc_save devdoc_update \
|
||||
build-linux build-docker-gaiadnode localnet-start localnet-stop \
|
||||
format check-ledger test_sim_gaia_nondeterminism test_sim_modules test_sim_gaia_fast \
|
||||
test_sim_gaia_custom_genesis_fast test_sim_gaia_custom_genesis_multi_seed \
|
||||
test_sim_gaia_multi_seed test_sim_gaia_import_export update_tools update_dev_tools \
|
||||
build-snap-edge
|
||||
|
||||
@ -25,6 +25,7 @@ FEATURES
|
||||
|
||||
* Gaia
|
||||
- [\#3397](https://github.com/cosmos/cosmos-sdk/pull/3397) Implement genesis file sanitization to avoid failures at chain init.
|
||||
* \#3428 Run the simulation from a particular genesis state loaded from a file
|
||||
|
||||
* SDK
|
||||
* \#3270 [x/staking] limit number of ongoing unbonding delegations /redelegations per pair/trio
|
||||
|
||||
@ -13,8 +13,10 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
"github.com/tendermint/tendermint/crypto/secp256k1"
|
||||
dbm "github.com/tendermint/tendermint/libs/db"
|
||||
"github.com/tendermint/tendermint/libs/log"
|
||||
tmtypes "github.com/tendermint/tendermint/types"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/baseapp"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
@ -36,16 +38,18 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
seed int64
|
||||
numBlocks int
|
||||
blockSize int
|
||||
enabled bool
|
||||
verbose bool
|
||||
commit bool
|
||||
period int
|
||||
genesisFile string
|
||||
seed int64
|
||||
numBlocks int
|
||||
blockSize int
|
||||
enabled bool
|
||||
verbose bool
|
||||
commit bool
|
||||
period int
|
||||
)
|
||||
|
||||
func init() {
|
||||
flag.StringVar(&genesisFile, "SimulationGenesis", "", "Custom simulation genesis file")
|
||||
flag.Int64Var(&seed, "SimulationSeed", 42, "Simulation random seed")
|
||||
flag.IntVar(&numBlocks, "SimulationNumBlocks", 500, "Number of blocks")
|
||||
flag.IntVar(&blockSize, "SimulationBlockSize", 200, "Operations per block")
|
||||
@ -55,7 +59,31 @@ func init() {
|
||||
flag.IntVar(&period, "SimulationPeriod", 1, "Run slow invariants only once every period assertions")
|
||||
}
|
||||
|
||||
func appStateFn(r *rand.Rand, accs []simulation.Account, genesisTimestamp time.Time) json.RawMessage {
|
||||
func appStateFromGenesisFileFn(r *rand.Rand, accs []simulation.Account, genesisTimestamp time.Time) (json.RawMessage, []simulation.Account, string) {
|
||||
var genesis tmtypes.GenesisDoc
|
||||
cdc := MakeCodec()
|
||||
bytes, err := ioutil.ReadFile(genesisFile)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
cdc.MustUnmarshalJSON(bytes, &genesis)
|
||||
var appState GenesisState
|
||||
cdc.MustUnmarshalJSON(genesis.AppState, &appState)
|
||||
var newAccs []simulation.Account
|
||||
for _, acc := range appState.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)
|
||||
privKey := secp256k1.GenPrivKeySecp256k1(privkeySeed)
|
||||
newAccs = append(newAccs, simulation.Account{privKey, privKey.PubKey(), acc.Address})
|
||||
}
|
||||
return json.RawMessage(genesis.AppState), newAccs, genesis.ChainID
|
||||
}
|
||||
|
||||
func appStateRandomizedFn(r *rand.Rand, accs []simulation.Account, genesisTimestamp time.Time) (json.RawMessage, []simulation.Account, string) {
|
||||
|
||||
var genesisAccounts []GenesisAccount
|
||||
|
||||
amount := int64(r.Intn(1e6))
|
||||
@ -221,7 +249,14 @@ func appStateFn(r *rand.Rand, accs []simulation.Account, genesisTimestamp time.T
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return appState
|
||||
return appState, accs, "simulation"
|
||||
}
|
||||
|
||||
func appStateFn(r *rand.Rand, accs []simulation.Account, genesisTimestamp time.Time) (json.RawMessage, []simulation.Account, string) {
|
||||
if genesisFile != "" {
|
||||
return appStateFromGenesisFileFn(r, accs, genesisTimestamp)
|
||||
}
|
||||
return appStateRandomizedFn(r, accs, genesisTimestamp)
|
||||
}
|
||||
|
||||
func randIntBetween(r *rand.Rand, min, max int) int {
|
||||
|
||||
@ -5,10 +5,12 @@ seeds=(1 2 4 7 9 20 32 123 124 582 1893 2989 3012 4728 37827 981928 87821 891823
|
||||
blocks=$1
|
||||
period=$2
|
||||
testname=$3
|
||||
genesis=$4
|
||||
|
||||
echo "Running multi-seed simulation with seeds ${seeds[@]}"
|
||||
echo "Running $blocks blocks per seed"
|
||||
echo "Running test $testname"
|
||||
echo "Using genesis file $genesis"
|
||||
echo "Edit scripts/multisim.sh to add new seeds. Keeping parameters in the file makes failures easy to reproduce."
|
||||
echo "This script will kill all sub-simulations on SIGINT/SIGTERM (i.e. Ctrl-C)."
|
||||
|
||||
@ -22,7 +24,7 @@ sim() {
|
||||
echo "Running Gaia simulation with seed $seed. This may take awhile!"
|
||||
file="$tmpdir/gaia-simulation-seed-$seed-date-$(date -u +"%Y-%m-%dT%H:%M:%S+00:00").stdout"
|
||||
echo "Writing stdout to $file..."
|
||||
go test ./cmd/gaia/app -run $testname -SimulationEnabled=true -SimulationNumBlocks=$blocks \
|
||||
go test ./cmd/gaia/app -run $testname -SimulationEnabled=true -SimulationNumBlocks=$blocks -SimulationGenesis=$genesis \
|
||||
-SimulationVerbose=true -SimulationCommit=true -SimulationSeed=$seed -SimulationPeriod=$period -v -timeout 24h > $file
|
||||
}
|
||||
|
||||
|
||||
@ -18,8 +18,8 @@ import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
// AppStateFn returns the app state json bytes
|
||||
type AppStateFn func(r *rand.Rand, accs []Account, genesisTimestamp time.Time) json.RawMessage
|
||||
// AppStateFn returns the app state json bytes, the genesis accounts, and the chain identifier
|
||||
type AppStateFn func(r *rand.Rand, accs []Account, genesisTimestamp time.Time) (appState json.RawMessage, accounts []Account, chainId string)
|
||||
|
||||
// Simulate tests application by sending random messages.
|
||||
func Simulate(t *testing.T, app *baseapp.BaseApp,
|
||||
@ -35,15 +35,18 @@ func Simulate(t *testing.T, app *baseapp.BaseApp,
|
||||
func initChain(
|
||||
r *rand.Rand, params Params, accounts []Account,
|
||||
app *baseapp.BaseApp, appStateFn AppStateFn, genesisTimestamp time.Time,
|
||||
) mockValidators {
|
||||
) (mockValidators, []Account) {
|
||||
|
||||
appState, accounts, chainID := appStateFn(r, accounts, genesisTimestamp)
|
||||
|
||||
req := abci.RequestInitChain{
|
||||
AppStateBytes: appStateFn(r, accounts, genesisTimestamp),
|
||||
AppStateBytes: appState,
|
||||
ChainId: chainID,
|
||||
}
|
||||
res := app.InitChain(req)
|
||||
validators := newMockValidators(r, res.Validators, params)
|
||||
|
||||
return validators
|
||||
return validators, accounts
|
||||
}
|
||||
|
||||
// SimulateFromSeed tests an application by running the provided
|
||||
@ -73,7 +76,11 @@ func SimulateFromSeed(tb testing.TB, app *baseapp.BaseApp,
|
||||
|
||||
// Second variable to keep pending validator set (delayed one block since
|
||||
// TM 0.24) Initially this is the same as the initial validator set
|
||||
validators := initChain(r, params, accs, app, appStateFn, genesisTimestamp)
|
||||
validators, accs := initChain(r, params, accs, app, appStateFn, genesisTimestamp)
|
||||
if len(accs) == 0 {
|
||||
return true, fmt.Errorf("must have greater than zero genesis accounts")
|
||||
}
|
||||
|
||||
nextValidators := validators
|
||||
|
||||
header := abci.Header{
|
||||
|
||||
Loading…
Reference in New Issue
Block a user