From 8a67a206e43d961901e00bcd03daeffdc194bd37 Mon Sep 17 00:00:00 2001 From: ValarDragon Date: Wed, 15 Aug 2018 22:20:23 -0700 Subject: [PATCH] Make randomized simulation deterministic from a given seed --- Gopkg.lock | 40 +++++++++---------- cmd/gaia/app/sim_test.go | 43 +++++++++++++++++++++ x/mock/app.go | 28 +++++++++++++- x/mock/simulation/random_simulate_blocks.go | 4 +- 4 files changed, 92 insertions(+), 23 deletions(-) diff --git a/Gopkg.lock b/Gopkg.lock index 304f75d03e10..1cdde264ff00 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -34,7 +34,7 @@ [[projects]] branch = "master" - digest = "1:2c00f064ba355903866cbfbf3f7f4c0fe64af6638cc7d1b8bdcf3181bc67f1d8" + digest = "1:6aabc1566d6351115d561d038da82a4c19b46c3b6e17f4a0a2fa60260663dc79" name = "github.com/btcsuite/btcd" packages = ["btcec"] pruneopts = "UT" @@ -71,7 +71,7 @@ version = "v1.4.7" [[projects]] - digest = "1:fdf5169073fb0ad6dc12a70c249145e30f4058647bea25f0abd48b6d9f228a11" + digest = "1:fa30c0652956e159cdb97dcb2ef8b8db63ed668c02a5c3a40961c8f0641252fe" name = "github.com/go-kit/kit" packages = [ "log", @@ -103,7 +103,7 @@ version = "v1.7.0" [[projects]] - digest = "1:35621fe20f140f05a0c4ef662c26c0ab4ee50bca78aa30fe87d33120bd28165e" + digest = "1:212285efb97b9ec2e20550d81f0446cb7897e57cbdfd7301b1363ab113d8be45" name = "github.com/gogo/protobuf" packages = [ "gogoproto", @@ -118,7 +118,7 @@ version = "v1.1.1" [[projects]] - digest = "1:17fe264ee908afc795734e8c4e63db2accabaf57326dbf21763a7d6b86096260" + digest = "1:cb22af0ed7c72d495d8be1106233ee553898950f15fd3f5404406d44c2e86888" name = "github.com/golang/protobuf" packages = [ "proto", @@ -165,7 +165,7 @@ [[projects]] branch = "master" - digest = "1:12247a2e99a060cc692f6680e5272c8adf0b8f572e6bce0d7095e624c958a240" + digest = "1:ac64f01acc5eeea9dde40e326de6b6471e501392ec06524c3b51033aa50789bc" name = "github.com/hashicorp/hcl" packages = [ ".", @@ -262,7 +262,7 @@ version = "v1.0.0" [[projects]] - digest = "1:c1a04665f9613e082e1209cf288bf64f4068dcd6c87a64bf1c4ff006ad422ba0" + digest = "1:98225904b7abff96c052b669b25788f18225a36673fba022fb93514bb9a2a64e" name = "github.com/prometheus/client_golang" packages = [ "prometheus", @@ -273,7 +273,7 @@ [[projects]] branch = "master" - digest = "1:2d5cd61daa5565187e1d96bae64dbbc6080dacf741448e9629c64fd93203b0d4" + digest = "1:0f37e09b3e92aaeda5991581311f8dbf38944b36a3edec61cc2d1991f527554a" name = "github.com/prometheus/client_model" packages = ["go"] pruneopts = "UT" @@ -281,7 +281,7 @@ [[projects]] branch = "master" - digest = "1:63b68062b8968092eb86bedc4e68894bd096ea6b24920faca8b9dcf451f54bb5" + digest = "1:dad2e5a2153ee7a6c9ab8fc13673a16ee4fb64434a7da980965a3741b0c981a3" name = "github.com/prometheus/common" packages = [ "expfmt", @@ -293,7 +293,7 @@ [[projects]] branch = "master" - digest = "1:8c49953a1414305f2ff5465147ee576dd705487c35b15918fcd4efdc0cb7a290" + digest = "1:a37c98f4b7a66bb5c539c0539f0915a74ef1c8e0b3b6f45735289d94cae92bfd" name = "github.com/prometheus/procfs" packages = [ ".", @@ -312,7 +312,7 @@ revision = "e2704e165165ec55d062f5919b4b29494e9fa790" [[projects]] - digest = "1:bd1ae00087d17c5a748660b8e89e1043e1e5479d0fea743352cda2f8dd8c4f84" + digest = "1:37ace7f35375adec11634126944bdc45a673415e2fcc07382d03b75ec76ea94c" name = "github.com/spf13/afero" packages = [ ".", @@ -331,7 +331,7 @@ version = "v1.2.0" [[projects]] - digest = "1:7ffc0983035bc7e297da3688d9fe19d60a420e9c38bef23f845c53788ed6a05e" + digest = "1:627ab2f549a6a55c44f46fa24a4307f4d0da81bfc7934ed0473bf38b24051d26" name = "github.com/spf13/cobra" packages = ["."] pruneopts = "UT" @@ -363,7 +363,7 @@ version = "v1.0.0" [[projects]] - digest = "1:7e8d267900c7fa7f35129a2a37596e38ed0f11ca746d6d9ba727980ee138f9f6" + digest = "1:73697231b93fb74a73ebd8384b68b9a60c57ea6b13c56d2425414566a72c8e6d" name = "github.com/stretchr/testify" packages = [ "assert", @@ -375,7 +375,7 @@ [[projects]] branch = "master" - digest = "1:f2ffd421680b0a3f7887501b3c6974bcf19217ecd301d0e2c9b681940ec363d5" + digest = "1:922191411ad8f61bcd8018ac127589bb489712c1d1a0ab2497aca4b16de417d2" name = "github.com/syndtr/goleveldb" packages = [ "leveldb", @@ -396,7 +396,7 @@ [[projects]] branch = "master" - digest = "1:087aaa7920e5d0bf79586feb57ce01c35c830396ab4392798112e8aae8c47722" + digest = "1:203b409c21115233a576f99e8f13d8e07ad82b25500491f7e1cca12588fb3232" name = "github.com/tendermint/ed25519" packages = [ ".", @@ -423,7 +423,7 @@ version = "v0.9.2" [[projects]] - digest = "1:26146cdb2811ce481e72138439b9b1aa17a64d54364f96bb92f97a9ef8ba4f01" + digest = "1:df232b6f3c44554161093af004100f75e564b398ad3ff63ecbc297fe400dcfdb" name = "github.com/tendermint/tendermint" packages = [ "abci/client", @@ -498,7 +498,7 @@ [[projects]] branch = "master" - digest = "1:7a71fffde456d746c52f9cd09c50b034533a3180fb1f6320abb149f2ccc579e5" + digest = "1:3c3c47c1f7587c380afcc1d76385a4a03a2917b9ccc1ac50864d8f87e0264ada" name = "golang.org/x/crypto" packages = [ "blowfish", @@ -520,7 +520,7 @@ revision = "de0752318171da717af4ce24d0a2e8626afaeb11" [[projects]] - digest = "1:d36f55a999540d29b6ea3c2ea29d71c76b1d9853fdcd3e5c5cb4836f2ba118f1" + digest = "1:04dda8391c3e2397daf254ac68003f30141c069b228d06baec8324a5f81dc1e9" name = "golang.org/x/net" packages = [ "context", @@ -537,7 +537,7 @@ [[projects]] branch = "master" - digest = "1:4bd75b1a219bc590b05c976bbebf47f4e993314ebb5c7cbf2efe05a09a184d54" + digest = "1:1b9d0e0ed6a27439ded0a6cb25f8d46fb649910c6e1b3d2160eb54ee4d1249ab" name = "golang.org/x/sys" packages = [ "cpu", @@ -547,7 +547,7 @@ revision = "14742f9018cd6651ec7364dc6ee08af0baaa1031" [[projects]] - digest = "1:a2ab62866c75542dd18d2b069fec854577a20211d7c0ea6ae746072a1dccdd18" + digest = "1:7509ba4347d1f8de6ae9be8818b0cd1abc3deeffe28aeaf4be6d4b6b5178d9ca" name = "golang.org/x/text" packages = [ "collate", @@ -578,7 +578,7 @@ revision = "383e8b2c3b9e36c4076b235b32537292176bae20" [[projects]] - digest = "1:2dab32a43451e320e49608ff4542fdfc653c95dcc35d0065ec9c6c3dd540ed74" + digest = "1:4515e3030c440845b046354fd5d57671238428b820deebce2e9dabb5cd3c51ac" name = "google.golang.org/grpc" packages = [ ".", diff --git a/cmd/gaia/app/sim_test.go b/cmd/gaia/app/sim_test.go index 18d3c809e825..5d0edcba2c7e 100644 --- a/cmd/gaia/app/sim_test.go +++ b/cmd/gaia/app/sim_test.go @@ -133,3 +133,46 @@ func TestFullGaiaSimulation(t *testing.T) { ) } + +// TODO: Make this not depend on Gaia or any of the modules, +// and place it in random_simulation_test.go +// +// Test doesn't use `app.ExportAppStateAndValidators` as that panics with the following: +// panic: Stored pool should not have been nil [recovered] +// panic: Stored pool should not have been nil +// Change to `app.ExportAppStateAndValidators` once it is fixed +func TestAppStateDeterminism(t *testing.T) { + numTimesToRun := 5 + appHashList := make([]json.RawMessage, numTimesToRun) + + seed := rand.Int63() + for i := 0; i < numTimesToRun; i++ { + logger := log.NewNopLogger() + db := dbm.NewMemDB() + app := NewGaiaApp(logger, db, nil) + + noOpInvariant := func(t *testing.T, baseapp *baseapp.BaseApp, log string) {} + noOpTestAndRunTx := func(t *testing.T, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, + privKeys []crypto.PrivKey, log string, event func(string), + ) (action string, err sdk.Error) { + return "", nil + } + + // Run randomized simulation + simulation.SimulateFromSeed( + t, app.BaseApp, appStateFn, seed, + []simulation.TestAndRunTx{ + noOpTestAndRunTx, + }, + []simulation.RandSetup{}, + []simulation.Invariant{noOpInvariant}, + 0, + 10, + ) + appHash := app.LastCommitID().Hash + appHashList[i] = appHash + } + for i := 1; i < numTimesToRun; i++ { + require.Equal(t, appHashList[0], appHashList[i]) + } +} diff --git a/x/mock/app.go b/x/mock/app.go index 53b6345b0040..f472c5531cca 100644 --- a/x/mock/app.go +++ b/x/mock/app.go @@ -11,6 +11,7 @@ import ( abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto/ed25519" + "github.com/tendermint/tendermint/crypto/secp256k1" dbm "github.com/tendermint/tendermint/libs/db" "github.com/tendermint/tendermint/libs/log" ) @@ -173,7 +174,32 @@ func GeneratePrivKeyAddressPairs(n int) (keys []crypto.PrivKey, addrs []sdk.AccA keys = make([]crypto.PrivKey, n, n) addrs = make([]sdk.AccAddress, n, n) for i := 0; i < n; i++ { - keys[i] = ed25519.GenPrivKey() + if rand.Int63()%2 == 0 { + keys[i] = secp256k1.GenPrivKey() + } else { + keys[i] = ed25519.GenPrivKey() + } + addrs[i] = sdk.AccAddress(keys[i].PubKey().Address()) + } + return +} + +// GeneratePrivKeyAddressPairsFromRand generates a total of n private key, address +// pairs using the provided randomness source. +func GeneratePrivKeyAddressPairsFromRand(rand *rand.Rand, n int) (keys []crypto.PrivKey, addrs []sdk.AccAddress) { + keys = make([]crypto.PrivKey, n, n) + addrs = make([]sdk.AccAddress, n, n) + for i := 0; i < n; i++ { + secret := make([]byte, 32) + _, err := rand.Read(secret) + if err != nil { + panic("Could not read randomness") + } + if rand.Int63()%2 == 0 { + keys[i] = secp256k1.GenPrivKeySecp256k1(secret) + } else { + keys[i] = ed25519.GenPrivKeyFromSecret(secret) + } addrs[i] = sdk.AccAddress(keys[i].PubKey().Address()) } return diff --git a/x/mock/simulation/random_simulate_blocks.go b/x/mock/simulation/random_simulate_blocks.go index b4dd3987a8c2..2aa1a7b0e812 100644 --- a/x/mock/simulation/random_simulate_blocks.go +++ b/x/mock/simulation/random_simulate_blocks.go @@ -34,8 +34,8 @@ func SimulateFromSeed( ) { log := fmt.Sprintf("Starting SimulateFromSeed with randomness created with seed %d", int(seed)) fmt.Printf("%s\n", log) - keys, accs := mock.GeneratePrivKeyAddressPairs(numKeys) r := rand.New(rand.NewSource(seed)) + keys, accs := mock.GeneratePrivKeyAddressPairsFromRand(r, numKeys) // Setup event stats events := make(map[string]uint) @@ -119,7 +119,7 @@ func SimulateFromSeed( validators = updateValidators(t, r, validators, res.ValidatorUpdates, event) } - fmt.Printf("\nSimulation complete. Final height (blocks): %d, final time (seconds): %d\n", header.Height, header.Time) + fmt.Printf("\nSimulation complete. Final height (blocks): %d, final time (seconds): %v\n", header.Height, header.Time) DisplayEvents(events) }