Merge PR #3428: Simulate from a genesis file

This commit is contained in:
Christopher Goes 2019-01-29 23:53:42 +01:00 committed by GitHub
parent 0ed6de0cbd
commit 9320dbb2da
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 78 additions and 19 deletions

View File

@ -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

View File

@ -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

View File

@ -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 {

View File

@ -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
}

View 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{