Merge PR #86: Update SDK to version latest master

This commit is contained in:
Alexander Bezobchuk
2019-08-05 11:50:11 -04:00
committed by GitHub
parent 1536f96e8b
commit 10cde2212e
16 changed files with 428 additions and 314 deletions

View File

@@ -14,70 +14,77 @@ import (
"github.com/stretchr/testify/require"
abci "github.com/tendermint/tendermint/abci/types"
dbm "github.com/tendermint/tendermint/libs/db"
"github.com/tendermint/tendermint/libs/log"
dbm "github.com/tendermint/tm-db"
"github.com/cosmos/cosmos-sdk/baseapp"
"github.com/cosmos/cosmos-sdk/simapp"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/auth"
authsim "github.com/cosmos/cosmos-sdk/x/auth/simulation"
"github.com/cosmos/cosmos-sdk/x/bank"
distr "github.com/cosmos/cosmos-sdk/x/distribution"
distrsim "github.com/cosmos/cosmos-sdk/x/distribution/simulation"
"github.com/cosmos/cosmos-sdk/x/gov"
govsim "github.com/cosmos/cosmos-sdk/x/gov/simulation"
"github.com/cosmos/cosmos-sdk/x/mint"
"github.com/cosmos/cosmos-sdk/x/params"
paramsim "github.com/cosmos/cosmos-sdk/x/params/simulation"
"github.com/cosmos/cosmos-sdk/x/simulation"
"github.com/cosmos/cosmos-sdk/x/slashing"
slashingsim "github.com/cosmos/cosmos-sdk/x/slashing/simulation"
"github.com/cosmos/cosmos-sdk/x/staking"
stakingsim "github.com/cosmos/cosmos-sdk/x/staking/simulation"
)
var (
genesisFile string
paramsFile string
seed int64
numBlocks int
blockSize int
enabled bool
verbose bool
lean bool
commit bool
period int
onOperation bool // TODO Remove in favor of binary search for invariant violation
allInvariants bool
"github.com/cosmos/cosmos-sdk/x/supply"
)
func init() {
flag.StringVar(&genesisFile, "SimulationGenesis", "", "custom simulation genesis file; cannot be used with params file")
flag.StringVar(&paramsFile, "SimulationParams", "", "custom simulation params file which overrides any random params; cannot be used with genesis")
flag.Int64Var(&seed, "SimulationSeed", 42, "simulation random seed")
flag.IntVar(&numBlocks, "SimulationNumBlocks", 500, "number of blocks")
flag.IntVar(&blockSize, "SimulationBlockSize", 200, "operations per block")
flag.BoolVar(&enabled, "SimulationEnabled", false, "enable the simulation")
flag.BoolVar(&verbose, "SimulationVerbose", false, "verbose log output")
flag.BoolVar(&lean, "SimulationLean", false, "lean simulation log output")
flag.BoolVar(&commit, "SimulationCommit", false, "have the simulation commit")
flag.IntVar(&period, "SimulationPeriod", 1, "run slow invariants only once every period assertions")
flag.StringVar(&genesisFile, "Genesis", "", "custom simulation genesis file; cannot be used with params file")
flag.StringVar(&paramsFile, "Params", "", "custom simulation params file which overrides any random params; cannot be used with genesis")
flag.StringVar(&exportParamsPath, "ExportParamsPath", "", "custom file path to save the exported params JSON")
flag.IntVar(&exportParamsHeight, "ExportParamsHeight", 0, "height to which export the randomly generated params")
flag.StringVar(&exportStatePath, "ExportStatePath", "", "custom file path to save the exported app state JSON")
flag.StringVar(&exportStatsPath, "ExportStatsPath", "", "custom file path to save the exported simulation statistics JSON")
flag.Int64Var(&seed, "Seed", 42, "simulation random seed")
flag.IntVar(&initialBlockHeight, "InitialBlockHeight", 1, "initial block to start the simulation")
flag.IntVar(&numBlocks, "NumBlocks", 500, "number of new blocks to simulate from the initial block height")
flag.IntVar(&blockSize, "BlockSize", 200, "operations per block")
flag.BoolVar(&enabled, "Enabled", false, "enable the simulation")
flag.BoolVar(&verbose, "Verbose", false, "verbose log output")
flag.BoolVar(&lean, "Lean", false, "lean simulation log output")
flag.BoolVar(&commit, "Commit", false, "have the simulation commit")
flag.IntVar(&period, "Period", 1, "run slow invariants only once every period assertions")
flag.BoolVar(&onOperation, "SimulateEveryOperation", false, "run slow invariants every operation")
flag.BoolVar(&allInvariants, "PrintAllInvariants", false, "print all invariants if a broken invariant is found")
flag.Int64Var(&genesisTime, "GenesisTime", 0, "override genesis UNIX time instead of using a random UNIX time")
}
// helper function for populating input for SimulateFromSeed
func getSimulateFromSeedInput(tb testing.TB, w io.Writer, app *GaiaApp) (
testing.TB, io.Writer, *baseapp.BaseApp, simulation.AppStateFn, int64,
simulation.WeightedOperations, sdk.Invariants, int, int, bool, bool, bool, bool, map[string]bool,
) {
simulation.WeightedOperations, sdk.Invariants, int, int, int, int, string,
bool, bool, bool, bool, bool, map[string]bool) {
exportParams := exportParamsPath != ""
return tb, w, app.BaseApp, appStateFn, seed,
testAndRunTxs(app), invariants(app), numBlocks, blockSize, commit,
lean, onOperation, allInvariants, app.ModuleAccountAddrs()
testAndRunTxs(app), invariants(app),
initialBlockHeight, numBlocks, exportParamsHeight, blockSize,
exportStatsPath, exportParams, commit, lean, onOperation, allInvariants, app.ModuleAccountAddrs()
}
func appStateFn(
r *rand.Rand, accs []simulation.Account, genesisTimestamp time.Time,
) (appState json.RawMessage, simAccs []simulation.Account, chainID string) {
r *rand.Rand, accs []simulation.Account,
) (appState json.RawMessage, simAccs []simulation.Account, chainID string, genesisTimestamp time.Time) {
cdc := MakeCodec()
if genesisTime == 0 {
genesisTimestamp = simulation.RandTimestamp(r)
} else {
genesisTimestamp = time.Unix(genesisTime, 0)
}
switch {
case paramsFile != "" && genesisFile != "":
panic("cannot provide both a genesis file and a params file")
@@ -100,7 +107,7 @@ func appStateFn(
appState, simAccs, chainID = appStateRandomizedFn(r, accs, genesisTimestamp, appParams)
}
return appState, simAccs, chainID
return appState, simAccs, chainID, genesisTimestamp
}
// TODO refactor out random initialization code to the modules
@@ -361,7 +368,7 @@ func fauxMerkleModeOpt(bapp *baseapp.BaseApp) {
}
// Profile with:
// /usr/local/go/bin/go test -benchmem -run=^$ github.com/cosmos/cosmos-sdk/GaiaApp -bench ^BenchmarkFullAppSimulation$ -SimulationCommit=true -cpuprofile cpu.out
// /usr/local/go/bin/go test -benchmem -run=^$ github.com/cosmos/cosmos-sdk/GaiaApp -bench ^BenchmarkFullAppSimulation$ -Commit=true -cpuprofile cpu.out
func BenchmarkFullAppSimulation(b *testing.B) {
logger := log.NewNopLogger()
@@ -375,14 +382,46 @@ func BenchmarkFullAppSimulation(b *testing.B) {
app := NewGaiaApp(logger, db, nil, true, 0)
// Run randomized simulation
// TODO parameterize numbers, save for a later PR
_, err := simulation.SimulateFromSeed(getSimulateFromSeedInput(b, os.Stdout, app))
if err != nil {
fmt.Println(err)
b.Fail()
// TODO: parameterize numbers, save for a later PR
_, params, simErr := simulation.SimulateFromSeed(getSimulateFromSeedInput(b, os.Stdout, app))
// export state and params before the simulation error is checked
if exportStatePath != "" {
fmt.Println("Exporting app state...")
appState, _, err := app.ExportAppStateAndValidators(false, nil)
if err != nil {
fmt.Println(err)
b.Fail()
}
err = ioutil.WriteFile(exportStatePath, []byte(appState), 0644)
if err != nil {
fmt.Println(err)
b.Fail()
}
}
if exportParamsPath != "" {
fmt.Println("Exporting simulation params...")
paramsBz, err := json.MarshalIndent(params, "", " ")
if err != nil {
fmt.Println(err)
b.Fail()
}
err = ioutil.WriteFile(exportParamsPath, paramsBz, 0644)
if err != nil {
fmt.Println(err)
b.Fail()
}
}
if simErr != nil {
fmt.Println(simErr)
b.FailNow()
}
if commit {
fmt.Println("GoLevelDB Stats")
fmt.Println("\nGoLevelDB Stats")
fmt.Println(db.Stats()["leveldb.stats"])
fmt.Println("GoLevelDB cached block size", db.Stats()["leveldb.cachedblock"])
}
@@ -414,16 +453,37 @@ func TestFullAppSimulation(t *testing.T) {
require.Equal(t, "GaiaApp", app.Name())
// Run randomized simulation
_, err := simulation.SimulateFromSeed(getSimulateFromSeedInput(t, os.Stdout, app))
_, params, simErr := simulation.SimulateFromSeed(getSimulateFromSeedInput(t, os.Stdout, app))
// export state and params before the simulation error is checked
if exportStatePath != "" {
fmt.Println("Exporting app state...")
appState, _, err := app.ExportAppStateAndValidators(false, nil)
require.NoError(t, err)
err = ioutil.WriteFile(exportStatePath, []byte(appState), 0644)
require.NoError(t, err)
}
if exportParamsPath != "" {
fmt.Println("Exporting simulation params...")
fmt.Println(params)
paramsBz, err := json.MarshalIndent(params, "", " ")
require.NoError(t, err)
err = ioutil.WriteFile(exportParamsPath, paramsBz, 0644)
require.NoError(t, err)
}
require.NoError(t, simErr)
if commit {
// for memdb:
// fmt.Println("Database Size", db.Stats()["database.size"])
fmt.Println("GoLevelDB Stats")
fmt.Println("\nGoLevelDB Stats")
fmt.Println(db.Stats()["leveldb.stats"])
fmt.Println("GoLevelDB cached block size", db.Stats()["leveldb.cachedblock"])
}
require.Nil(t, err)
}
func TestAppImportExport(t *testing.T) {
@@ -448,20 +508,40 @@ func TestAppImportExport(t *testing.T) {
}()
app := NewGaiaApp(logger, db, nil, true, 0, fauxMerkleModeOpt)
require.Equal(t, "GaiaApp", app.Name())
require.Equal(t, "SimApp", app.Name())
// Run randomized simulation
_, err := simulation.SimulateFromSeed(getSimulateFromSeedInput(t, os.Stdout, app))
_, simParams, simErr := simulation.SimulateFromSeed(getSimulateFromSeedInput(t, os.Stdout, app))
// export state and simParams before the simulation error is checked
if exportStatePath != "" {
fmt.Println("Exporting app state...")
appState, _, err := app.ExportAppStateAndValidators(false, nil)
require.NoError(t, err)
err = ioutil.WriteFile(exportStatePath, []byte(appState), 0644)
require.NoError(t, err)
}
if exportParamsPath != "" {
fmt.Println("Exporting simulation params...")
simParamsBz, err := json.MarshalIndent(simParams, "", " ")
require.NoError(t, err)
err = ioutil.WriteFile(exportParamsPath, simParamsBz, 0644)
require.NoError(t, err)
}
require.NoError(t, simErr)
if commit {
// for memdb:
// fmt.Println("Database Size", db.Stats()["database.size"])
fmt.Println("GoLevelDB Stats")
fmt.Println("\nGoLevelDB Stats")
fmt.Println(db.Stats()["leveldb.stats"])
fmt.Println("GoLevelDB cached block size", db.Stats()["leveldb.cachedblock"])
}
require.Nil(t, err)
fmt.Printf("Exporting genesis...\n")
appState, _, err := app.ExportAppStateAndValidators(false, []string{})
@@ -477,7 +557,7 @@ func TestAppImportExport(t *testing.T) {
}()
newApp := NewGaiaApp(log.NewNopLogger(), newDB, nil, true, 0, fauxMerkleModeOpt)
require.Equal(t, "GaiaApp", newApp.Name())
require.Equal(t, "SimApp", newApp.Name())
var genesisState simapp.GenesisState
err = app.cdc.UnmarshalJSON(appState, &genesisState)
@@ -498,16 +578,18 @@ func TestAppImportExport(t *testing.T) {
}
storeKeysPrefixes := []StoreKeysPrefixes{
{app.keyMain, newApp.keyMain, [][]byte{}},
{app.keyAccount, newApp.keyAccount, [][]byte{}},
{app.keyStaking, newApp.keyStaking, [][]byte{staking.UnbondingQueueKey,
staking.RedelegationQueueKey, staking.ValidatorQueueKey}}, // ordering may change but it doesn't matter
{app.keySlashing, newApp.keySlashing, [][]byte{}},
{app.keyMint, newApp.keyMint, [][]byte{}},
{app.keyDistr, newApp.keyDistr, [][]byte{}},
{app.keySupply, newApp.keySupply, [][]byte{}},
{app.keyParams, newApp.keyParams, [][]byte{}},
{app.keyGov, newApp.keyGov, [][]byte{}},
{app.keys[baseapp.MainStoreKey], newApp.keys[baseapp.MainStoreKey], [][]byte{}},
{app.keys[auth.StoreKey], newApp.keys[auth.StoreKey], [][]byte{}},
{app.keys[staking.StoreKey], newApp.keys[staking.StoreKey],
[][]byte{
staking.UnbondingQueueKey, staking.RedelegationQueueKey, staking.ValidatorQueueKey,
}}, // ordering may change but it doesn't matter
{app.keys[slashing.StoreKey], newApp.keys[slashing.StoreKey], [][]byte{}},
{app.keys[mint.StoreKey], newApp.keys[mint.StoreKey], [][]byte{}},
{app.keys[distr.StoreKey], newApp.keys[distr.StoreKey], [][]byte{}},
{app.keys[supply.StoreKey], newApp.keys[supply.StoreKey], [][]byte{}},
{app.keys[params.StoreKey], newApp.keys[params.StoreKey], [][]byte{}},
{app.keys[gov.StoreKey], newApp.keys[gov.StoreKey], [][]byte{}},
}
for _, storeKeysPrefix := range storeKeysPrefixes {
@@ -516,9 +598,9 @@ func TestAppImportExport(t *testing.T) {
prefixes := storeKeysPrefix.Prefixes
storeA := ctxA.KVStore(storeKeyA)
storeB := ctxB.KVStore(storeKeyB)
kvA, kvB, count, equal := sdk.DiffKVStores(storeA, storeB, prefixes)
fmt.Printf("Compared %d key/value pairs between %s and %s\n", count, storeKeyA, storeKeyB)
require.True(t, equal, simapp.GetSimulationLog(storeKeyA.Name(), app.cdc, newApp.cdc, kvA, kvB))
failedKVs := sdk.DiffKVStores(storeA, storeB, prefixes)
fmt.Printf("Compared %d key/value pairs between %s and %s\n", len(failedKVs)/2, storeKeyA, storeKeyB)
require.Len(t, failedKVs, 0, simapp.GetSimulationLog(storeKeyA.Name(), app.cdc, newApp.cdc, failedKVs))
}
}
@@ -547,18 +629,37 @@ func TestAppSimulationAfterImport(t *testing.T) {
require.Equal(t, "GaiaApp", app.Name())
// Run randomized simulation
stopEarly, err := simulation.SimulateFromSeed(getSimulateFromSeedInput(t, os.Stdout, app))
stopEarly, params, simErr := simulation.SimulateFromSeed(getSimulateFromSeedInput(t, os.Stdout, app))
// export state and params before the simulation error is checked
if exportStatePath != "" {
fmt.Println("Exporting app state...")
appState, _, err := app.ExportAppStateAndValidators(false, nil)
require.NoError(t, err)
err = ioutil.WriteFile(exportStatePath, []byte(appState), 0644)
require.NoError(t, err)
}
if exportParamsPath != "" {
fmt.Println("Exporting simulation params...")
paramsBz, err := json.MarshalIndent(params, "", " ")
require.NoError(t, err)
err = ioutil.WriteFile(exportParamsPath, paramsBz, 0644)
require.NoError(t, err)
}
require.NoError(t, simErr)
if commit {
// for memdb:
// fmt.Println("Database Size", db.Stats()["database.size"])
fmt.Println("GoLevelDB Stats")
fmt.Println("\nGoLevelDB Stats")
fmt.Println(db.Stats()["leveldb.stats"])
fmt.Println("GoLevelDB cached block size", db.Stats()["leveldb.cachedblock"])
}
require.Nil(t, err)
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")
@@ -589,7 +690,7 @@ func TestAppSimulationAfterImport(t *testing.T) {
})
// Run randomized simulation on imported app
_, err = simulation.SimulateFromSeed(getSimulateFromSeedInput(t, os.Stdout, newApp))
_, _, err = simulation.SimulateFromSeed(getSimulateFromSeedInput(t, os.Stdout, newApp))
require.Nil(t, err)
}
@@ -611,24 +712,16 @@ func TestAppStateDeterminism(t *testing.T) {
db := dbm.NewMemDB()
app := NewGaiaApp(logger, db, nil, true, 0)
// run randomized simulation
// Run randomized simulation
simulation.SimulateFromSeed(
t, os.Stdout, app.BaseApp, appStateFn, seed,
testAndRunTxs(app),
[]sdk.Invariant{},
50,
100,
true,
false,
false,
false,
app.ModuleAccountAddrs(),
testAndRunTxs(app), []sdk.Invariant{},
1, 50, 100, 0, "",
false, true, false, false, false, app.ModuleAccountAddrs(),
)
appHash := app.LastCommitID().Hash
appHashList[j] = appHash
}
for k := 1; k < numTimesToRunPerSeed; k++ {
require.Equal(t, appHashList[0], appHashList[k], "appHash list: %v", appHashList)
}
@@ -646,15 +739,47 @@ func BenchmarkInvariants(b *testing.B) {
}()
app := NewGaiaApp(logger, db, nil, true, 0)
exportParams := exportParamsPath != ""
// 2. Run parameterized simulation (w/o invariants)
_, err := simulation.SimulateFromSeed(
_, params, simErr := simulation.SimulateFromSeed(
b, ioutil.Discard, app.BaseApp, appStateFn, seed, testAndRunTxs(app),
[]sdk.Invariant{}, numBlocks, blockSize, commit, lean, onOperation, false,
app.ModuleAccountAddrs(),
[]sdk.Invariant{}, initialBlockHeight, numBlocks, exportParamsHeight, blockSize,
exportStatsPath, exportParams, commit, lean, onOperation, false, app.ModuleAccountAddrs(),
)
if err != nil {
fmt.Println(err)
// export state and params before the simulation error is checked
if exportStatePath != "" {
fmt.Println("Exporting app state...")
appState, _, err := app.ExportAppStateAndValidators(false, nil)
if err != nil {
fmt.Println(err)
b.Fail()
}
err = ioutil.WriteFile(exportStatePath, []byte(appState), 0644)
if err != nil {
fmt.Println(err)
b.Fail()
}
}
if exportParamsPath != "" {
fmt.Println("Exporting simulation params...")
paramsBz, err := json.MarshalIndent(params, "", " ")
if err != nil {
fmt.Println(err)
b.Fail()
}
err = ioutil.WriteFile(exportParamsPath, paramsBz, 0644)
if err != nil {
fmt.Println(err)
b.Fail()
}
}
if simErr != nil {
fmt.Println(simErr)
b.FailNow()
}