diff --git a/.deepsource.toml b/.deepsource.toml new file mode 100644 index 000000000000..8b42c258ff02 --- /dev/null +++ b/.deepsource.toml @@ -0,0 +1,20 @@ +version = 1 + +test_patterns = [ + "tests/**", + "**_test.go" +] + +exclude_patterns = [ + "third_party/proto/**", + "testutil/**", + "proto/cosmos/**", + "contrib/**" +] + +[[analyzers]] +name = "go" +enabled = true + + [analyzers.meta] + import_paths = ["github.com/cosmos/cosmos-sdk"] \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 551ab5614ebf..dda608c263ac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -48,6 +48,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ * [\#8346](https://github.com/cosmos/cosmos-sdk/pull/8346) All CLI `tx` commands generate ServiceMsgs by default. Graceful Amino support has been added to ServiceMsgs to support signing legacy Msgs. * (crypto/ed25519) [\#8690] Adopt zip1215 ed2559 verification rules. * [\#8849](https://github.com/cosmos/cosmos-sdk/pull/8849) Upgrade module no longer supports time based upgrades. +* [\#8880](https://github.com/cosmos/cosmos-sdk/pull/8880) The CLI `simd migrate v0.40 ...` command has been renamed to `simd migrate v0.42`. ### API Breaking Changes @@ -76,6 +77,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ ### Improvements +* (x/staking) [\#8909](https://github.com/cosmos/cosmos-sdk/pull/8909) Require self delegation in `MsgCreateValidator` to be at least one consensus power. * (x/bank) [\#8614](https://github.com/cosmos/cosmos-sdk/issues/8614) Add `Name` and `Symbol` fields to denom metadata * (x/auth) [\#8522](https://github.com/cosmos/cosmos-sdk/pull/8522) Allow to query all stored accounts * (crypto/types) [\#8600](https://github.com/cosmos/cosmos-sdk/pull/8600) `CompactBitArray`: optimize the `NumTrueBitsBefore` method and add an `Equal` method. diff --git a/client/context_test.go b/client/context_test.go index 978f31732c1c..f1c01e765810 100644 --- a/client/context_test.go +++ b/client/context_test.go @@ -51,7 +51,7 @@ func TestContext_PrintObject(t *testing.T) { require.NoError(t, err) require.Equal(t, `{"animal":{"@type":"/testdata.Dog","size":"big","name":"Spot"},"x":"10"} -`, string(buf.Bytes())) +`, buf.String()) // yaml buf = &bytes.Buffer{} @@ -65,7 +65,7 @@ func TestContext_PrintObject(t *testing.T) { name: Spot size: big x: "10" -`, string(buf.Bytes())) +`, buf.String()) // // amino @@ -81,7 +81,7 @@ x: "10" require.NoError(t, err) require.Equal(t, `{"type":"testdata/HasAnimal","value":{"animal":{"type":"testdata/Dog","value":{"size":"big","name":"Spot"}},"x":"10"}} -`, string(buf.Bytes())) +`, buf.String()) // yaml buf = &bytes.Buffer{} @@ -98,7 +98,7 @@ value: name: Spot size: big x: "10" -`, string(buf.Bytes())) +`, buf.String()) } func TestCLIQueryConn(t *testing.T) { diff --git a/go.mod b/go.mod index 6f88f451cd5b..17084a037b92 100644 --- a/go.mod +++ b/go.mod @@ -32,7 +32,7 @@ require ( github.com/otiai10/copy v1.5.0 github.com/pelletier/go-toml v1.8.1 // indirect github.com/pkg/errors v0.9.1 - github.com/prometheus/client_golang v1.9.0 + github.com/prometheus/client_golang v1.10.0 github.com/prometheus/common v0.19.0 github.com/rakyll/statik v0.1.7 github.com/regen-network/cosmos-proto v0.3.1 diff --git a/go.sum b/go.sum index b8d2468d1509..84b14b3d074a 100644 --- a/go.sum +++ b/go.sum @@ -273,8 +273,9 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.1.1-0.20200604201612-c04b05f3adfa h1:Q75Upo5UN4JbPFURXZ8nLKYUvF85dyFRop/vQ0Rv+64= @@ -539,8 +540,8 @@ github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeD github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_golang v1.8.0/go.mod h1:O9VU6huf47PktckDQfMTX0Y8tY0/7TSWwj+ITvv0TnM= -github.com/prometheus/client_golang v1.9.0 h1:Rrch9mh17XcxvEu9D9DEpb4isxjGBtcevQjKvxPRQIU= -github.com/prometheus/client_golang v1.9.0/go.mod h1:FqZLKOZnGdFAhOK4nqGHa7D66IdsO+O441Eve7ptJDU= +github.com/prometheus/client_golang v1.10.0 h1:/o0BDeWzLWXNZ+4q5gXltUvaMpJqckTa+jTNoB+z4cg= +github.com/prometheus/client_golang v1.10.0/go.mod h1:WJM3cc3yu7XKBKa/I8WeZm+V3eltZnBwfENSU7mdogU= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= @@ -556,7 +557,7 @@ github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt2 github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.14.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= -github.com/prometheus/common v0.15.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= +github.com/prometheus/common v0.18.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= github.com/prometheus/common v0.19.0 h1:Itb4+NjG9wRdkAWgVucbM/adyIXxEhbw0866e0uZE6A= github.com/prometheus/common v0.19.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= @@ -565,8 +566,9 @@ github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7z github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.2.0 h1:wH4vA7pcjKuZzjF7lM8awk4fnuJO6idemZXoKnULUx4= github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/prometheus/procfs v0.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3xv4= +github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/tsdb v0.6.2-0.20190402121629-4f204dcbc150/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/rakyll/statik v0.1.7 h1:OF3QCZUuyPxuGEP7B4ypUa7sB/iHtqOTDYZXGM8KOdQ= @@ -807,6 +809,7 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -851,8 +854,9 @@ golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200922070232-aee5d888a860/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201015000850-e3ed0017c211/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201214210602-f9fddec55a1e h1:AyodaIpKjppX+cBfTASF2E1US3H2JFBj920Ot3rtDjs= -golang.org/x/sys v0.0.0-20201214210602-f9fddec55a1e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210309074719-68d13333faf2 h1:46ULzRKLh1CwgRq2dC5SlBzEqqNCi8rreOZnNrbqcIY= +golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221 h1:/ZHdbVpdR/jk3g30/d4yUL0JU9kksj8+F/bnQUVLGDM= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= diff --git a/x/auth/ante/ante_test.go b/x/auth/ante/ante_test.go index 5ec5f0ca4199..cb45492bd551 100644 --- a/x/auth/ante/ante_test.go +++ b/x/auth/ante/ante_test.go @@ -903,8 +903,7 @@ func generatePubKeysAndSignatures(n int, msg []byte, _ bool) (pubkeys []cryptoty pubkeys = make([]cryptotypes.PubKey, n) signatures = make([][]byte, n) for i := 0; i < n; i++ { - var privkey cryptotypes.PrivKey - privkey = secp256k1.GenPrivKey() + var privkey cryptotypes.PrivKey = secp256k1.GenPrivKey() // TODO: also generate ed25519 keys as below when ed25519 keys are // actually supported, https://github.com/cosmos/cosmos-sdk/issues/4789 diff --git a/x/auth/client/rest/rest_test.go b/x/auth/client/rest/rest_test.go index 41a22a26eb21..4cd99475d6b1 100644 --- a/x/auth/client/rest/rest_test.go +++ b/x/auth/client/rest/rest_test.go @@ -116,7 +116,7 @@ func (s *IntegrationTestSuite) TestEncodeDecode() { err = cdc.UnmarshalJSON(res, &encodeResp) require.NoError(err) - bz, err = cdc.MarshalJSON(authrest.DecodeReq{Tx: encodeResp.Tx}) + bz, err = cdc.MarshalJSON(authrest.DecodeReq(encodeResp)) require.NoError(err) res, err = rest.PostRequest(fmt.Sprintf("%s/txs/decode", val.APIAddress), "application/json", bz) diff --git a/x/auth/tx/builder_test.go b/x/auth/tx/builder_test.go index 6948299df515..50e81a676d16 100644 --- a/x/auth/tx/builder_test.go +++ b/x/auth/tx/builder_test.go @@ -40,8 +40,7 @@ func TestTxBuilder(t *testing.T) { Sequence: accSeq, }) - var sig signing.SignatureV2 - sig = signing.SignatureV2{ + var sig signing.SignatureV2 = signing.SignatureV2{ PubKey: pubkey, Data: &signing.SingleSignatureData{ SignMode: signing.SignMode_SIGN_MODE_DIRECT, diff --git a/x/distribution/legacy/v043/store_test.go b/x/distribution/legacy/v043/store_test.go index 848430133579..c719d34ddb1e 100644 --- a/x/distribution/legacy/v043/store_test.go +++ b/x/distribution/legacy/v043/store_test.go @@ -90,7 +90,7 @@ func TestStoreMigration(t *testing.T) { for _, tc := range testCases { tc := tc t.Run(tc.name, func(t *testing.T) { - if bytes.Compare(tc.oldKey, tc.newKey) != 0 { + if !bytes.Equal(tc.oldKey, tc.newKey) { require.Nil(t, store.Get(tc.oldKey)) } require.Equal(t, value, store.Get(tc.newKey)) diff --git a/x/genutil/client/cli/migrate.go b/x/genutil/client/cli/migrate.go index 483f4aaf107d..9bba5c3d8845 100644 --- a/x/genutil/client/cli/migrate.go +++ b/x/genutil/client/cli/migrate.go @@ -18,6 +18,7 @@ import ( v038 "github.com/cosmos/cosmos-sdk/x/genutil/legacy/v038" v039 "github.com/cosmos/cosmos-sdk/x/genutil/legacy/v039" v040 "github.com/cosmos/cosmos-sdk/x/genutil/legacy/v040" + v043 "github.com/cosmos/cosmos-sdk/x/genutil/legacy/v043" "github.com/cosmos/cosmos-sdk/x/genutil/types" ) @@ -28,9 +29,10 @@ const flagGenesisTime = "genesis-time" // Ref: https://github.com/cosmos/cosmos-sdk/issues/5041 var migrationMap = types.MigrationMap{ "v0.36": v036.Migrate, - "v0.38": v038.Migrate, // NOTE: v0.37 and v0.38 are genesis compatible + "v0.38": v038.Migrate, // NOTE: v0.37 and v0.38 are genesis compatible. "v0.39": v039.Migrate, - "v0.40": v040.Migrate, + "v0.42": v040.Migrate, // NOTE: v0.40, v0.41 and v0.42 are genesis compatible. + "v0.43": v043.Migrate, } // GetMigrationCallback returns a MigrationCallback for a given version. @@ -131,7 +133,7 @@ $ %s migrate v0.36 /path/to/genesis.json --chain-id=cosmoshub-3 --genesis-time=2 return errors.Wrap(err, "failed to sort JSON genesis doc") } - fmt.Println(string(sortedBz)) + cmd.Println(string(sortedBz)) return nil }, } diff --git a/x/genutil/client/cli/migrate_test.go b/x/genutil/client/cli/migrate_test.go index d31f8962a958..7e2f0e17af5f 100644 --- a/x/genutil/client/cli/migrate_test.go +++ b/x/genutil/client/cli/migrate_test.go @@ -25,35 +25,41 @@ func (s *IntegrationTestSuite) TestMigrateGenesis() { target string expErr bool expErrMsg string + check func(jsonOut string) }{ { - "migrate to 0.36", + "migrate 0.34 to 0.36", `{"chain_id":"test","app_state":{}}`, "v0.36", - false, "", + false, "", func(_ string) {}, }, { - "exported 0.37 genesis file", + "migrate 0.37 to 0.42", v037Exported, - "v0.40", - true, "Make sure that you have correctly migrated all Tendermint consensus params", + "v0.42", + true, "Make sure that you have correctly migrated all Tendermint consensus params", func(_ string) {}, }, { - "valid 0.40 genesis file", + "migrate 0.42 to 0.43", v040Valid, - "v0.40", + "v0.43", false, "", + func(jsonOut string) { + // Make sure the json output contains the ADR-037 gov weighted votes. + s.Require().Contains(jsonOut, "\"weight\":\"1.000000000000000000\"") + }, }, } for _, tc := range testCases { s.Run(tc.name, func() { genesisFile := testutil.WriteToNewTempFile(s.T(), tc.genesis) - _, err := clitestutil.ExecTestCLICmd(val0.ClientCtx, cli.MigrateGenesisCmd(), []string{tc.target, genesisFile.Name()}) + jsonOutput, err := clitestutil.ExecTestCLICmd(val0.ClientCtx, cli.MigrateGenesisCmd(), []string{tc.target, genesisFile.Name()}) if tc.expErr { s.Require().Contains(err.Error(), tc.expErrMsg) } else { s.Require().NoError(err) + tc.check(jsonOutput.String()) } }) } diff --git a/x/genutil/client/cli/validate_genesis_test.go b/x/genutil/client/cli/validate_genesis_test.go index f62aa1b7a48e..ea3d49c47465 100644 --- a/x/genutil/client/cli/validate_genesis_test.go +++ b/x/genutil/client/cli/validate_genesis_test.go @@ -26,9 +26,28 @@ var v037Exported = `{ }` // An example exported genesis file that's 0.40 compatible. +// We added the following app_state: +// +// - x/gov: added votes to test ADR-037 split votes migration. var v040Valid = `{ "app_hash": "", - "app_state": {}, + "app_state": { + "gov": { + "starting_proposal_id": "0", + "deposits": [], + "votes": [ + { + "proposal_id": "5", + "voter": "cosmos1fl48vsnmsdzcv85q5d2q4z5ajdha8yu34mf0eh", + "option": "VOTE_OPTION_YES" + } + ], + "proposals": [], + "deposit_params": { "min_deposit": [], "max_deposit_period": "0s" }, + "voting_params": { "voting_period": "0s" }, + "tally_params": { "quorum": "0", "threshold": "0", "veto_threshold": "0" } + } + }, "chain_id": "test", "consensus_params": { "block": { diff --git a/x/genutil/legacy/v043/migrate.go b/x/genutil/legacy/v043/migrate.go new file mode 100644 index 000000000000..8b6a00529252 --- /dev/null +++ b/x/genutil/legacy/v043/migrate.go @@ -0,0 +1,27 @@ +package v043 + +import ( + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/x/genutil/types" + v040gov "github.com/cosmos/cosmos-sdk/x/gov/legacy/v040" + v043gov "github.com/cosmos/cosmos-sdk/x/gov/legacy/v043" +) + +// Migrate migrates exported state from v0.40 to a v0.43 genesis state. +func Migrate(appState types.AppMap, clientCtx client.Context) types.AppMap { + // Migrate x/gov. + if appState[v040gov.ModuleName] != nil { + // unmarshal relative source genesis application state + var oldGovState v040gov.GenesisState + clientCtx.JSONMarshaler.MustUnmarshalJSON(appState[v040gov.ModuleName], &oldGovState) + + // delete deprecated x/gov genesis state + delete(appState, v040gov.ModuleName) + + // Migrate relative source genesis application state and marshal it into + // the respective key. + appState[v043gov.ModuleName] = clientCtx.JSONMarshaler.MustMarshalJSON(v043gov.MigrateJSON(&oldGovState)) + } + + return appState +} diff --git a/x/gov/legacy/v040/genesis.pb.go b/x/gov/legacy/v040/genesis.pb.go new file mode 100644 index 000000000000..2dc67061a936 --- /dev/null +++ b/x/gov/legacy/v040/genesis.pb.go @@ -0,0 +1,592 @@ +// Package v040 is taken from: +// https://github.com/cosmos/cosmos-sdk/blob/v0.42.1/x/gov/types/genesis.pb.go +// by copy-pasted only the relevants parts for Genesis. +//nolint +package v040 + +import ( + fmt "fmt" + io "io" + math_bits "math/bits" + + _ "github.com/gogo/protobuf/gogoproto" + proto "github.com/gogo/protobuf/proto" + + "github.com/cosmos/cosmos-sdk/x/gov/types" +) + +// GenesisState defines the gov module's genesis state. +type GenesisState struct { + // starting_proposal_id is the ID of the starting proposal. + StartingProposalId uint64 `protobuf:"varint,1,opt,name=starting_proposal_id,json=startingProposalId,proto3" json:"starting_proposal_id,omitempty" yaml:"starting_proposal_id"` + // deposits defines all the deposits present at genesis. + Deposits types.Deposits `protobuf:"bytes,2,rep,name=deposits,proto3,castrepeated=Deposits" json:"deposits"` + // votes defines all the votes present at genesis. + Votes Votes `protobuf:"bytes,3,rep,name=votes,proto3,castrepeated=Votes" json:"votes"` + // proposals defines all the proposals present at genesis. + Proposals types.Proposals `protobuf:"bytes,4,rep,name=proposals,proto3,castrepeated=Proposals" json:"proposals"` + // params defines all the paramaters of related to deposit. + DepositParams types.DepositParams `protobuf:"bytes,5,opt,name=deposit_params,json=depositParams,proto3" json:"deposit_params" yaml:"deposit_params"` + // params defines all the paramaters of related to voting. + VotingParams types.VotingParams `protobuf:"bytes,6,opt,name=voting_params,json=votingParams,proto3" json:"voting_params" yaml:"voting_params"` + // params defines all the paramaters of related to tally. + TallyParams types.TallyParams `protobuf:"bytes,7,opt,name=tally_params,json=tallyParams,proto3" json:"tally_params" yaml:"tally_params"` +} + +func (m *GenesisState) Reset() { *m = GenesisState{} } +func (m *GenesisState) String() string { return proto.CompactTextString(m) } +func (*GenesisState) ProtoMessage() {} + +func (m *GenesisState) GetStartingProposalId() uint64 { + if m != nil { + return m.StartingProposalId + } + return 0 +} + +func (m *GenesisState) GetDeposits() types.Deposits { + if m != nil { + return m.Deposits + } + return nil +} + +func (m *GenesisState) GetVotes() Votes { + if m != nil { + return m.Votes + } + return nil +} + +func (m *GenesisState) GetProposals() types.Proposals { + if m != nil { + return m.Proposals + } + return nil +} + +func (m *GenesisState) GetDepositParams() types.DepositParams { + if m != nil { + return m.DepositParams + } + return types.DepositParams{} +} + +func (m *GenesisState) GetVotingParams() types.VotingParams { + if m != nil { + return m.VotingParams + } + return types.VotingParams{} +} + +func (m *GenesisState) GetTallyParams() types.TallyParams { + if m != nil { + return m.TallyParams + } + return types.TallyParams{} +} + +func (m *GenesisState) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *GenesisState) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.TallyParams.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x3a + { + size, err := m.VotingParams.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x32 + { + size, err := m.DepositParams.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a + if len(m.Proposals) > 0 { + for iNdEx := len(m.Proposals) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Proposals[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + } + } + if len(m.Votes) > 0 { + for iNdEx := len(m.Votes) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Votes[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + } + if len(m.Deposits) > 0 { + for iNdEx := len(m.Deposits) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Deposits[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + if m.StartingProposalId != 0 { + i = encodeVarintGenesis(dAtA, i, uint64(m.StartingProposalId)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func encodeVarintGenesis(dAtA []byte, offset int, v uint64) int { + offset -= sovGenesis(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *GenesisState) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.StartingProposalId != 0 { + n += 1 + sovGenesis(uint64(m.StartingProposalId)) + } + if len(m.Deposits) > 0 { + for _, e := range m.Deposits { + l = e.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + } + if len(m.Votes) > 0 { + for _, e := range m.Votes { + l = e.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + } + if len(m.Proposals) > 0 { + for _, e := range m.Proposals { + l = e.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + } + l = m.DepositParams.Size() + n += 1 + l + sovGenesis(uint64(l)) + l = m.VotingParams.Size() + n += 1 + l + sovGenesis(uint64(l)) + l = m.TallyParams.Size() + n += 1 + l + sovGenesis(uint64(l)) + return n +} + +func sovGenesis(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func (m *GenesisState) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: GenesisState: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GenesisState: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field StartingProposalId", wireType) + } + m.StartingProposalId = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.StartingProposalId |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Deposits", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Deposits = append(m.Deposits, types.Deposit{}) + if err := m.Deposits[len(m.Deposits)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Votes", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Votes = append(m.Votes, Vote{}) + if err := m.Votes[len(m.Votes)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Proposals", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Proposals = append(m.Proposals, types.Proposal{}) + if err := m.Proposals[len(m.Proposals)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DepositParams", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.DepositParams.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field VotingParams", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.VotingParams.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TallyParams", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.TallyParams.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenesis(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenesis + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipGenesis(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowGenesis + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowGenesis + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowGenesis + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthGenesis + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupGenesis + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthGenesis + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthGenesis = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowGenesis = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupGenesis = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/gov/legacy/v040/gov.pb.go b/x/gov/legacy/v040/gov.pb.go index 9e2bb2d0f8fe..34ca3d82a0f9 100644 --- a/x/gov/legacy/v040/gov.pb.go +++ b/x/gov/legacy/v040/gov.pb.go @@ -1,4 +1,4 @@ -// Package v040 is take from: +// Package v040 is taken from: // https://github.com/cosmos/cosmos-sdk/blob/v0.41.1/x/gov/types/gov.pb.go // by copy-pasted only the relevants parts for Vote. package v040 diff --git a/x/gov/legacy/v043/json.go b/x/gov/legacy/v043/json.go new file mode 100644 index 000000000000..db6e47757724 --- /dev/null +++ b/x/gov/legacy/v043/json.go @@ -0,0 +1,32 @@ +package v043 + +import ( + v040gov "github.com/cosmos/cosmos-sdk/x/gov/legacy/v040" + "github.com/cosmos/cosmos-sdk/x/gov/types" +) + +// migrateWeightedVotes migrates the ADR-037 weighted votes. +func migrateJSONWeightedVotes(oldVotes v040gov.Votes) types.Votes { + newVotes := make(types.Votes, len(oldVotes)) + for i, oldVote := range oldVotes { + newVotes[i] = migrateVote(oldVote) + } + + return newVotes +} + +// MigrateJSON accepts exported v0.40 x/gov genesis state and migrates it to +// v0.43 x/gov genesis state. The migration includes: +// +// - Gov weighted votes. +func MigrateJSON(oldState *v040gov.GenesisState) *types.GenesisState { + return &types.GenesisState{ + StartingProposalId: oldState.StartingProposalId, + Deposits: oldState.Deposits, + Votes: migrateJSONWeightedVotes(oldState.Votes), + Proposals: oldState.Proposals, + DepositParams: oldState.DepositParams, + VotingParams: oldState.VotingParams, + TallyParams: oldState.TallyParams, + } +} diff --git a/x/gov/legacy/v043/json_test.go b/x/gov/legacy/v043/json_test.go new file mode 100644 index 000000000000..66082e5daf6b --- /dev/null +++ b/x/gov/legacy/v043/json_test.go @@ -0,0 +1,124 @@ +package v043_test + +import ( + "encoding/json" + "fmt" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/simapp" + sdk "github.com/cosmos/cosmos-sdk/types" + v040gov "github.com/cosmos/cosmos-sdk/x/gov/legacy/v040" + v043gov "github.com/cosmos/cosmos-sdk/x/gov/legacy/v043" + "github.com/cosmos/cosmos-sdk/x/gov/types" +) + +func TestMigrateJSON(t *testing.T) { + encodingConfig := simapp.MakeTestEncodingConfig() + clientCtx := client.Context{}. + WithInterfaceRegistry(encodingConfig.InterfaceRegistry). + WithTxConfig(encodingConfig.TxConfig). + WithJSONMarshaler(encodingConfig.Marshaler) + + voter, err := sdk.AccAddressFromBech32("cosmos1fl48vsnmsdzcv85q5d2q4z5ajdha8yu34mf0eh") + require.NoError(t, err) + govGenState := &v040gov.GenesisState{ + Votes: v040gov.Votes{ + v040gov.NewVote(1, voter, types.OptionAbstain), + v040gov.NewVote(2, voter, types.OptionEmpty), + v040gov.NewVote(3, voter, types.OptionNo), + v040gov.NewVote(4, voter, types.OptionNoWithVeto), + v040gov.NewVote(5, voter, types.OptionYes), + }, + } + + migrated := v043gov.MigrateJSON(govGenState) + + bz, err := clientCtx.JSONMarshaler.MarshalJSON(migrated) + require.NoError(t, err) + + // Indent the JSON bz correctly. + var jsonObj map[string]interface{} + err = json.Unmarshal(bz, &jsonObj) + require.NoError(t, err) + indentedBz, err := json.MarshalIndent(jsonObj, "", "\t") + require.NoError(t, err) + + // Make sure about: + // - Votes are all ADR-037 weighted votes with weight 1. + expected := `{ + "deposit_params": { + "max_deposit_period": "0s", + "min_deposit": [] + }, + "deposits": [], + "proposals": [], + "starting_proposal_id": "0", + "tally_params": { + "quorum": "0", + "threshold": "0", + "veto_threshold": "0" + }, + "votes": [ + { + "options": [ + { + "option": "VOTE_OPTION_ABSTAIN", + "weight": "1.000000000000000000" + } + ], + "proposal_id": "1", + "voter": "cosmos1fl48vsnmsdzcv85q5d2q4z5ajdha8yu34mf0eh" + }, + { + "options": [ + { + "option": "VOTE_OPTION_UNSPECIFIED", + "weight": "1.000000000000000000" + } + ], + "proposal_id": "2", + "voter": "cosmos1fl48vsnmsdzcv85q5d2q4z5ajdha8yu34mf0eh" + }, + { + "options": [ + { + "option": "VOTE_OPTION_NO", + "weight": "1.000000000000000000" + } + ], + "proposal_id": "3", + "voter": "cosmos1fl48vsnmsdzcv85q5d2q4z5ajdha8yu34mf0eh" + }, + { + "options": [ + { + "option": "VOTE_OPTION_NO_WITH_VETO", + "weight": "1.000000000000000000" + } + ], + "proposal_id": "4", + "voter": "cosmos1fl48vsnmsdzcv85q5d2q4z5ajdha8yu34mf0eh" + }, + { + "options": [ + { + "option": "VOTE_OPTION_YES", + "weight": "1.000000000000000000" + } + ], + "proposal_id": "5", + "voter": "cosmos1fl48vsnmsdzcv85q5d2q4z5ajdha8yu34mf0eh" + } + ], + "voting_params": { + "voting_period": "0s" + } +}` + + fmt.Println(string(indentedBz)) + + require.Equal(t, expected, string(indentedBz)) +} diff --git a/x/gov/legacy/v043/keys.go b/x/gov/legacy/v043/keys.go new file mode 100644 index 000000000000..8a2528ce5cdf --- /dev/null +++ b/x/gov/legacy/v043/keys.go @@ -0,0 +1,6 @@ +package v043 + +const ( + // ModuleName is the name of the module + ModuleName = "gov" +) diff --git a/x/gov/legacy/v043/store.go b/x/gov/legacy/v043/store.go index 9189e12f736a..0cacf51c3bac 100644 --- a/x/gov/legacy/v043/store.go +++ b/x/gov/legacy/v043/store.go @@ -32,8 +32,17 @@ func migratePrefixProposalAddress(store sdk.KVStore, prefixBz []byte) { } } -// migrateWeightedVotes migrates the ADR-037 weighted votes. -func migrateWeightedVotes(store sdk.KVStore, cdc codec.BinaryMarshaler) error { +// migrateStoreWeightedVotes migrates a legacy vote to an ADR-037 weighted vote. +func migrateVote(oldVote v040gov.Vote) types.Vote { + return types.Vote{ + ProposalId: oldVote.ProposalId, + Voter: oldVote.Voter, + Options: []types.WeightedVoteOption{{Option: oldVote.Option, Weight: sdk.NewDec(1)}}, + } +} + +// migrateStoreWeightedVotes migrates in-place all legacy votes to ADR-037 weighted votes. +func migrateStoreWeightedVotes(store sdk.KVStore, cdc codec.BinaryMarshaler) error { iterator := sdk.KVStorePrefixIterator(store, v040gov.VotesKeyPrefix) defer iterator.Close() @@ -44,12 +53,8 @@ func migrateWeightedVotes(store sdk.KVStore, cdc codec.BinaryMarshaler) error { return err } - newVote := &types.Vote{ - ProposalId: oldVote.ProposalId, - Voter: oldVote.Voter, - Options: []types.WeightedVoteOption{{Option: oldVote.Option, Weight: sdk.NewDec(1)}}, - } - bz, err := cdc.MarshalBinaryBare(newVote) + newVote := migrateVote(oldVote) + bz, err := cdc.MarshalBinaryBare(&newVote) if err != nil { return err } @@ -68,5 +73,5 @@ func MigrateStore(ctx sdk.Context, storeKey sdk.StoreKey, cdc codec.BinaryMarsha store := ctx.KVStore(storeKey) migratePrefixProposalAddress(store, v040gov.DepositsKeyPrefix) migratePrefixProposalAddress(store, v040gov.VotesKeyPrefix) - return migrateWeightedVotes(store, cdc) + return migrateStoreWeightedVotes(store, cdc) } diff --git a/x/gov/legacy/v043/store_test.go b/x/gov/legacy/v043/store_test.go index 22d3e3ba4fb2..d84e8859109e 100644 --- a/x/gov/legacy/v043/store_test.go +++ b/x/gov/legacy/v043/store_test.go @@ -16,7 +16,7 @@ import ( "github.com/cosmos/cosmos-sdk/x/gov/types" ) -func TestStoreMigration(t *testing.T) { +func TestMigrateStore(t *testing.T) { cdc := simapp.MakeTestEncodingConfig().Marshaler govKey := sdk.NewKVStoreKey("gov") ctx := testutil.DefaultContext(govKey, sdk.NewTransientStoreKey("transient_test")) @@ -82,7 +82,7 @@ func TestStoreMigration(t *testing.T) { for _, tc := range testCases { tc := tc t.Run(tc.name, func(t *testing.T) { - if bytes.Compare(tc.oldKey, tc.newKey) != 0 { + if !bytes.Equal(tc.oldKey, tc.newKey) { require.Nil(t, store.Get(tc.oldKey)) } require.Equal(t, tc.newValue, store.Get(tc.newKey)) diff --git a/x/slashing/legacy/v043/store_test.go b/x/slashing/legacy/v043/store_test.go index f0440c1e8416..a31b1cd65b3e 100644 --- a/x/slashing/legacy/v043/store_test.go +++ b/x/slashing/legacy/v043/store_test.go @@ -59,7 +59,7 @@ func TestStoreMigration(t *testing.T) { for _, tc := range testCases { tc := tc t.Run(tc.name, func(t *testing.T) { - if bytes.Compare(tc.oldKey, tc.newKey) != 0 { + if !bytes.Equal(tc.oldKey, tc.newKey) { require.Nil(t, store.Get(tc.oldKey)) } require.Equal(t, value, store.Get(tc.newKey)) diff --git a/x/staking/client/cli/cli_test.go b/x/staking/client/cli/cli_test.go index adaa825f92b7..fc270f430d14 100644 --- a/x/staking/client/cli/cli_test.go +++ b/x/staking/client/cli/cli_test.go @@ -97,7 +97,7 @@ func (s *IntegrationTestSuite) TestNewCreateValidatorCmd() { val.ClientCtx, val.Address, newAddr, - sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(200))), fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10000000))), fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), ) @@ -131,7 +131,7 @@ func (s *IntegrationTestSuite) TestNewCreateValidatorCmd() { { "invalid transaction (missing pubkey)", []string{ - fmt.Sprintf("--%s=100stake", cli.FlagAmount), + fmt.Sprintf("--%s=%dstake", cli.FlagAmount, sdk.PowerReduction.Int64()), fmt.Sprintf("--%s=AFAF00C4", cli.FlagIdentity), fmt.Sprintf("--%s=https://newvalidator.io", cli.FlagWebsite), fmt.Sprintf("--%s=contact@newvalidator.io", cli.FlagSecurityContact), @@ -151,7 +151,7 @@ func (s *IntegrationTestSuite) TestNewCreateValidatorCmd() { "invalid transaction (missing moniker)", []string{ fmt.Sprintf("--%s=%s", cli.FlagPubKey, consPubKey), - fmt.Sprintf("--%s=100stake", cli.FlagAmount), + fmt.Sprintf("--%s=%dstake", cli.FlagAmount, sdk.PowerReduction.Int64()), fmt.Sprintf("--%s=AFAF00C4", cli.FlagIdentity), fmt.Sprintf("--%s=https://newvalidator.io", cli.FlagWebsite), fmt.Sprintf("--%s=contact@newvalidator.io", cli.FlagSecurityContact), @@ -171,7 +171,7 @@ func (s *IntegrationTestSuite) TestNewCreateValidatorCmd() { "valid transaction", []string{ fmt.Sprintf("--%s=%s", cli.FlagPubKey, consPubKey), - fmt.Sprintf("--%s=100stake", cli.FlagAmount), + fmt.Sprintf("--%s=%dstake", cli.FlagAmount, sdk.PowerReduction.Int64()), fmt.Sprintf("--%s=NewValidator", cli.FlagMoniker), fmt.Sprintf("--%s=AFAF00C4", cli.FlagIdentity), fmt.Sprintf("--%s=https://newvalidator.io", cli.FlagWebsite), diff --git a/x/staking/legacy/v043/store_test.go b/x/staking/legacy/v043/store_test.go index 0abe8f3b1e86..7d7f365acb28 100644 --- a/x/staking/legacy/v043/store_test.go +++ b/x/staking/legacy/v043/store_test.go @@ -128,7 +128,7 @@ func TestStoreMigration(t *testing.T) { for _, tc := range testCases { tc := tc t.Run(tc.name, func(t *testing.T) { - if bytes.Compare(tc.oldKey, tc.newKey) != 0 { + if !bytes.Equal(tc.oldKey, tc.newKey) { require.Nil(t, store.Get(tc.oldKey)) } require.Equal(t, value, store.Get(tc.newKey)) diff --git a/x/staking/simulation/operations.go b/x/staking/simulation/operations.go index cf99446b9f3d..558a63b4e72d 100644 --- a/x/staking/simulation/operations.go +++ b/x/staking/simulation/operations.go @@ -112,11 +112,22 @@ func SimulateMsgCreateValidator(ak types.AccountKeeper, bk types.BankKeeper, k k return simtypes.NoOpMsg(types.ModuleName, types.TypeMsgCreateValidator, "balance is negative"), nil, nil } - amount, err := simtypes.RandPositiveInt(r, balance) + // A validator can only be created if it has at least one consensus power worth of tokens. + // Construct a maximum random value that is reduced by the PowerReduction, allowing + // for a minimum self delegation of the PowerReduction. + max := balance.Sub(sdk.PowerReduction) + if !max.IsPositive() { + return simtypes.NoOpMsg(types.ModuleName, types.TypeMsgCreateValidator, "balance doesn't have enough delegation amount"), nil, nil + } + + amount, err := simtypes.RandPositiveInt(r, max) if err != nil { return simtypes.NoOpMsg(types.ModuleName, types.TypeMsgCreateValidator, "unable to generate positive amount"), nil, err } + // ensure self delegation meets minimum requirement + amount = amount.Add(sdk.PowerReduction) + selfDelegation := sdk.NewCoin(denom, amount) account := ak.GetAccount(ctx, simAccount.Address) diff --git a/x/staking/types/msg.go b/x/staking/types/msg.go index e397046e5779..6cbb6e8254cd 100644 --- a/x/staking/types/msg.go +++ b/x/staking/types/msg.go @@ -140,6 +140,11 @@ func (msg MsgCreateValidator) ValidateBasic() error { return ErrMinSelfDelegationInvalid } + // ensure delegation is at least one consensus power + if sdk.TokensToConsensusPower(msg.Value.Amount) <= 0 { + return sdkerrors.Wrapf(ErrBadDelegationAmount, "self delegation amount (%s) must be at least one consensus power (%s)", msg.Value.Amount, sdk.PowerReduction) + } + if msg.Value.Amount.LT(msg.MinSelfDelegation) { return ErrSelfDelegationBelowMinimum } diff --git a/x/staking/types/msg_test.go b/x/staking/types/msg_test.go index 493434527c94..7b11d96a7429 100644 --- a/x/staking/types/msg_test.go +++ b/x/staking/types/msg_test.go @@ -15,7 +15,7 @@ import ( ) var ( - coinPos = sdk.NewInt64Coin(sdk.DefaultBondDenom, 1000) + coinPos = sdk.NewInt64Coin(sdk.DefaultBondDenom, sdk.PowerReduction.Int64()) coinZero = sdk.NewInt64Coin(sdk.DefaultBondDenom, 0) ) @@ -75,6 +75,7 @@ func TestMsgCreateValidator(t *testing.T) { {"zero min self delegation", "a", "b", "c", "d", "e", commission1, sdk.ZeroInt(), valAddr1, pk1, coinPos, false}, {"negative min self delegation", "a", "b", "c", "d", "e", commission1, sdk.NewInt(-1), valAddr1, pk1, coinPos, false}, {"delegation less than min self delegation", "a", "b", "c", "d", "e", commission1, coinPos.Amount.Add(sdk.OneInt()), valAddr1, pk1, coinPos, false}, + {"delegation less than one consensus power", "a", "b", "c", "d", "e", commission1, sdk.OneInt(), valAddr1, pk1, sdk.NewInt64Coin(sdk.DefaultBondDenom, 1000), false}, } for _, tc := range tests {