diff --git a/CHANGELOG.md b/CHANGELOG.md index 799a8d52f7e1..1b0c613343a4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -116,6 +116,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ ### API Breaking Changes +* (x/gov) [#15988](https://github.com/cosmos/cosmos-sdk/issues/15988) `NewKeeper` now takes a `KVStoreService` instead of a `StoreKey`, methods in the `Keeper` now take a `context.Context` instead of a `sdk.Context` and return an `error` (instead of panicking or returning a `found bool`). Iterators callback functions now return an error instead of a `bool`. * (x/auth) [#15985](https://github.com/cosmos/cosmos-sdk/pull/15985) The `AccountKeeper` does not expose the `QueryServer` and `MsgServer` APIs anymore. * (x/authz) [#15962](https://github.com/cosmos/cosmos-sdk/issues/15962) `NewKeeper` now takes a `KVStoreService` instead of a `StoreKey`, methods in the `Keeper` now take a `context.Context` instead of a `sdk.Context`. The `Authorization` interface's `Accept` method now takes a `context.Context` instead of a `sdk.Context`. * (x/distribution) [#15948](https://github.com/cosmos/cosmos-sdk/issues/15948) `NewKeeper` now takes a `KVStoreService` instead of a `StoreKey` and methods in the `Keeper` now take a `context.Context` instead of a `sdk.Context`. Keeper methods also now return an `error`. diff --git a/UPGRADING.md b/UPGRADING.md index fa3eefa28591..f7517617c631 100644 --- a/UPGRADING.md +++ b/UPGRADING.md @@ -79,6 +79,7 @@ The following modules `NewKeeper` function now take a `KVStoreService` instead o * `x/consensus` * `x/distribution` * `x/feegrant` +* `x/gov` * `x/nft` User manually wiring their chain need to use the `runtime.NewKVStoreService` method to create a `KVStoreService` from a `StoreKey`: @@ -97,6 +98,7 @@ The following modules' `Keeper` methods now take in a `context.Context` instead * `x/authz` * `x/bank` * `x/distribution` +* `x/gov` **Users using depinject do not need any changes, this is automatically done for them.** diff --git a/go.mod b/go.mod index 7ee046ff473e..08fde70797df 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( cosmossdk.io/collections v0.1.0 cosmossdk.io/core v0.6.1 cosmossdk.io/depinject v1.0.0-alpha.3 - cosmossdk.io/errors v1.0.0-beta.7 + cosmossdk.io/errors v1.0.0-beta.7.0.20230429155654-3ee8242364e4 cosmossdk.io/log v1.1.0 cosmossdk.io/math v1.0.0 cosmossdk.io/store v0.1.0-alpha.1.0.20230328185921-37ba88872dbc diff --git a/go.sum b/go.sum index 2265464421a0..763ef83f9365 100644 --- a/go.sum +++ b/go.sum @@ -41,8 +41,8 @@ cosmossdk.io/collections v0.1.0 h1:nzJGeiq32KnZroSrhB6rPifw4I85Cgmzw/YAmr4luv8= cosmossdk.io/collections v0.1.0/go.mod h1:xbauc0YsbUF8qKMVeBZl0pFCunxBIhKN/WlxpZ3lBuo= cosmossdk.io/depinject v1.0.0-alpha.3 h1:6evFIgj//Y3w09bqOUOzEpFj5tsxBqdc5CfkO7z+zfw= cosmossdk.io/depinject v1.0.0-alpha.3/go.mod h1:eRbcdQ7MRpIPEM5YUJh8k97nxHpYbc3sMUnEtt8HPWU= -cosmossdk.io/errors v1.0.0-beta.7 h1:gypHW76pTQGVnHKo6QBkb4yFOJjC+sUGRc5Al3Odj1w= -cosmossdk.io/errors v1.0.0-beta.7/go.mod h1:mz6FQMJRku4bY7aqS/Gwfcmr/ue91roMEKAmDUDpBfE= +cosmossdk.io/errors v1.0.0-beta.7.0.20230429155654-3ee8242364e4 h1:rOy7iw7HlwKc5Af5qIHLXdBx/F98o6du/I/WGwOW6eA= +cosmossdk.io/errors v1.0.0-beta.7.0.20230429155654-3ee8242364e4/go.mod h1:AwrAxbvuH9FdatzJX463kMYNMVkjujWU/xR+HsimWTw= cosmossdk.io/log v1.1.0 h1:v0ogPHYeTzPcBTcPR1A3j1hkei4pZama8kz8LKlCMv0= cosmossdk.io/log v1.1.0/go.mod h1:6zjroETlcDs+mm62gd8Ig7mZ+N+fVOZS91V17H+M4N4= cosmossdk.io/math v1.0.0 h1:ro9w7eKx23om2tZz/VM2Pf+z2WAbGX1yDQQOJ6iGeJw= diff --git a/simapp/app.go b/simapp/app.go index 29e3c73a6d81..330a1fe3f768 100644 --- a/simapp/app.go +++ b/simapp/app.go @@ -326,7 +326,7 @@ func NewSimApp( govConfig.MaxMetadataLen = 10000 */ govKeeper := govkeeper.NewKeeper( - appCodec, keys[govtypes.StoreKey], app.AccountKeeper, app.BankKeeper, + appCodec, runtime.NewKVStoreService(keys[govtypes.StoreKey]), app.AccountKeeper, app.BankKeeper, app.StakingKeeper, app.DistrKeeper, app.MsgServiceRouter(), govConfig, authtypes.NewModuleAddress(govtypes.ModuleName).String(), ) diff --git a/simapp/go.mod b/simapp/go.mod index c792a212355e..d33e5b534584 100644 --- a/simapp/go.mod +++ b/simapp/go.mod @@ -37,7 +37,7 @@ require ( cloud.google.com/go/iam v0.13.0 // indirect cloud.google.com/go/storage v1.30.0 // indirect cosmossdk.io/collections v0.1.0 // indirect - cosmossdk.io/errors v1.0.0-beta.7 // indirect + cosmossdk.io/errors v1.0.0-beta.7.0.20230429155654-3ee8242364e4 // indirect cosmossdk.io/x/tx v0.6.1 // indirect filippo.io/edwards25519 v1.0.0 // indirect github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect diff --git a/simapp/go.sum b/simapp/go.sum index 3491bcc8ae92..ad65a52c91a1 100644 --- a/simapp/go.sum +++ b/simapp/go.sum @@ -192,8 +192,8 @@ cosmossdk.io/collections v0.1.0 h1:nzJGeiq32KnZroSrhB6rPifw4I85Cgmzw/YAmr4luv8= cosmossdk.io/collections v0.1.0/go.mod h1:xbauc0YsbUF8qKMVeBZl0pFCunxBIhKN/WlxpZ3lBuo= cosmossdk.io/depinject v1.0.0-alpha.3 h1:6evFIgj//Y3w09bqOUOzEpFj5tsxBqdc5CfkO7z+zfw= cosmossdk.io/depinject v1.0.0-alpha.3/go.mod h1:eRbcdQ7MRpIPEM5YUJh8k97nxHpYbc3sMUnEtt8HPWU= -cosmossdk.io/errors v1.0.0-beta.7 h1:gypHW76pTQGVnHKo6QBkb4yFOJjC+sUGRc5Al3Odj1w= -cosmossdk.io/errors v1.0.0-beta.7/go.mod h1:mz6FQMJRku4bY7aqS/Gwfcmr/ue91roMEKAmDUDpBfE= +cosmossdk.io/errors v1.0.0-beta.7.0.20230429155654-3ee8242364e4 h1:rOy7iw7HlwKc5Af5qIHLXdBx/F98o6du/I/WGwOW6eA= +cosmossdk.io/errors v1.0.0-beta.7.0.20230429155654-3ee8242364e4/go.mod h1:AwrAxbvuH9FdatzJX463kMYNMVkjujWU/xR+HsimWTw= cosmossdk.io/log v1.1.0 h1:v0ogPHYeTzPcBTcPR1A3j1hkei4pZama8kz8LKlCMv0= cosmossdk.io/log v1.1.0/go.mod h1:6zjroETlcDs+mm62gd8Ig7mZ+N+fVOZS91V17H+M4N4= cosmossdk.io/math v1.0.0 h1:ro9w7eKx23om2tZz/VM2Pf+z2WAbGX1yDQQOJ6iGeJw= diff --git a/tests/go.mod b/tests/go.mod index 9ad3d04cde83..689ab6168620 100644 --- a/tests/go.mod +++ b/tests/go.mod @@ -5,7 +5,7 @@ go 1.20 require ( cosmossdk.io/api v0.4.1 cosmossdk.io/depinject v1.0.0-alpha.3 - cosmossdk.io/errors v1.0.0-beta.7 + cosmossdk.io/errors v1.0.0-beta.7.0.20230429155654-3ee8242364e4 cosmossdk.io/log v1.1.0 cosmossdk.io/math v1.0.0 cosmossdk.io/simapp v0.0.0-20230309163709-87da587416ba diff --git a/tests/go.sum b/tests/go.sum index 28873dcc964d..a2d04fcdb35f 100644 --- a/tests/go.sum +++ b/tests/go.sum @@ -194,8 +194,8 @@ cosmossdk.io/collections v0.1.0 h1:nzJGeiq32KnZroSrhB6rPifw4I85Cgmzw/YAmr4luv8= cosmossdk.io/collections v0.1.0/go.mod h1:xbauc0YsbUF8qKMVeBZl0pFCunxBIhKN/WlxpZ3lBuo= cosmossdk.io/depinject v1.0.0-alpha.3 h1:6evFIgj//Y3w09bqOUOzEpFj5tsxBqdc5CfkO7z+zfw= cosmossdk.io/depinject v1.0.0-alpha.3/go.mod h1:eRbcdQ7MRpIPEM5YUJh8k97nxHpYbc3sMUnEtt8HPWU= -cosmossdk.io/errors v1.0.0-beta.7 h1:gypHW76pTQGVnHKo6QBkb4yFOJjC+sUGRc5Al3Odj1w= -cosmossdk.io/errors v1.0.0-beta.7/go.mod h1:mz6FQMJRku4bY7aqS/Gwfcmr/ue91roMEKAmDUDpBfE= +cosmossdk.io/errors v1.0.0-beta.7.0.20230429155654-3ee8242364e4 h1:rOy7iw7HlwKc5Af5qIHLXdBx/F98o6du/I/WGwOW6eA= +cosmossdk.io/errors v1.0.0-beta.7.0.20230429155654-3ee8242364e4/go.mod h1:AwrAxbvuH9FdatzJX463kMYNMVkjujWU/xR+HsimWTw= cosmossdk.io/log v1.1.0 h1:v0ogPHYeTzPcBTcPR1A3j1hkei4pZama8kz8LKlCMv0= cosmossdk.io/log v1.1.0/go.mod h1:6zjroETlcDs+mm62gd8Ig7mZ+N+fVOZS91V17H+M4N4= cosmossdk.io/math v1.0.0 h1:ro9w7eKx23om2tZz/VM2Pf+z2WAbGX1yDQQOJ6iGeJw= diff --git a/tests/integration/gov/genesis_test.go b/tests/integration/gov/genesis_test.go index 2bb1e6d439b8..65621bab3330 100644 --- a/tests/integration/gov/genesis_test.go +++ b/tests/integration/gov/genesis_test.go @@ -88,14 +88,15 @@ func TestImportExportQueues(t *testing.T) { assert.NilError(t, err) proposalID2 := proposal2.Id - votingStarted, err := s1.GovKeeper.AddDeposit(ctx, proposalID2, addrs[0], s1.GovKeeper.GetParams(ctx).MinDeposit) + params, _ := s1.GovKeeper.GetParams(ctx) + votingStarted, err := s1.GovKeeper.AddDeposit(ctx, proposalID2, addrs[0], params.MinDeposit) assert.NilError(t, err) assert.Assert(t, votingStarted) - proposal1, ok := s1.GovKeeper.GetProposal(ctx, proposalID1) - assert.Assert(t, ok) - proposal2, ok = s1.GovKeeper.GetProposal(ctx, proposalID2) - assert.Assert(t, ok) + proposal1, err = s1.GovKeeper.GetProposal(ctx, proposalID1) + assert.NilError(t, err) + proposal2, err = s1.GovKeeper.GetProposal(ctx, proposalID2) + assert.NilError(t, err) assert.Assert(t, proposal1.Status == v1.StatusDepositPeriod) assert.Assert(t, proposal2.Status == v1.StatusVotingPeriod) @@ -105,7 +106,7 @@ func TestImportExportQueues(t *testing.T) { distributionGenState := s1.DistrKeeper.ExportGenesis(ctx) // export the state and import it into a new app - govGenState := gov.ExportGenesis(ctx, s1.GovKeeper) + govGenState, _ := gov.ExportGenesis(ctx, s1.GovKeeper) genesisState := s1.appBuilder.DefaultGenesis() genesisState[authtypes.ModuleName] = s1.cdc.MustMarshalJSON(authGenState) @@ -144,27 +145,30 @@ func TestImportExportQueues(t *testing.T) { ctx2 := s2.app.BaseApp.NewContext(false, cmtproto.Header{}) + params, err = s2.GovKeeper.GetParams(ctx2) + assert.NilError(t, err) // Jump the time forward past the DepositPeriod and VotingPeriod - ctx2 = ctx2.WithBlockTime(ctx2.BlockHeader().Time.Add(*s2.GovKeeper.GetParams(ctx2).MaxDepositPeriod).Add(*s2.GovKeeper.GetParams(ctx2).VotingPeriod)) + ctx2 = ctx2.WithBlockTime(ctx2.BlockHeader().Time.Add(*params.MaxDepositPeriod).Add(*params.VotingPeriod)) // Make sure that they are still in the DepositPeriod and VotingPeriod respectively - proposal1, ok = s2.GovKeeper.GetProposal(ctx2, proposalID1) - assert.Assert(t, ok) - proposal2, ok = s2.GovKeeper.GetProposal(ctx2, proposalID2) - assert.Assert(t, ok) + proposal1, err = s2.GovKeeper.GetProposal(ctx2, proposalID1) + assert.NilError(t, err) + proposal2, err = s2.GovKeeper.GetProposal(ctx2, proposalID2) + assert.NilError(t, err) assert.Assert(t, proposal1.Status == v1.StatusDepositPeriod) assert.Assert(t, proposal2.Status == v1.StatusVotingPeriod) macc := s2.GovKeeper.GetGovernanceAccount(ctx2) - assert.DeepEqual(t, sdk.Coins(s2.GovKeeper.GetParams(ctx2).MinDeposit), s2.BankKeeper.GetAllBalances(ctx2, macc.GetAddress())) + assert.DeepEqual(t, sdk.Coins(params.MinDeposit), s2.BankKeeper.GetAllBalances(ctx2, macc.GetAddress())) // Run the endblocker. Check to make sure that proposal1 is removed from state, and proposal2 is finished VotingPeriod. - gov.EndBlocker(ctx2, s2.GovKeeper) + err = gov.EndBlocker(ctx2, s2.GovKeeper) + assert.NilError(t, err) - proposal1, ok = s2.GovKeeper.GetProposal(ctx2, proposalID1) - assert.Assert(t, ok == false) + proposal1, err = s2.GovKeeper.GetProposal(ctx2, proposalID1) + assert.ErrorContains(t, err, "proposal 1 doesn't exist") - proposal2, ok = s2.GovKeeper.GetProposal(ctx2, proposalID2) - assert.Assert(t, ok) + proposal2, err = s2.GovKeeper.GetProposal(ctx2, proposalID2) + assert.NilError(t, err) assert.Assert(t, proposal2.Status == v1.StatusRejected) } diff --git a/tests/integration/gov/keeper/tally_test.go b/tests/integration/gov/keeper/tally_test.go index a021a3c8537a..725241d67138 100644 --- a/tests/integration/gov/keeper/tally_test.go +++ b/tests/integration/gov/keeper/tally_test.go @@ -28,7 +28,7 @@ func TestTallyNoOneVotes(t *testing.T) { proposal, ok := app.GovKeeper.GetProposal(ctx, proposalID) assert.Assert(t, ok) - passes, burnDeposits, tallyResults := app.GovKeeper.Tally(ctx, proposal) + passes, burnDeposits, tallyResults, _ := app.GovKeeper.Tally(ctx, proposal) assert.Assert(t, passes == false) assert.Assert(t, burnDeposits == false) @@ -57,7 +57,7 @@ func TestTallyNoQuorum(t *testing.T) { proposal, ok := app.GovKeeper.GetProposal(ctx, proposalID) assert.Assert(t, ok) - passes, burnDeposits, _ := app.GovKeeper.Tally(ctx, proposal) + passes, burnDeposits, _, _ := app.GovKeeper.Tally(ctx, proposal) assert.Assert(t, passes == false) assert.Assert(t, burnDeposits == false) } @@ -83,7 +83,7 @@ func TestTallyOnlyValidatorsAllYes(t *testing.T) { proposal, ok := app.GovKeeper.GetProposal(ctx, proposalID) assert.Assert(t, ok) - passes, burnDeposits, tallyResults := app.GovKeeper.Tally(ctx, proposal) + passes, burnDeposits, tallyResults, _ := app.GovKeeper.Tally(ctx, proposal) assert.Assert(t, passes) assert.Assert(t, burnDeposits == false) @@ -110,7 +110,7 @@ func TestTallyOnlyValidators51No(t *testing.T) { proposal, ok := app.GovKeeper.GetProposal(ctx, proposalID) assert.Assert(t, ok) - passes, burnDeposits, _ := app.GovKeeper.Tally(ctx, proposal) + passes, burnDeposits, _, _ := app.GovKeeper.Tally(ctx, proposal) assert.Assert(t, passes == false) assert.Assert(t, burnDeposits == false) @@ -136,7 +136,7 @@ func TestTallyOnlyValidators51Yes(t *testing.T) { proposal, ok := app.GovKeeper.GetProposal(ctx, proposalID) assert.Assert(t, ok) - passes, burnDeposits, tallyResults := app.GovKeeper.Tally(ctx, proposal) + passes, burnDeposits, tallyResults, _ := app.GovKeeper.Tally(ctx, proposal) assert.Assert(t, passes) assert.Assert(t, burnDeposits == false) @@ -164,7 +164,7 @@ func TestTallyOnlyValidatorsVetoed(t *testing.T) { proposal, ok := app.GovKeeper.GetProposal(ctx, proposalID) assert.Assert(t, ok) - passes, burnDeposits, tallyResults := app.GovKeeper.Tally(ctx, proposal) + passes, burnDeposits, tallyResults, _ := app.GovKeeper.Tally(ctx, proposal) assert.Assert(t, passes == false) assert.Assert(t, burnDeposits) @@ -192,7 +192,7 @@ func TestTallyOnlyValidatorsAbstainPasses(t *testing.T) { proposal, ok := app.GovKeeper.GetProposal(ctx, proposalID) assert.Assert(t, ok) - passes, burnDeposits, tallyResults := app.GovKeeper.Tally(ctx, proposal) + passes, burnDeposits, tallyResults, _ := app.GovKeeper.Tally(ctx, proposal) assert.Assert(t, passes) assert.Assert(t, burnDeposits == false) @@ -220,7 +220,7 @@ func TestTallyOnlyValidatorsAbstainFails(t *testing.T) { proposal, ok := app.GovKeeper.GetProposal(ctx, proposalID) assert.Assert(t, ok) - passes, burnDeposits, tallyResults := app.GovKeeper.Tally(ctx, proposal) + passes, burnDeposits, tallyResults, _ := app.GovKeeper.Tally(ctx, proposal) assert.Assert(t, passes == false) assert.Assert(t, burnDeposits == false) @@ -248,7 +248,7 @@ func TestTallyOnlyValidatorsNonVoter(t *testing.T) { proposal, ok := app.GovKeeper.GetProposal(ctx, proposalID) assert.Assert(t, ok) - passes, burnDeposits, tallyResults := app.GovKeeper.Tally(ctx, proposal) + passes, burnDeposits, tallyResults, _ := app.GovKeeper.Tally(ctx, proposal) assert.Assert(t, passes == false) assert.Assert(t, burnDeposits == false) @@ -286,7 +286,7 @@ func TestTallyDelgatorOverride(t *testing.T) { proposal, ok := app.GovKeeper.GetProposal(ctx, proposalID) assert.Assert(t, ok) - passes, burnDeposits, tallyResults := app.GovKeeper.Tally(ctx, proposal) + passes, burnDeposits, tallyResults, _ := app.GovKeeper.Tally(ctx, proposal) assert.Assert(t, passes == false) assert.Assert(t, burnDeposits == false) @@ -323,7 +323,7 @@ func TestTallyDelgatorInherit(t *testing.T) { proposal, ok := app.GovKeeper.GetProposal(ctx, proposalID) assert.Assert(t, ok) - passes, burnDeposits, tallyResults := app.GovKeeper.Tally(ctx, proposal) + passes, burnDeposits, tallyResults, _ := app.GovKeeper.Tally(ctx, proposal) assert.Assert(t, passes) assert.Assert(t, burnDeposits == false) @@ -365,7 +365,7 @@ func TestTallyDelgatorMultipleOverride(t *testing.T) { proposal, ok := app.GovKeeper.GetProposal(ctx, proposalID) assert.Assert(t, ok) - passes, burnDeposits, tallyResults := app.GovKeeper.Tally(ctx, proposal) + passes, burnDeposits, tallyResults, _ := app.GovKeeper.Tally(ctx, proposal) assert.Assert(t, passes == false) assert.Assert(t, burnDeposits == false) @@ -408,7 +408,7 @@ func TestTallyDelgatorMultipleInherit(t *testing.T) { proposal, ok := app.GovKeeper.GetProposal(ctx, proposalID) assert.Assert(t, ok) - passes, burnDeposits, tallyResults := app.GovKeeper.Tally(ctx, proposal) + passes, burnDeposits, tallyResults, _ := app.GovKeeper.Tally(ctx, proposal) assert.Assert(t, passes == false) assert.Assert(t, burnDeposits == false) @@ -453,7 +453,7 @@ func TestTallyJailedValidator(t *testing.T) { proposal, ok := app.GovKeeper.GetProposal(ctx, proposalID) assert.Assert(t, ok) - passes, burnDeposits, tallyResults := app.GovKeeper.Tally(ctx, proposal) + passes, burnDeposits, tallyResults, _ := app.GovKeeper.Tally(ctx, proposal) assert.Assert(t, passes) assert.Assert(t, burnDeposits == false) @@ -488,7 +488,7 @@ func TestTallyValidatorMultipleDelegations(t *testing.T) { proposal, ok := app.GovKeeper.GetProposal(ctx, proposalID) assert.Assert(t, ok) - passes, burnDeposits, tallyResults := app.GovKeeper.Tally(ctx, proposal) + passes, burnDeposits, tallyResults, _ := app.GovKeeper.Tally(ctx, proposal) assert.Assert(t, passes) assert.Assert(t, burnDeposits == false) diff --git a/tools/rosetta/go.mod b/tools/rosetta/go.mod index cbefbd6df114..f5bf4b3ced97 100644 --- a/tools/rosetta/go.mod +++ b/tools/rosetta/go.mod @@ -21,7 +21,7 @@ require ( cosmossdk.io/collections v0.1.0 // indirect cosmossdk.io/core v0.6.1 // indirect cosmossdk.io/depinject v1.0.0-alpha.3 // indirect - cosmossdk.io/errors v1.0.0-beta.7 // indirect + cosmossdk.io/errors v1.0.0-beta.7.0.20230429155654-3ee8242364e4 // indirect cosmossdk.io/store v0.1.0-alpha.1.0.20230328185921-37ba88872dbc // indirect cosmossdk.io/x/tx v0.6.1 // indirect filippo.io/edwards25519 v1.0.0 // indirect @@ -141,8 +141,8 @@ require ( // TODO: remove after merge of https://github.com/cosmos/cosmos-sdk/pull/15873 and tagging releases replace ( + cosmossdk.io/core => ../../core cosmossdk.io/store => ../../store cosmossdk.io/x/tx => ../../x/tx - cosmossdk.io/core => ../../core github.com/cosmos/cosmos-sdk => ../.. ) diff --git a/tools/rosetta/go.sum b/tools/rosetta/go.sum index 3f8bef5da1dc..00262986a6b1 100644 --- a/tools/rosetta/go.sum +++ b/tools/rosetta/go.sum @@ -39,12 +39,10 @@ cosmossdk.io/api v0.4.1 h1:0ikaYM6GyxTYYcfBiyR8YnLCfhNnhKpEFnaSepCTmqg= cosmossdk.io/api v0.4.1/go.mod h1:jR7k5ok90LxW2lFUXvd8Vpo/dr4PpiyVegxdm7b1ZdE= cosmossdk.io/collections v0.1.0 h1:nzJGeiq32KnZroSrhB6rPifw4I85Cgmzw/YAmr4luv8= cosmossdk.io/collections v0.1.0/go.mod h1:xbauc0YsbUF8qKMVeBZl0pFCunxBIhKN/WlxpZ3lBuo= -cosmossdk.io/core v0.6.1 h1:OBy7TI2W+/gyn2z40vVvruK3di+cAluinA6cybFbE7s= -cosmossdk.io/core v0.6.1/go.mod h1:g3MMBCBXtxbDWBURDVnJE7XML4BG5qENhs0gzkcpuFA= cosmossdk.io/depinject v1.0.0-alpha.3 h1:6evFIgj//Y3w09bqOUOzEpFj5tsxBqdc5CfkO7z+zfw= cosmossdk.io/depinject v1.0.0-alpha.3/go.mod h1:eRbcdQ7MRpIPEM5YUJh8k97nxHpYbc3sMUnEtt8HPWU= -cosmossdk.io/errors v1.0.0-beta.7 h1:gypHW76pTQGVnHKo6QBkb4yFOJjC+sUGRc5Al3Odj1w= -cosmossdk.io/errors v1.0.0-beta.7/go.mod h1:mz6FQMJRku4bY7aqS/Gwfcmr/ue91roMEKAmDUDpBfE= +cosmossdk.io/errors v1.0.0-beta.7.0.20230429155654-3ee8242364e4 h1:rOy7iw7HlwKc5Af5qIHLXdBx/F98o6du/I/WGwOW6eA= +cosmossdk.io/errors v1.0.0-beta.7.0.20230429155654-3ee8242364e4/go.mod h1:AwrAxbvuH9FdatzJX463kMYNMVkjujWU/xR+HsimWTw= cosmossdk.io/log v1.1.0 h1:v0ogPHYeTzPcBTcPR1A3j1hkei4pZama8kz8LKlCMv0= cosmossdk.io/log v1.1.0/go.mod h1:6zjroETlcDs+mm62gd8Ig7mZ+N+fVOZS91V17H+M4N4= cosmossdk.io/math v1.0.0 h1:ro9w7eKx23om2tZz/VM2Pf+z2WAbGX1yDQQOJ6iGeJw= diff --git a/x/gov/abci.go b/x/gov/abci.go index 934e770545a0..9d4085d6933d 100644 --- a/x/gov/abci.go +++ b/x/gov/abci.go @@ -12,20 +12,30 @@ import ( ) // EndBlocker called every block, process inflation, update validator set. -func EndBlocker(ctx sdk.Context, keeper *keeper.Keeper) { +func EndBlocker(ctx sdk.Context, keeper *keeper.Keeper) error { defer telemetry.ModuleMeasureSince(types.ModuleName, time.Now(), telemetry.MetricKeyEndBlocker) logger := ctx.Logger().With("module", "x/"+types.ModuleName) // delete dead proposals from store and returns theirs deposits. // A proposal is dead when it's inactive and didn't get enough deposit on time to get into voting phase. - keeper.IterateInactiveProposalsQueue(ctx, ctx.BlockHeader().Time, func(proposal v1.Proposal) bool { - keeper.DeleteProposal(ctx, proposal.Id) + err := keeper.IterateInactiveProposalsQueue(ctx, ctx.BlockHeader().Time, func(proposal v1.Proposal) error { + err := keeper.DeleteProposal(ctx, proposal.Id) + if err != nil { + return err + } - params := keeper.GetParams(ctx) + params, err := keeper.GetParams(ctx) + if err != nil { + return err + } if !params.BurnProposalDepositPrevote { - keeper.RefundAndDeleteDeposits(ctx, proposal.Id) // refund deposit if proposal got removed without getting 100% of the proposal + err = keeper.RefundAndDeleteDeposits(ctx, proposal.Id) // refund deposit if proposal got removed without getting 100% of the proposal } else { - keeper.DeleteAndBurnDeposits(ctx, proposal.Id) // burn the deposit if proposal got removed without getting 100% of the proposal + err = keeper.DeleteAndBurnDeposits(ctx, proposal.Id) // burn the deposit if proposal got removed without getting 100% of the proposal + } + + if err != nil { + return err } // called when proposal become inactive @@ -48,14 +58,20 @@ func EndBlocker(ctx sdk.Context, keeper *keeper.Keeper) { "total_deposit", sdk.NewCoins(proposal.TotalDeposit...).String(), ) - return false + return nil }) + if err != nil { + return err + } // fetch active proposals whose voting periods have ended (are passed the block time) - keeper.IterateActiveProposalsQueue(ctx, ctx.BlockHeader().Time, func(proposal v1.Proposal) bool { + return keeper.IterateActiveProposalsQueue(ctx, ctx.BlockHeader().Time, func(proposal v1.Proposal) error { var tagValue, logMsg string - passes, burnDeposits, tallyResults := keeper.Tally(ctx, proposal) + passes, burnDeposits, tallyResults, err := keeper.Tally(ctx, proposal) + if err != nil { + return err + } // If an expedited proposal fails, we do not want to update // the deposit at this point since the proposal is converted to regular. @@ -63,13 +79,20 @@ func EndBlocker(ctx sdk.Context, keeper *keeper.Keeper) { // EXCEPT when an expedited proposal fails. if !(proposal.Expedited && !passes) { if burnDeposits { - keeper.DeleteAndBurnDeposits(ctx, proposal.Id) + err = keeper.DeleteAndBurnDeposits(ctx, proposal.Id) } else { - keeper.RefundAndDeleteDeposits(ctx, proposal.Id) + err = keeper.RefundAndDeleteDeposits(ctx, proposal.Id) + } + + if err != nil { + return err } } - keeper.RemoveFromActiveProposalQueue(ctx, proposal.Id, *proposal.VotingEndTime) + err = keeper.RemoveFromActiveProposalQueue(ctx, proposal.Id, *proposal.VotingEndTime) + if err != nil { + return err + } switch { case passes: @@ -129,11 +152,17 @@ func EndBlocker(ctx sdk.Context, keeper *keeper.Keeper) { // once the regular voting period expires again, the tally is repeated // according to the regular proposal rules. proposal.Expedited = false - params := keeper.GetParams(ctx) + params, err := keeper.GetParams(ctx) + if err != nil { + return err + } endTime := proposal.VotingStartTime.Add(*params.VotingPeriod) proposal.VotingEndTime = &endTime - keeper.InsertActiveProposalQueue(ctx, proposal.Id, *proposal.VotingEndTime) + err = keeper.InsertActiveProposalQueue(ctx, proposal.Id, *proposal.VotingEndTime) + if err != nil { + return err + } tagValue = types.AttributeValueExpeditedProposalRejected logMsg = "expedited proposal converted to regular" @@ -145,7 +174,10 @@ func EndBlocker(ctx sdk.Context, keeper *keeper.Keeper) { proposal.FinalTallyResult = &tallyResults - keeper.SetProposal(ctx, proposal) + err = keeper.SetProposal(ctx, proposal) + if err != nil { + return err + } // when proposal become active keeper.Hooks().AfterProposalVotingPeriodEnded(ctx, proposal.Id) @@ -168,6 +200,6 @@ func EndBlocker(ctx sdk.Context, keeper *keeper.Keeper) { ), ) - return false + return nil }) } diff --git a/x/gov/abci_test.go b/x/gov/abci_test.go index 2423c488d498..3c99ab77e9b3 100644 --- a/x/gov/abci_test.go +++ b/x/gov/abci_test.go @@ -32,7 +32,7 @@ func TestTickExpiredDepositPeriod(t *testing.T) { govMsgSvr := keeper.NewMsgServerImpl(suite.GovKeeper) - inactiveQueue := suite.GovKeeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time) + inactiveQueue, _ := suite.GovKeeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time) require.False(t, inactiveQueue.Valid()) inactiveQueue.Close() @@ -51,7 +51,7 @@ func TestTickExpiredDepositPeriod(t *testing.T) { require.NoError(t, err) require.NotNil(t, res) - inactiveQueue = suite.GovKeeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time) + inactiveQueue, _ = suite.GovKeeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time) require.False(t, inactiveQueue.Valid()) inactiveQueue.Close() @@ -59,21 +59,22 @@ func TestTickExpiredDepositPeriod(t *testing.T) { newHeader.Time = ctx.BlockHeader().Time.Add(time.Duration(1) * time.Second) ctx = ctx.WithBlockHeader(newHeader) - inactiveQueue = suite.GovKeeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time) + inactiveQueue, _ = suite.GovKeeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time) require.False(t, inactiveQueue.Valid()) inactiveQueue.Close() + params, _ := suite.GovKeeper.GetParams(ctx) newHeader = ctx.BlockHeader() - newHeader.Time = ctx.BlockHeader().Time.Add(*suite.GovKeeper.GetParams(ctx).MaxDepositPeriod) + newHeader.Time = ctx.BlockHeader().Time.Add(*params.MaxDepositPeriod) ctx = ctx.WithBlockHeader(newHeader) - inactiveQueue = suite.GovKeeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time) + inactiveQueue, _ = suite.GovKeeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time) require.True(t, inactiveQueue.Valid()) inactiveQueue.Close() gov.EndBlocker(ctx, suite.GovKeeper) - inactiveQueue = suite.GovKeeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time) + inactiveQueue, _ = suite.GovKeeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time) require.False(t, inactiveQueue.Valid()) inactiveQueue.Close() } @@ -89,7 +90,7 @@ func TestTickMultipleExpiredDepositPeriod(t *testing.T) { govMsgSvr := keeper.NewMsgServerImpl(suite.GovKeeper) - inactiveQueue := suite.GovKeeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time) + inactiveQueue, _ := suite.GovKeeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time) require.False(t, inactiveQueue.Valid()) inactiveQueue.Close() @@ -108,7 +109,7 @@ func TestTickMultipleExpiredDepositPeriod(t *testing.T) { require.NoError(t, err) require.NotNil(t, res) - inactiveQueue = suite.GovKeeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time) + inactiveQueue, _ = suite.GovKeeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time) require.False(t, inactiveQueue.Valid()) inactiveQueue.Close() @@ -116,7 +117,7 @@ func TestTickMultipleExpiredDepositPeriod(t *testing.T) { newHeader.Time = ctx.BlockHeader().Time.Add(time.Duration(2) * time.Second) ctx = ctx.WithBlockHeader(newHeader) - inactiveQueue = suite.GovKeeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time) + inactiveQueue, _ = suite.GovKeeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time) require.False(t, inactiveQueue.Valid()) inactiveQueue.Close() @@ -136,16 +137,17 @@ func TestTickMultipleExpiredDepositPeriod(t *testing.T) { require.NotNil(t, res) newHeader = ctx.BlockHeader() - newHeader.Time = ctx.BlockHeader().Time.Add(*suite.GovKeeper.GetParams(ctx).MaxDepositPeriod).Add(time.Duration(-1) * time.Second) + params, _ := suite.GovKeeper.GetParams(ctx) + newHeader.Time = ctx.BlockHeader().Time.Add(*params.MaxDepositPeriod).Add(time.Duration(-1) * time.Second) ctx = ctx.WithBlockHeader(newHeader) - inactiveQueue = suite.GovKeeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time) + inactiveQueue, _ = suite.GovKeeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time) require.True(t, inactiveQueue.Valid()) inactiveQueue.Close() gov.EndBlocker(ctx, suite.GovKeeper) - inactiveQueue = suite.GovKeeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time) + inactiveQueue, _ = suite.GovKeeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time) require.False(t, inactiveQueue.Valid()) inactiveQueue.Close() @@ -153,13 +155,13 @@ func TestTickMultipleExpiredDepositPeriod(t *testing.T) { newHeader.Time = ctx.BlockHeader().Time.Add(time.Duration(5) * time.Second) ctx = ctx.WithBlockHeader(newHeader) - inactiveQueue = suite.GovKeeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time) + inactiveQueue, _ = suite.GovKeeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time) require.True(t, inactiveQueue.Valid()) inactiveQueue.Close() gov.EndBlocker(ctx, suite.GovKeeper) - inactiveQueue = suite.GovKeeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time) + inactiveQueue, _ = suite.GovKeeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time) require.False(t, inactiveQueue.Valid()) inactiveQueue.Close() } @@ -175,10 +177,10 @@ func TestTickPassedDepositPeriod(t *testing.T) { govMsgSvr := keeper.NewMsgServerImpl(suite.GovKeeper) - inactiveQueue := suite.GovKeeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time) + inactiveQueue, _ := suite.GovKeeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time) require.False(t, inactiveQueue.Valid()) inactiveQueue.Close() - activeQueue := suite.GovKeeper.ActiveProposalQueueIterator(ctx, ctx.BlockHeader().Time) + activeQueue, _ := suite.GovKeeper.ActiveProposalQueueIterator(ctx, ctx.BlockHeader().Time) require.False(t, activeQueue.Valid()) activeQueue.Close() @@ -199,7 +201,7 @@ func TestTickPassedDepositPeriod(t *testing.T) { proposalID := res.ProposalId - inactiveQueue = suite.GovKeeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time) + inactiveQueue, _ = suite.GovKeeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time) require.False(t, inactiveQueue.Valid()) inactiveQueue.Close() @@ -207,7 +209,7 @@ func TestTickPassedDepositPeriod(t *testing.T) { newHeader.Time = ctx.BlockHeader().Time.Add(time.Duration(1) * time.Second) ctx = ctx.WithBlockHeader(newHeader) - inactiveQueue = suite.GovKeeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time) + inactiveQueue, _ = suite.GovKeeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time) require.False(t, inactiveQueue.Valid()) inactiveQueue.Close() @@ -217,7 +219,7 @@ func TestTickPassedDepositPeriod(t *testing.T) { require.NoError(t, err) require.NotNil(t, res1) - activeQueue = suite.GovKeeper.ActiveProposalQueueIterator(ctx, ctx.BlockHeader().Time) + activeQueue, _ = suite.GovKeeper.ActiveProposalQueueIterator(ctx, ctx.BlockHeader().Time) require.False(t, activeQueue.Valid()) activeQueue.Close() } @@ -251,10 +253,10 @@ func TestTickPassedVotingPeriod(t *testing.T) { govMsgSvr := keeper.NewMsgServerImpl(suite.GovKeeper) - inactiveQueue := suite.GovKeeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time) + inactiveQueue, _ := suite.GovKeeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time) require.False(t, inactiveQueue.Valid()) inactiveQueue.Close() - activeQueue := suite.GovKeeper.ActiveProposalQueueIterator(ctx, ctx.BlockHeader().Time) + activeQueue, _ := suite.GovKeeper.ActiveProposalQueueIterator(ctx, ctx.BlockHeader().Time) require.False(t, activeQueue.Valid()) activeQueue.Close() @@ -278,33 +280,33 @@ func TestTickPassedVotingPeriod(t *testing.T) { require.NoError(t, err) require.NotNil(t, res1) - params := suite.GovKeeper.GetParams(ctx) + params, _ := suite.GovKeeper.GetParams(ctx) votingPeriod := params.VotingPeriod if tc.expedited { votingPeriod = params.ExpeditedVotingPeriod } newHeader = ctx.BlockHeader() - newHeader.Time = ctx.BlockHeader().Time.Add(*suite.GovKeeper.GetParams(ctx).MaxDepositPeriod).Add(*votingPeriod) + newHeader.Time = ctx.BlockHeader().Time.Add(*params.MaxDepositPeriod).Add(*votingPeriod) ctx = ctx.WithBlockHeader(newHeader) - inactiveQueue = suite.GovKeeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time) + inactiveQueue, _ = suite.GovKeeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time) require.False(t, inactiveQueue.Valid()) inactiveQueue.Close() - activeQueue = suite.GovKeeper.ActiveProposalQueueIterator(ctx, ctx.BlockHeader().Time) + activeQueue, _ = suite.GovKeeper.ActiveProposalQueueIterator(ctx, ctx.BlockHeader().Time) require.True(t, activeQueue.Valid()) activeProposalID := types.GetProposalIDFromBytes(activeQueue.Value()) - proposal, ok := suite.GovKeeper.GetProposal(ctx, activeProposalID) - require.True(t, ok) + proposal, err := suite.GovKeeper.GetProposal(ctx, activeProposalID) + require.Nil(t, err) require.Equal(t, v1.StatusVotingPeriod, proposal.Status) activeQueue.Close() gov.EndBlocker(ctx, suite.GovKeeper) - activeQueue = suite.GovKeeper.ActiveProposalQueueIterator(ctx, ctx.BlockHeader().Time) + activeQueue, _ = suite.GovKeeper.ActiveProposalQueueIterator(ctx, ctx.BlockHeader().Time) if !tc.expedited { require.False(t, activeQueue.Valid()) activeQueue.Close() @@ -315,8 +317,8 @@ func TestTickPassedVotingPeriod(t *testing.T) { require.True(t, activeQueue.Valid()) activeProposalID = types.GetProposalIDFromBytes(activeQueue.Value()) - proposal, ok = suite.GovKeeper.GetProposal(ctx, activeProposalID) - require.True(t, ok) + proposal, err = suite.GovKeeper.GetProposal(ctx, activeProposalID) + require.Nil(t, err) require.Equal(t, v1.StatusVotingPeriod, proposal.Status) require.False(t, proposal.Expedited) require.Equal(t, proposal.VotingStartTime.Add(*params.VotingPeriod), *proposal.VotingEndTime) @@ -387,7 +389,8 @@ func TestProposalPassedEndblocker(t *testing.T) { require.NoError(t, err) newHeader := ctx.BlockHeader() - newHeader.Time = ctx.BlockHeader().Time.Add(*suite.GovKeeper.GetParams(ctx).MaxDepositPeriod).Add(*suite.GovKeeper.GetParams(ctx).VotingPeriod) + params, _ := suite.GovKeeper.GetParams(ctx) + newHeader.Time = ctx.BlockHeader().Time.Add(*params.MaxDepositPeriod).Add(*params.VotingPeriod) ctx = ctx.WithBlockHeader(newHeader) gov.EndBlocker(ctx, suite.GovKeeper) @@ -432,8 +435,9 @@ func TestEndBlockerProposalHandlerFailed(t *testing.T) { err = suite.GovKeeper.AddVote(ctx, proposal.Id, addrs[0], v1.NewNonSplitVoteOption(v1.OptionYes), "") require.NoError(t, err) + params, _ := suite.GovKeeper.GetParams(ctx) newHeader := ctx.BlockHeader() - newHeader.Time = ctx.BlockHeader().Time.Add(*suite.GovKeeper.GetParams(ctx).MaxDepositPeriod).Add(*suite.GovKeeper.GetParams(ctx).VotingPeriod) + newHeader.Time = ctx.BlockHeader().Time.Add(*params.MaxDepositPeriod).Add(*params.VotingPeriod) ctx = ctx.WithBlockHeader(newHeader) // validate that the proposal fails/has been rejected @@ -445,8 +449,8 @@ func TestEndBlockerProposalHandlerFailed(t *testing.T) { require.True(t, eventOk) require.Contains(t, attr[0].Value, "failed on execution") - proposal, ok := suite.GovKeeper.GetProposal(ctx, proposal.Id) - require.True(t, ok) + proposal, err = suite.GovKeeper.GetProposal(ctx, proposal.Id) + require.Nil(t, err) require.Equal(t, v1.StatusFailed, proposal.Status) } @@ -481,7 +485,8 @@ func TestExpeditedProposal_PassAndConversionToRegular(t *testing.T) { ctx := app.BaseApp.NewContext(false, cmtproto.Header{}) depositMultiplier := getDepositMultiplier(true) addrs := simtestutil.AddTestAddrs(suite.BankKeeper, suite.StakingKeeper, ctx, 3, valTokens.Mul(math.NewInt(depositMultiplier))) - params := suite.GovKeeper.GetParams(ctx) + params, err := suite.GovKeeper.GetParams(ctx) + require.NoError(t, err) SortAddresses(addrs) @@ -498,10 +503,10 @@ func TestExpeditedProposal_PassAndConversionToRegular(t *testing.T) { createValidators(t, stakingMsgSvr, ctx, []sdk.ValAddress{valAddr}, []int64{10}) suite.StakingKeeper.EndBlocker(ctx) - inactiveQueue := suite.GovKeeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time) + inactiveQueue, _ := suite.GovKeeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time) require.False(t, inactiveQueue.Valid()) inactiveQueue.Close() - activeQueue := suite.GovKeeper.ActiveProposalQueueIterator(ctx, ctx.BlockHeader().Time) + activeQueue, _ := suite.GovKeeper.ActiveProposalQueueIterator(ctx, ctx.BlockHeader().Time) require.False(t, activeQueue.Valid()) activeQueue.Close() @@ -536,16 +541,16 @@ func TestExpeditedProposal_PassAndConversionToRegular(t *testing.T) { newHeader.Time = ctx.BlockHeader().Time.Add(*params.MaxDepositPeriod).Add(*params.ExpeditedVotingPeriod) ctx = ctx.WithBlockHeader(newHeader) - inactiveQueue = suite.GovKeeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time) + inactiveQueue, _ = suite.GovKeeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time) require.False(t, inactiveQueue.Valid()) inactiveQueue.Close() - activeQueue = suite.GovKeeper.ActiveProposalQueueIterator(ctx, ctx.BlockHeader().Time) + activeQueue, _ = suite.GovKeeper.ActiveProposalQueueIterator(ctx, ctx.BlockHeader().Time) require.True(t, activeQueue.Valid()) activeProposalID := types.GetProposalIDFromBytes(activeQueue.Value()) - proposal, ok := suite.GovKeeper.GetProposal(ctx, activeProposalID) - require.True(t, ok) + proposal, err := suite.GovKeeper.GetProposal(ctx, activeProposalID) + require.Nil(t, err) require.Equal(t, v1.StatusVotingPeriod, proposal.Status) activeQueue.Close() @@ -559,13 +564,13 @@ func TestExpeditedProposal_PassAndConversionToRegular(t *testing.T) { // Here the expedited proposal is converted to regular after expiry. gov.EndBlocker(ctx, suite.GovKeeper) - activeQueue = suite.GovKeeper.ActiveProposalQueueIterator(ctx, ctx.BlockHeader().Time) + activeQueue, _ = suite.GovKeeper.ActiveProposalQueueIterator(ctx, ctx.BlockHeader().Time) if tc.expeditedPasses { require.False(t, activeQueue.Valid()) - proposal, ok = suite.GovKeeper.GetProposal(ctx, activeProposalID) - require.True(t, ok) + proposal, err = suite.GovKeeper.GetProposal(ctx, activeProposalID) + require.Nil(t, err) require.Equal(t, v1.StatusPassed, proposal.Status) @@ -588,8 +593,8 @@ func TestExpeditedProposal_PassAndConversionToRegular(t *testing.T) { activeProposalID = types.GetProposalIDFromBytes(activeQueue.Value()) activeQueue.Close() - proposal, ok = suite.GovKeeper.GetProposal(ctx, activeProposalID) - require.True(t, ok) + proposal, err = suite.GovKeeper.GetProposal(ctx, activeProposalID) + require.Nil(t, err) require.Equal(t, v1.StatusVotingPeriod, proposal.Status) require.False(t, proposal.Expedited) require.Equal(t, proposal.VotingStartTime.Add(*params.VotingPeriod), *proposal.VotingEndTime) @@ -608,11 +613,11 @@ func TestExpeditedProposal_PassAndConversionToRegular(t *testing.T) { newHeader.Time = ctx.BlockHeader().Time.Add(*params.MaxDepositPeriod).Add(*params.VotingPeriod) ctx = ctx.WithBlockHeader(newHeader) - inactiveQueue = suite.GovKeeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time) + inactiveQueue, _ = suite.GovKeeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time) require.False(t, inactiveQueue.Valid()) inactiveQueue.Close() - activeQueue = suite.GovKeeper.ActiveProposalQueueIterator(ctx, ctx.BlockHeader().Time) + activeQueue, _ = suite.GovKeeper.ActiveProposalQueueIterator(ctx, ctx.BlockHeader().Time) require.True(t, activeQueue.Valid()) if tc.regularEventuallyPassing { @@ -631,11 +636,11 @@ func TestExpeditedProposal_PassAndConversionToRegular(t *testing.T) { submitterEventualBalance := suite.BankKeeper.GetAllBalances(ctx, addrs[0]) depositorEventualBalance := suite.BankKeeper.GetAllBalances(ctx, addrs[1]) - activeQueue = suite.GovKeeper.ActiveProposalQueueIterator(ctx, ctx.BlockHeader().Time) + activeQueue, _ = suite.GovKeeper.ActiveProposalQueueIterator(ctx, ctx.BlockHeader().Time) require.False(t, activeQueue.Valid()) - proposal, ok = suite.GovKeeper.GetProposal(ctx, activeProposalID) - require.True(t, ok) + proposal, err = suite.GovKeeper.GetProposal(ctx, activeProposalID) + require.Nil(t, err) if tc.regularEventuallyPassing { // Module account has refunded the deposit diff --git a/x/gov/genesis.go b/x/gov/genesis.go index c8bdf162049e..0c0c156f6910 100644 --- a/x/gov/genesis.go +++ b/x/gov/genesis.go @@ -11,9 +11,20 @@ import ( // InitGenesis - store genesis parameters func InitGenesis(ctx sdk.Context, ak types.AccountKeeper, bk types.BankKeeper, k *keeper.Keeper, data *v1.GenesisState) { - k.SetProposalID(ctx, data.StartingProposalId) - k.SetParams(ctx, *data.Params) - k.SetConstitution(ctx, data.Constitution) + err := k.SetProposalID(ctx, data.StartingProposalId) + if err != nil { + panic(err) + } + + err = k.SetParams(ctx, *data.Params) + if err != nil { + panic(err) + } + + err = k.SetConstitution(ctx, data.Constitution) + if err != nil { + panic(err) + } // check if the deposits pool account exists moduleAcc := k.GetGovernanceAccount(ctx) @@ -54,19 +65,42 @@ func InitGenesis(ctx sdk.Context, ak types.AccountKeeper, bk types.BankKeeper, k } // ExportGenesis - output genesis parameters -func ExportGenesis(ctx sdk.Context, k *keeper.Keeper) *v1.GenesisState { - startingProposalID, _ := k.GetProposalID(ctx) - proposals := k.GetProposals(ctx) - constitution := k.GetConstitution(ctx) - params := k.GetParams(ctx) +func ExportGenesis(ctx sdk.Context, k *keeper.Keeper) (*v1.GenesisState, error) { + startingProposalID, err := k.GetProposalID(ctx) + if err != nil { + return nil, err + } + + proposals, err := k.GetProposals(ctx) + if err != nil { + return nil, err + } + + constitution, err := k.GetConstitution(ctx) + if err != nil { + return nil, err + } + + params, err := k.GetParams(ctx) + if err != nil { + return nil, err + } var proposalsDeposits v1.Deposits var proposalsVotes v1.Votes for _, proposal := range proposals { - deposits := k.GetDeposits(ctx, proposal.Id) + deposits, err := k.GetDeposits(ctx, proposal.Id) + if err != nil { + return nil, err + } + proposalsDeposits = append(proposalsDeposits, deposits...) - votes := k.GetVotes(ctx, proposal.Id) + votes, err := k.GetVotes(ctx, proposal.Id) + if err != nil { + return nil, err + } + proposalsVotes = append(proposalsVotes, votes...) } @@ -77,5 +111,5 @@ func ExportGenesis(ctx sdk.Context, k *keeper.Keeper) *v1.GenesisState { Proposals: proposals, Params: ¶ms, Constitution: constitution, - } + }, nil } diff --git a/x/gov/genesis_test.go b/x/gov/genesis_test.go index 5b8b0d32c6f4..730a99ae42c3 100644 --- a/x/gov/genesis_test.go +++ b/x/gov/genesis_test.go @@ -33,6 +33,7 @@ func TestImportExportQueues_ErrorUnconsistentState(t *testing.T) { }) }) gov.InitGenesis(ctx, suite.AccountKeeper, suite.BankKeeper, suite.GovKeeper, v1.DefaultGenesisState()) - genState := gov.ExportGenesis(ctx, suite.GovKeeper) + genState, err := gov.ExportGenesis(ctx, suite.GovKeeper) + require.NoError(t, err) require.Equal(t, genState, v1.DefaultGenesisState()) } diff --git a/x/gov/keeper/common_test.go b/x/gov/keeper/common_test.go index fe17762e0b54..242e459a74cb 100644 --- a/x/gov/keeper/common_test.go +++ b/x/gov/keeper/common_test.go @@ -12,6 +12,7 @@ import ( storetypes "cosmossdk.io/store/types" "github.com/cosmos/cosmos-sdk/baseapp" + "github.com/cosmos/cosmos-sdk/runtime" "github.com/cosmos/cosmos-sdk/testutil" "github.com/cosmos/cosmos-sdk/testutil/testdata" sdk "github.com/cosmos/cosmos-sdk/types" @@ -58,6 +59,7 @@ func setupGovKeeper(t *testing.T) ( sdk.Context, ) { key := storetypes.NewKVStoreKey(types.StoreKey) + storeService := runtime.NewKVStoreService(key) testCtx := testutil.DefaultContextWithDB(t, key, storetypes.NewTransientStoreKey("transient_test")) ctx := testCtx.Ctx.WithBlockHeader(cmtproto.Header{Time: cmttime.Now()}) encCfg := moduletestutil.MakeTestEncodingConfig() @@ -94,7 +96,8 @@ func setupGovKeeper(t *testing.T) ( distributionKeeper.EXPECT().FundCommunityPool(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).AnyTimes() // Gov keeper initializations - govKeeper := keeper.NewKeeper(encCfg.Codec, key, acctKeeper, bankKeeper, stakingKeeper, distributionKeeper, msr, types.DefaultConfig(), govAcct.String()) + + govKeeper := keeper.NewKeeper(encCfg.Codec, storeService, acctKeeper, bankKeeper, stakingKeeper, distributionKeeper, msr, types.DefaultConfig(), govAcct.String()) govKeeper.SetProposalID(ctx, 1) govRouter := v1beta1.NewRouter() // Also register legacy gov handlers to test them too. govRouter.AddRoute(types.RouterKey, v1beta1.ProposalHandler) diff --git a/x/gov/keeper/constitution.go b/x/gov/keeper/constitution.go index db3ab6e3913a..0f791a6f1821 100644 --- a/x/gov/keeper/constitution.go +++ b/x/gov/keeper/constitution.go @@ -1,18 +1,21 @@ package keeper import ( - sdk "github.com/cosmos/cosmos-sdk/types" + "context" + "github.com/cosmos/cosmos-sdk/x/gov/types" ) -func (keeper Keeper) GetConstitution(ctx sdk.Context) (constitution string) { - store := ctx.KVStore(keeper.storeKey) - bz := store.Get(types.KeyConstitution) +// GetConstitution gets the chain's constitution. +func (keeper Keeper) GetConstitution(ctx context.Context) (string, error) { + store := keeper.storeService.OpenKVStore(ctx) + bz, err := store.Get(types.KeyConstitution) - return string(bz) + return string(bz), err } -func (keeper Keeper) SetConstitution(ctx sdk.Context, constitution string) { - store := ctx.KVStore(keeper.storeKey) - store.Set(types.KeyConstitution, []byte(constitution)) +// GetConstitution sets the chain's constitution. +func (keeper Keeper) SetConstitution(ctx context.Context, constitution string) error { + store := keeper.storeService.OpenKVStore(ctx) + return store.Set(types.KeyConstitution, []byte(constitution)) } diff --git a/x/gov/keeper/deposit.go b/x/gov/keeper/deposit.go index e83cc493848d..7cfebba67efb 100644 --- a/x/gov/keeper/deposit.go +++ b/x/gov/keeper/deposit.go @@ -1,12 +1,14 @@ package keeper import ( + "context" "fmt" "cosmossdk.io/errors" sdkmath "cosmossdk.io/math" storetypes "cosmossdk.io/store/types" + "github.com/cosmos/cosmos-sdk/runtime" sdk "github.com/cosmos/cosmos-sdk/types" disttypes "github.com/cosmos/cosmos-sdk/x/distribution/types" "github.com/cosmos/cosmos-sdk/x/gov/types" @@ -14,113 +16,148 @@ import ( ) // GetDeposit gets the deposit of a specific depositor on a specific proposal -func (keeper Keeper) GetDeposit(ctx sdk.Context, proposalID uint64, depositorAddr sdk.AccAddress) (deposit v1.Deposit, found bool) { - store := ctx.KVStore(keeper.storeKey) - bz := store.Get(types.DepositKey(proposalID, depositorAddr)) +func (keeper Keeper) GetDeposit(ctx context.Context, proposalID uint64, depositorAddr sdk.AccAddress) (deposit v1.Deposit, err error) { + store := keeper.storeService.OpenKVStore(ctx) + bz, err := store.Get(types.DepositKey(proposalID, depositorAddr)) + if err != nil { + return deposit, err + } + if bz == nil { - return deposit, false + return deposit, types.ErrDepositNotFound } - keeper.cdc.MustUnmarshal(bz, &deposit) + err = keeper.cdc.Unmarshal(bz, &deposit) + if err != nil { + return deposit, err + } - return deposit, true + return deposit, nil } // SetDeposit sets a Deposit to the gov store -func (keeper Keeper) SetDeposit(ctx sdk.Context, deposit v1.Deposit) { - store := ctx.KVStore(keeper.storeKey) - bz := keeper.cdc.MustMarshal(&deposit) +func (keeper Keeper) SetDeposit(ctx context.Context, deposit v1.Deposit) error { + store := keeper.storeService.OpenKVStore(ctx) + bz, err := keeper.cdc.Marshal(&deposit) + if err != nil { + return err + } + depositor, err := keeper.authKeeper.StringToBytes(deposit.Depositor) if err != nil { - panic(err) + return err } - store.Set(types.DepositKey(deposit.ProposalId, depositor), bz) + return store.Set(types.DepositKey(deposit.ProposalId, depositor), bz) } // GetAllDeposits returns all the deposits from the store -func (keeper Keeper) GetAllDeposits(ctx sdk.Context) (deposits v1.Deposits) { - keeper.IterateAllDeposits(ctx, func(deposit v1.Deposit) bool { +func (keeper Keeper) GetAllDeposits(ctx context.Context) (deposits v1.Deposits, err error) { + err = keeper.IterateAllDeposits(ctx, func(deposit v1.Deposit) error { deposits = append(deposits, &deposit) - return false + return nil }) return } // GetDeposits returns all the deposits of a proposal -func (keeper Keeper) GetDeposits(ctx sdk.Context, proposalID uint64) (deposits v1.Deposits) { - keeper.IterateDeposits(ctx, proposalID, func(deposit v1.Deposit) bool { +func (keeper Keeper) GetDeposits(ctx context.Context, proposalID uint64) (deposits v1.Deposits, err error) { + err = keeper.IterateDeposits(ctx, proposalID, func(deposit v1.Deposit) error { deposits = append(deposits, &deposit) - return false + return nil }) return } // DeleteAndBurnDeposits deletes and burns all the deposits on a specific proposal. -func (keeper Keeper) DeleteAndBurnDeposits(ctx sdk.Context, proposalID uint64) { - store := ctx.KVStore(keeper.storeKey) +func (keeper Keeper) DeleteAndBurnDeposits(ctx context.Context, proposalID uint64) error { + store := keeper.storeService.OpenKVStore(ctx) - keeper.IterateDeposits(ctx, proposalID, func(deposit v1.Deposit) bool { + err := keeper.IterateDeposits(ctx, proposalID, func(deposit v1.Deposit) error { err := keeper.bankKeeper.BurnCoins(ctx, types.ModuleName, deposit.Amount) if err != nil { - panic(err) + return err } depositor, err := keeper.authKeeper.StringToBytes(deposit.Depositor) if err != nil { - panic(err) + return err } - store.Delete(types.DepositKey(proposalID, depositor)) - return false + err = store.Delete(types.DepositKey(proposalID, depositor)) + if err != nil { + return err + } + return nil }) + + return err } // IterateAllDeposits iterates over all the stored deposits and performs a callback function. -func (keeper Keeper) IterateAllDeposits(ctx sdk.Context, cb func(deposit v1.Deposit) (stop bool)) { - store := ctx.KVStore(keeper.storeKey) - iterator := storetypes.KVStorePrefixIterator(store, types.DepositsKeyPrefix) - +func (keeper Keeper) IterateAllDeposits(ctx context.Context, cb func(deposit v1.Deposit) error) error { + store := keeper.storeService.OpenKVStore(ctx) + iterator := storetypes.KVStorePrefixIterator(runtime.KVStoreAdapter(store), types.DepositsKeyPrefix) defer iterator.Close() for ; iterator.Valid(); iterator.Next() { var deposit v1.Deposit - keeper.cdc.MustUnmarshal(iterator.Value(), &deposit) + err := keeper.cdc.Unmarshal(iterator.Value(), &deposit) + if err != nil { + return err + } - if cb(deposit) { - break + err = cb(deposit) + // exit early without error if cb returns ErrStopIterating + if errors.IsOf(err, errors.ErrStopIterating) { + return nil + } else if err != nil { + return err } } + + return nil } // IterateDeposits iterates over all the proposals deposits and performs a callback function -func (keeper Keeper) IterateDeposits(ctx sdk.Context, proposalID uint64, cb func(deposit v1.Deposit) (stop bool)) { - store := ctx.KVStore(keeper.storeKey) - iterator := storetypes.KVStorePrefixIterator(store, types.DepositsKey(proposalID)) +func (keeper Keeper) IterateDeposits(ctx context.Context, proposalID uint64, cb func(deposit v1.Deposit) error) error { + store := keeper.storeService.OpenKVStore(ctx) + iterator := storetypes.KVStorePrefixIterator(runtime.KVStoreAdapter(store), types.DepositsKey(proposalID)) defer iterator.Close() for ; iterator.Valid(); iterator.Next() { var deposit v1.Deposit + err := keeper.cdc.Unmarshal(iterator.Value(), &deposit) + if err != nil { + return err + } - keeper.cdc.MustUnmarshal(iterator.Value(), &deposit) - - if cb(deposit) { - break + err = cb(deposit) + // exit early without error if cb returns ErrStopIterating + if errors.IsOf(err, errors.ErrStopIterating) { + return nil + } else if err != nil { + return err } } + + return nil } // AddDeposit adds or updates a deposit of a specific depositor on a specific proposal. // Activates voting period when appropriate and returns true in that case, else returns false. -func (keeper Keeper) AddDeposit(ctx sdk.Context, proposalID uint64, depositorAddr sdk.AccAddress, depositAmount sdk.Coins) (bool, error) { +func (keeper Keeper) AddDeposit(ctx context.Context, proposalID uint64, depositorAddr sdk.AccAddress, depositAmount sdk.Coins) (bool, error) { // Checks to see if proposal exists - proposal, ok := keeper.GetProposal(ctx, proposalID) - if !ok { - return false, errors.Wrapf(types.ErrUnknownProposal, "%d", proposalID) + proposal, err := keeper.GetProposal(ctx, proposalID) + if err != nil { + if errors.IsOf(err, types.ErrProposalNotFound) { + return false, errors.Wrapf(types.ErrUnknownProposal, "%d", proposalID) + } + return false, err } // Check if proposal is still depositable @@ -129,38 +166,54 @@ func (keeper Keeper) AddDeposit(ctx sdk.Context, proposalID uint64, depositorAdd } // update the governance module's account coins pool - err := keeper.bankKeeper.SendCoinsFromAccountToModule(ctx, depositorAddr, types.ModuleName, depositAmount) + err = keeper.bankKeeper.SendCoinsFromAccountToModule(ctx, depositorAddr, types.ModuleName, depositAmount) if err != nil { return false, err } // Update proposal proposal.TotalDeposit = sdk.NewCoins(proposal.TotalDeposit...).Add(depositAmount...) - keeper.SetProposal(ctx, proposal) + err = keeper.SetProposal(ctx, proposal) + if err != nil { + return false, err + } // Check if deposit has provided sufficient total funds to transition the proposal into the voting period activatedVotingPeriod := false - minDepositAmount := proposal.GetMinDepositFromParams(keeper.GetParams(ctx)) + params, err := keeper.GetParams(ctx) + if err != nil { + return false, err + } + minDepositAmount := proposal.GetMinDepositFromParams(params) if proposal.Status == v1.StatusDepositPeriod && sdk.NewCoins(proposal.TotalDeposit...).IsAllGTE(minDepositAmount) { - keeper.ActivateVotingPeriod(ctx, proposal) + err = keeper.ActivateVotingPeriod(ctx, proposal) + if err != nil { + return false, err + } activatedVotingPeriod = true } // Add or update deposit object - deposit, found := keeper.GetDeposit(ctx, proposalID, depositorAddr) - - if found { + deposit, err := keeper.GetDeposit(ctx, proposalID, depositorAddr) + switch { + case err == nil: + // deposit exists deposit.Amount = sdk.NewCoins(deposit.Amount...).Add(depositAmount...) - } else { + case errors.IsOf(err, types.ErrDepositNotFound): + // deposit doesn't exist deposit = v1.NewDeposit(proposalID, depositorAddr, depositAmount) + default: + // failed to get deposit + return false, err } // called when deposit has been added to a proposal, however the proposal may not be active keeper.Hooks().AfterProposalDeposit(ctx, proposalID, depositorAddr) - ctx.EventManager().EmitEvent( + sdkCtx := sdk.UnwrapSDKContext(ctx) + sdkCtx.EventManager().EmitEvent( sdk.NewEvent( types.EventTypeProposalDeposit, sdk.NewAttribute(sdk.AttributeKeyAmount, depositAmount.String()), @@ -168,7 +221,10 @@ func (keeper Keeper) AddDeposit(ctx sdk.Context, proposalID uint64, depositorAdd ), ) - keeper.SetDeposit(ctx, deposit) + err = keeper.SetDeposit(ctx, deposit) + if err != nil { + return false, err + } return activatedVotingPeriod, nil } @@ -176,12 +232,17 @@ func (keeper Keeper) AddDeposit(ctx sdk.Context, proposalID uint64, depositorAdd // ChargeDeposit will charge proposal cancellation fee (deposits * proposal_cancel_burn_rate) and // send to a destAddress if defined or burn otherwise. // Remaining funds are send back to the depositor. -func (keeper Keeper) ChargeDeposit(ctx sdk.Context, proposalID uint64, destAddress, proposalCancelRate string) error { - store := ctx.KVStore(keeper.storeKey) +func (keeper Keeper) ChargeDeposit(ctx context.Context, proposalID uint64, destAddress, proposalCancelRate string) error { + store := keeper.storeService.OpenKVStore(ctx) rate := sdkmath.LegacyMustNewDecFromStr(proposalCancelRate) var cancellationCharges sdk.Coins - for _, deposit := range keeper.GetDeposits(ctx, proposalID) { + deposits, err := keeper.GetDeposits(ctx, proposalID) + if err != nil { + return err + } + + for _, deposit := range deposits { depositerAddress, err := keeper.authKeeper.StringToBytes(deposit.Depositor) if err != nil { return err @@ -215,7 +276,10 @@ func (keeper Keeper) ChargeDeposit(ctx sdk.Context, proposalID uint64, destAddre } } - store.Delete(types.DepositKey(deposit.ProposalId, depositerAddress)) + err = store.Delete(types.DepositKey(deposit.ProposalId, depositerAddress)) + if err != nil { + return err + } } // burn the cancellation fee or sent the cancellation charges to destination address. @@ -230,7 +294,7 @@ func (keeper Keeper) ChargeDeposit(ctx sdk.Context, proposalID uint64, destAddre return err } case distributionAddress.String() == destAddress: - err := keeper.distrkeeper.FundCommunityPool(ctx, cancellationCharges, keeper.ModuleAccountAddress()) + err := keeper.distrKeeper.FundCommunityPool(ctx, cancellationCharges, keeper.ModuleAccountAddress()) if err != nil { return err } @@ -252,30 +316,39 @@ func (keeper Keeper) ChargeDeposit(ctx sdk.Context, proposalID uint64, destAddre } // RefundAndDeleteDeposits refunds and deletes all the deposits on a specific proposal. -func (keeper Keeper) RefundAndDeleteDeposits(ctx sdk.Context, proposalID uint64) { - store := ctx.KVStore(keeper.storeKey) +func (keeper Keeper) RefundAndDeleteDeposits(ctx context.Context, proposalID uint64) error { + store := keeper.storeService.OpenKVStore(ctx) - keeper.IterateDeposits(ctx, proposalID, func(deposit v1.Deposit) bool { + err := keeper.IterateDeposits(ctx, proposalID, func(deposit v1.Deposit) error { depositor, err := keeper.authKeeper.StringToBytes(deposit.Depositor) if err != nil { - panic(err) + return err } err = keeper.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, depositor, deposit.Amount) if err != nil { - panic(err) + return err } - store.Delete(types.DepositKey(proposalID, depositor)) - return false + err = store.Delete(types.DepositKey(proposalID, depositor)) + if err != nil { + return err + } + return nil }) + + return err } // validateInitialDeposit validates if initial deposit is greater than or equal to the minimum // required at the time of proposal submission. This threshold amount is determined by // the deposit parameters. Returns nil on success, error otherwise. -func (keeper Keeper) validateInitialDeposit(ctx sdk.Context, initialDeposit sdk.Coins, expedited bool) error { - params := keeper.GetParams(ctx) +func (keeper Keeper) validateInitialDeposit(ctx context.Context, initialDeposit sdk.Coins, expedited bool) error { + params, err := keeper.GetParams(ctx) + if err != nil { + return err + } + minInitialDepositRatio, err := sdk.NewDecFromStr(params.MinInitialDepositRatio) if err != nil { return err diff --git a/x/gov/keeper/deposit_test.go b/x/gov/keeper/deposit_test.go index d0fec3191214..3b9ce3cf5890 100644 --- a/x/gov/keeper/deposit_test.go +++ b/x/gov/keeper/deposit_test.go @@ -12,6 +12,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" disttypes "github.com/cosmos/cosmos-sdk/x/distribution/types" + "github.com/cosmos/cosmos-sdk/x/gov/types" v1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" ) @@ -67,22 +68,22 @@ func TestDeposits(t *testing.T) { require.True(t, sdk.NewCoins(proposal.TotalDeposit...).Equal(sdk.NewCoins())) // Check no deposits at beginning - _, found := govKeeper.GetDeposit(ctx, proposalID, TestAddrs[1]) - require.False(t, found) - proposal, ok := govKeeper.GetProposal(ctx, proposalID) - require.True(t, ok) + _, err = govKeeper.GetDeposit(ctx, proposalID, TestAddrs[1]) + require.ErrorIs(t, err, types.ErrDepositNotFound) + proposal, err = govKeeper.GetProposal(ctx, proposalID) + require.Nil(t, err) require.Nil(t, proposal.VotingStartTime) // Check first deposit votingStarted, err := govKeeper.AddDeposit(ctx, proposalID, TestAddrs[0], fourStake) require.NoError(t, err) require.False(t, votingStarted) - deposit, found := govKeeper.GetDeposit(ctx, proposalID, TestAddrs[0]) - require.True(t, found) + deposit, err := govKeeper.GetDeposit(ctx, proposalID, TestAddrs[0]) + require.Nil(t, err) require.Equal(t, fourStake, sdk.NewCoins(deposit.Amount...)) require.Equal(t, TestAddrs[0].String(), deposit.Depositor) - proposal, ok = govKeeper.GetProposal(ctx, proposalID) - require.True(t, ok) + proposal, err = govKeeper.GetProposal(ctx, proposalID) + require.Nil(t, err) require.Equal(t, fourStake, sdk.NewCoins(proposal.TotalDeposit...)) require.Equal(t, addr0Initial.Sub(fourStake...), bankKeeper.GetAllBalances(ctx, TestAddrs[0])) @@ -90,12 +91,12 @@ func TestDeposits(t *testing.T) { votingStarted, err = govKeeper.AddDeposit(ctx, proposalID, TestAddrs[0], fiveStake) require.NoError(t, err) require.False(t, votingStarted) - deposit, found = govKeeper.GetDeposit(ctx, proposalID, TestAddrs[0]) - require.True(t, found) + deposit, err = govKeeper.GetDeposit(ctx, proposalID, TestAddrs[0]) + require.Nil(t, err) require.Equal(t, fourStake.Add(fiveStake...), sdk.NewCoins(deposit.Amount...)) require.Equal(t, TestAddrs[0].String(), deposit.Depositor) - proposal, ok = govKeeper.GetProposal(ctx, proposalID) - require.True(t, ok) + proposal, err = govKeeper.GetProposal(ctx, proposalID) + require.Nil(t, err) require.Equal(t, fourStake.Add(fiveStake...), sdk.NewCoins(proposal.TotalDeposit...)) require.Equal(t, addr0Initial.Sub(fourStake...).Sub(fiveStake...), bankKeeper.GetAllBalances(ctx, TestAddrs[0])) @@ -103,37 +104,38 @@ func TestDeposits(t *testing.T) { votingStarted, err = govKeeper.AddDeposit(ctx, proposalID, TestAddrs[1], fourStake) require.NoError(t, err) require.True(t, votingStarted) - deposit, found = govKeeper.GetDeposit(ctx, proposalID, TestAddrs[1]) - require.True(t, found) + deposit, err = govKeeper.GetDeposit(ctx, proposalID, TestAddrs[1]) + require.Nil(t, err) require.Equal(t, TestAddrs[1].String(), deposit.Depositor) require.Equal(t, fourStake, sdk.NewCoins(deposit.Amount...)) - proposal, ok = govKeeper.GetProposal(ctx, proposalID) - require.True(t, ok) + proposal, err = govKeeper.GetProposal(ctx, proposalID) + require.Nil(t, err) require.Equal(t, fourStake.Add(fiveStake...).Add(fourStake...), sdk.NewCoins(proposal.TotalDeposit...)) require.Equal(t, addr1Initial.Sub(fourStake...), bankKeeper.GetAllBalances(ctx, TestAddrs[1])) // Check that proposal moved to voting period - proposal, ok = govKeeper.GetProposal(ctx, proposalID) - require.True(t, ok) + proposal, err = govKeeper.GetProposal(ctx, proposalID) + require.Nil(t, err) require.True(t, proposal.VotingStartTime.Equal(ctx.BlockHeader().Time)) // Test deposit iterator // NOTE order of deposits is determined by the addresses - deposits := govKeeper.GetAllDeposits(ctx) + deposits, _ := govKeeper.GetAllDeposits(ctx) require.Len(t, deposits, 2) - require.Equal(t, deposits, govKeeper.GetDeposits(ctx, proposalID)) + propDeposits, _ := govKeeper.GetDeposits(ctx, proposalID) + require.Equal(t, deposits, propDeposits) require.Equal(t, TestAddrs[0].String(), deposits[0].Depositor) require.Equal(t, fourStake.Add(fiveStake...), sdk.NewCoins(deposits[0].Amount...)) require.Equal(t, TestAddrs[1].String(), deposits[1].Depositor) require.Equal(t, fourStake, sdk.NewCoins(deposits[1].Amount...)) // Test Refund Deposits - deposit, found = govKeeper.GetDeposit(ctx, proposalID, TestAddrs[1]) - require.True(t, found) + deposit, err = govKeeper.GetDeposit(ctx, proposalID, TestAddrs[1]) + require.Nil(t, err) require.Equal(t, fourStake, sdk.NewCoins(deposit.Amount...)) govKeeper.RefundAndDeleteDeposits(ctx, proposalID) - deposit, found = govKeeper.GetDeposit(ctx, proposalID, TestAddrs[1]) - require.False(t, found) + deposit, err = govKeeper.GetDeposit(ctx, proposalID, TestAddrs[1]) + require.ErrorIs(t, err, types.ErrDepositNotFound) require.Equal(t, addr0Initial, bankKeeper.GetAllBalances(ctx, TestAddrs[0])) require.Equal(t, addr1Initial, bankKeeper.GetAllBalances(ctx, TestAddrs[1])) @@ -144,7 +146,7 @@ func TestDeposits(t *testing.T) { _, err = govKeeper.AddDeposit(ctx, proposalID, TestAddrs[0], fourStake) require.NoError(t, err) govKeeper.DeleteAndBurnDeposits(ctx, proposalID) - deposits = govKeeper.GetDeposits(ctx, proposalID) + deposits, _ = govKeeper.GetDeposits(ctx, proposalID) require.Len(t, deposits, 0) require.Equal(t, addr0Initial.Sub(fourStake...), bankKeeper.GetAllBalances(ctx, TestAddrs[0])) }) @@ -345,7 +347,7 @@ func TestChargeDeposit(t *testing.T) { } // get the deposits - allDeposits := govKeeper.GetDeposits(ctx, proposalID) + allDeposits, _ := govKeeper.GetDeposits(ctx, proposalID) // charge cancellation charges for cancel proposal err = govKeeper.ChargeDeposit(ctx, proposalID, TestAddrs[0].String(), params.ProposalCancelRatio) diff --git a/x/gov/keeper/grpc_query.go b/x/gov/keeper/grpc_query.go index 54733e649dca..7ffa76de63a0 100644 --- a/x/gov/keeper/grpc_query.go +++ b/x/gov/keeper/grpc_query.go @@ -6,9 +6,11 @@ import ( "google.golang.org/grpc/codes" "google.golang.org/grpc/status" + "cosmossdk.io/errors" sdkmath "cosmossdk.io/math" "cosmossdk.io/store/prefix" + "github.com/cosmos/cosmos-sdk/runtime" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/query" v3 "github.com/cosmos/cosmos-sdk/x/gov/migrations/v3" @@ -19,15 +21,16 @@ import ( var _ v1.QueryServer = Keeper{} -func (q Keeper) Constitution(c context.Context, req *v1.QueryConstitutionRequest) (*v1.QueryConstitutionResponse, error) { - ctx := sdk.UnwrapSDKContext(c) - constitution := q.GetConstitution(ctx) - +func (q Keeper) Constitution(ctx context.Context, req *v1.QueryConstitutionRequest) (*v1.QueryConstitutionResponse, error) { + constitution, err := q.GetConstitution(ctx) + if err != nil { + return nil, err + } return &v1.QueryConstitutionResponse{Constitution: constitution}, nil } // Proposal returns proposal details based on ProposalID -func (q Keeper) Proposal(c context.Context, req *v1.QueryProposalRequest) (*v1.QueryProposalResponse, error) { +func (q Keeper) Proposal(ctx context.Context, req *v1.QueryProposalRequest) (*v1.QueryProposalResponse, error) { if req == nil { return nil, status.Error(codes.InvalidArgument, "invalid request") } @@ -36,22 +39,21 @@ func (q Keeper) Proposal(c context.Context, req *v1.QueryProposalRequest) (*v1.Q return nil, status.Error(codes.InvalidArgument, "proposal id can not be 0") } - ctx := sdk.UnwrapSDKContext(c) - - proposal, found := q.GetProposal(ctx, req.ProposalId) - if !found { - return nil, status.Errorf(codes.NotFound, "proposal %d doesn't exist", req.ProposalId) + proposal, err := q.GetProposal(ctx, req.ProposalId) + if err != nil { + if errors.IsOf(err, types.ErrProposalNotFound) { + return nil, status.Errorf(codes.NotFound, "proposal %d doesn't exist", req.ProposalId) + } + return nil, status.Error(codes.Internal, err.Error()) } return &v1.QueryProposalResponse{Proposal: &proposal}, nil } // Proposals implements the Query/Proposals gRPC method -func (q Keeper) Proposals(c context.Context, req *v1.QueryProposalsRequest) (*v1.QueryProposalsResponse, error) { - ctx := sdk.UnwrapSDKContext(c) - - store := ctx.KVStore(q.storeKey) - proposalStore := prefix.NewStore(store, types.ProposalsKeyPrefix) +func (q Keeper) Proposals(ctx context.Context, req *v1.QueryProposalsRequest) (*v1.QueryProposalsResponse, error) { + store := q.storeService.OpenKVStore(ctx) + proposalStore := prefix.NewStore(runtime.KVStoreAdapter(store), types.ProposalsKeyPrefix) filteredProposals, pageRes, err := query.GenericFilteredPaginate( q.cdc, @@ -72,7 +74,9 @@ func (q Keeper) Proposals(c context.Context, req *v1.QueryProposalsRequest) (*v1 return nil, err } - _, matchVoter = q.GetVote(ctx, p.Id, voter) + _, err = q.GetVote(ctx, p.Id, voter) + // if no error, vote found, matchVoter = true + matchVoter = err == nil } // match depositor (if supplied) @@ -81,7 +85,9 @@ func (q Keeper) Proposals(c context.Context, req *v1.QueryProposalsRequest) (*v1 if err != nil { return nil, err } - _, matchDepositor = q.GetDeposit(ctx, p.Id, depositor) + _, err = q.GetDeposit(ctx, p.Id, depositor) + // if no error, deposit found, matchDepositor = true + matchDepositor = err == nil } if matchVoter && matchDepositor && matchStatus { @@ -100,7 +106,7 @@ func (q Keeper) Proposals(c context.Context, req *v1.QueryProposalsRequest) (*v1 } // Vote returns Voted information based on proposalID, voterAddr -func (q Keeper) Vote(c context.Context, req *v1.QueryVoteRequest) (*v1.QueryVoteResponse, error) { +func (q Keeper) Vote(ctx context.Context, req *v1.QueryVoteRequest) (*v1.QueryVoteResponse, error) { if req == nil { return nil, status.Error(codes.InvalidArgument, "invalid request") } @@ -113,23 +119,24 @@ func (q Keeper) Vote(c context.Context, req *v1.QueryVoteRequest) (*v1.QueryVote return nil, status.Error(codes.InvalidArgument, "empty voter address") } - ctx := sdk.UnwrapSDKContext(c) - voter, err := q.authKeeper.StringToBytes(req.Voter) if err != nil { return nil, err } - vote, found := q.GetVote(ctx, req.ProposalId, voter) - if !found { - return nil, status.Errorf(codes.InvalidArgument, - "voter: %v not found for proposal: %v", req.Voter, req.ProposalId) + vote, err := q.GetVote(ctx, req.ProposalId, voter) + if err != nil { + if errors.IsOf(err, types.ErrVoteNotFound) { + return nil, status.Errorf(codes.InvalidArgument, + "voter: %v not found for proposal: %v", req.Voter, req.ProposalId) + } + return nil, status.Error(codes.Internal, err.Error()) } return &v1.QueryVoteResponse{Vote: &vote}, nil } // Votes returns single proposal's votes -func (q Keeper) Votes(c context.Context, req *v1.QueryVotesRequest) (*v1.QueryVotesResponse, error) { +func (q Keeper) Votes(ctx context.Context, req *v1.QueryVotesRequest) (*v1.QueryVotesResponse, error) { if req == nil { return nil, status.Error(codes.InvalidArgument, "invalid request") } @@ -139,10 +146,8 @@ func (q Keeper) Votes(c context.Context, req *v1.QueryVotesRequest) (*v1.QueryVo } var votes v1.Votes - ctx := sdk.UnwrapSDKContext(c) - - store := ctx.KVStore(q.storeKey) - votesStore := prefix.NewStore(store, types.VotesKey(req.ProposalId)) + store := q.storeService.OpenKVStore(ctx) + votesStore := prefix.NewStore(runtime.KVStoreAdapter(store), types.VotesKey(req.ProposalId)) pageRes, err := query.Paginate(votesStore, req.Pagination, func(key, value []byte) error { var vote v1.Vote @@ -161,14 +166,15 @@ func (q Keeper) Votes(c context.Context, req *v1.QueryVotesRequest) (*v1.QueryVo } // Params queries all params -func (q Keeper) Params(c context.Context, req *v1.QueryParamsRequest) (*v1.QueryParamsResponse, error) { +func (q Keeper) Params(ctx context.Context, req *v1.QueryParamsRequest) (*v1.QueryParamsResponse, error) { if req == nil { return nil, status.Error(codes.InvalidArgument, "invalid request") } - ctx := sdk.UnwrapSDKContext(c) - params := q.GetParams(ctx) - + params, err := q.GetParams(ctx) + if err != nil { + return nil, err + } response := &v1.QueryParamsResponse{} //nolint:staticcheck // needed for legacy parameters @@ -196,7 +202,7 @@ func (q Keeper) Params(c context.Context, req *v1.QueryParamsRequest) (*v1.Query } // Deposit queries single deposit information based on proposalID, depositAddr. -func (q Keeper) Deposit(c context.Context, req *v1.QueryDepositRequest) (*v1.QueryDepositResponse, error) { +func (q Keeper) Deposit(ctx context.Context, req *v1.QueryDepositRequest) (*v1.QueryDepositResponse, error) { if req == nil { return nil, status.Error(codes.InvalidArgument, "invalid request") } @@ -209,23 +215,24 @@ func (q Keeper) Deposit(c context.Context, req *v1.QueryDepositRequest) (*v1.Que return nil, status.Error(codes.InvalidArgument, "empty depositor address") } - ctx := sdk.UnwrapSDKContext(c) - depositor, err := q.authKeeper.StringToBytes(req.Depositor) if err != nil { return nil, err } - deposit, found := q.GetDeposit(ctx, req.ProposalId, depositor) - if !found { - return nil, status.Errorf(codes.InvalidArgument, - "depositer: %v not found for proposal: %v", req.Depositor, req.ProposalId) + deposit, err := q.GetDeposit(ctx, req.ProposalId, depositor) + if err != nil { + if errors.IsOf(err, types.ErrDepositNotFound) { + return nil, status.Errorf(codes.InvalidArgument, + "depositer: %v not found for proposal: %v", req.Depositor, req.ProposalId) + } + return nil, status.Error(codes.Internal, err.Error()) } return &v1.QueryDepositResponse{Deposit: &deposit}, nil } // Deposits returns single proposal's all deposits -func (q Keeper) Deposits(c context.Context, req *v1.QueryDepositsRequest) (*v1.QueryDepositsResponse, error) { +func (q Keeper) Deposits(ctx context.Context, req *v1.QueryDepositsRequest) (*v1.QueryDepositsResponse, error) { if req == nil { return nil, status.Error(codes.InvalidArgument, "invalid request") } @@ -235,10 +242,9 @@ func (q Keeper) Deposits(c context.Context, req *v1.QueryDepositsRequest) (*v1.Q } var deposits []*v1.Deposit - ctx := sdk.UnwrapSDKContext(c) - store := ctx.KVStore(q.storeKey) - depositStore := prefix.NewStore(store, types.DepositsKey(req.ProposalId)) + store := q.storeService.OpenKVStore(ctx) + depositStore := prefix.NewStore(runtime.KVStoreAdapter(store), types.DepositsKey(req.ProposalId)) pageRes, err := query.Paginate(depositStore, req.Pagination, func(key, value []byte) error { var deposit v1.Deposit @@ -257,7 +263,7 @@ func (q Keeper) Deposits(c context.Context, req *v1.QueryDepositsRequest) (*v1.Q } // TallyResult queries the tally of a proposal vote -func (q Keeper) TallyResult(c context.Context, req *v1.QueryTallyResultRequest) (*v1.QueryTallyResultResponse, error) { +func (q Keeper) TallyResult(ctx context.Context, req *v1.QueryTallyResultRequest) (*v1.QueryTallyResultResponse, error) { if req == nil { return nil, status.Error(codes.InvalidArgument, "invalid request") } @@ -266,11 +272,12 @@ func (q Keeper) TallyResult(c context.Context, req *v1.QueryTallyResultRequest) return nil, status.Error(codes.InvalidArgument, "proposal id can not be 0") } - ctx := sdk.UnwrapSDKContext(c) - - proposal, ok := q.GetProposal(ctx, req.ProposalId) - if !ok { - return nil, status.Errorf(codes.NotFound, "proposal %d doesn't exist", req.ProposalId) + proposal, err := q.GetProposal(ctx, req.ProposalId) + if err != nil { + if errors.IsOf(err, types.ErrProposalNotFound) { + return nil, status.Errorf(codes.NotFound, "proposal %d doesn't exist", req.ProposalId) + } + return nil, status.Error(codes.Internal, err.Error()) } var tallyResult v1.TallyResult @@ -284,7 +291,11 @@ func (q Keeper) TallyResult(c context.Context, req *v1.QueryTallyResultRequest) default: // proposal is in voting period - _, _, tallyResult = q.Tally(ctx, proposal) + var err error + _, _, tallyResult, err = q.Tally(ctx, proposal) + if err != nil { + return nil, err + } } return &v1.QueryTallyResultResponse{Tally: &tallyResult}, nil @@ -301,8 +312,8 @@ func NewLegacyQueryServer(k *Keeper) v1beta1.QueryServer { return &legacyQueryServer{keeper: k} } -func (q legacyQueryServer) Proposal(c context.Context, req *v1beta1.QueryProposalRequest) (*v1beta1.QueryProposalResponse, error) { - resp, err := q.keeper.Proposal(c, &v1.QueryProposalRequest{ +func (q legacyQueryServer) Proposal(ctx context.Context, req *v1beta1.QueryProposalRequest) (*v1beta1.QueryProposalResponse, error) { + resp, err := q.keeper.Proposal(ctx, &v1.QueryProposalRequest{ ProposalId: req.ProposalId, }) if err != nil { @@ -317,8 +328,8 @@ func (q legacyQueryServer) Proposal(c context.Context, req *v1beta1.QueryProposa return &v1beta1.QueryProposalResponse{Proposal: proposal}, nil } -func (q legacyQueryServer) Proposals(c context.Context, req *v1beta1.QueryProposalsRequest) (*v1beta1.QueryProposalsResponse, error) { - resp, err := q.keeper.Proposals(c, &v1.QueryProposalsRequest{ +func (q legacyQueryServer) Proposals(ctx context.Context, req *v1beta1.QueryProposalsRequest) (*v1beta1.QueryProposalsResponse, error) { + resp, err := q.keeper.Proposals(ctx, &v1.QueryProposalsRequest{ ProposalStatus: v1.ProposalStatus(req.ProposalStatus), Voter: req.Voter, Depositor: req.Depositor, @@ -342,8 +353,8 @@ func (q legacyQueryServer) Proposals(c context.Context, req *v1beta1.QueryPropos }, nil } -func (q legacyQueryServer) Vote(c context.Context, req *v1beta1.QueryVoteRequest) (*v1beta1.QueryVoteResponse, error) { - resp, err := q.keeper.Vote(c, &v1.QueryVoteRequest{ +func (q legacyQueryServer) Vote(ctx context.Context, req *v1beta1.QueryVoteRequest) (*v1beta1.QueryVoteResponse, error) { + resp, err := q.keeper.Vote(ctx, &v1.QueryVoteRequest{ ProposalId: req.ProposalId, Voter: req.Voter, }) @@ -359,8 +370,8 @@ func (q legacyQueryServer) Vote(c context.Context, req *v1beta1.QueryVoteRequest return &v1beta1.QueryVoteResponse{Vote: vote}, nil } -func (q legacyQueryServer) Votes(c context.Context, req *v1beta1.QueryVotesRequest) (*v1beta1.QueryVotesResponse, error) { - resp, err := q.keeper.Votes(c, &v1.QueryVotesRequest{ +func (q legacyQueryServer) Votes(ctx context.Context, req *v1beta1.QueryVotesRequest) (*v1beta1.QueryVotesResponse, error) { + resp, err := q.keeper.Votes(ctx, &v1.QueryVotesRequest{ ProposalId: req.ProposalId, Pagination: req.Pagination, }) @@ -383,8 +394,8 @@ func (q legacyQueryServer) Votes(c context.Context, req *v1beta1.QueryVotesReque } //nolint:staticcheck // this is needed for legacy param support -func (q legacyQueryServer) Params(c context.Context, req *v1beta1.QueryParamsRequest) (*v1beta1.QueryParamsResponse, error) { - resp, err := q.keeper.Params(c, &v1.QueryParamsRequest{ +func (q legacyQueryServer) Params(ctx context.Context, req *v1beta1.QueryParamsRequest) (*v1beta1.QueryParamsResponse, error) { + resp, err := q.keeper.Params(ctx, &v1.QueryParamsRequest{ ParamsType: req.ParamsType, }) if err != nil { @@ -422,8 +433,8 @@ func (q legacyQueryServer) Params(c context.Context, req *v1beta1.QueryParamsReq return response, nil } -func (q legacyQueryServer) Deposit(c context.Context, req *v1beta1.QueryDepositRequest) (*v1beta1.QueryDepositResponse, error) { - resp, err := q.keeper.Deposit(c, &v1.QueryDepositRequest{ +func (q legacyQueryServer) Deposit(ctx context.Context, req *v1beta1.QueryDepositRequest) (*v1beta1.QueryDepositResponse, error) { + resp, err := q.keeper.Deposit(ctx, &v1.QueryDepositRequest{ ProposalId: req.ProposalId, Depositor: req.Depositor, }) @@ -435,8 +446,8 @@ func (q legacyQueryServer) Deposit(c context.Context, req *v1beta1.QueryDepositR return &v1beta1.QueryDepositResponse{Deposit: deposit}, nil } -func (q legacyQueryServer) Deposits(c context.Context, req *v1beta1.QueryDepositsRequest) (*v1beta1.QueryDepositsResponse, error) { - resp, err := q.keeper.Deposits(c, &v1.QueryDepositsRequest{ +func (q legacyQueryServer) Deposits(ctx context.Context, req *v1beta1.QueryDepositsRequest) (*v1beta1.QueryDepositsResponse, error) { + resp, err := q.keeper.Deposits(ctx, &v1.QueryDepositsRequest{ ProposalId: req.ProposalId, Pagination: req.Pagination, }) @@ -451,8 +462,8 @@ func (q legacyQueryServer) Deposits(c context.Context, req *v1beta1.QueryDeposit return &v1beta1.QueryDepositsResponse{Deposits: deposits, Pagination: resp.Pagination}, nil } -func (q legacyQueryServer) TallyResult(c context.Context, req *v1beta1.QueryTallyResultRequest) (*v1beta1.QueryTallyResultResponse, error) { - resp, err := q.keeper.TallyResult(c, &v1.QueryTallyResultRequest{ +func (q legacyQueryServer) TallyResult(ctx context.Context, req *v1beta1.QueryTallyResultRequest) (*v1beta1.QueryTallyResultResponse, error) { + resp, err := q.keeper.TallyResult(ctx, &v1.QueryTallyResultRequest{ ProposalId: req.ProposalId, }) if err != nil { diff --git a/x/gov/keeper/hooks_test.go b/x/gov/keeper/hooks_test.go index 430f6487bc20..64290f5db3e6 100644 --- a/x/gov/keeper/hooks_test.go +++ b/x/gov/keeper/hooks_test.go @@ -1,6 +1,7 @@ package keeper_test import ( + "context" "testing" "time" @@ -25,23 +26,23 @@ type MockGovHooksReceiver struct { AfterProposalVotingPeriodEndedValid bool } -func (h *MockGovHooksReceiver) AfterProposalSubmission(ctx sdk.Context, proposalID uint64) { +func (h *MockGovHooksReceiver) AfterProposalSubmission(ctx context.Context, proposalID uint64) { h.AfterProposalSubmissionValid = true } -func (h *MockGovHooksReceiver) AfterProposalDeposit(ctx sdk.Context, proposalID uint64, depositorAddr sdk.AccAddress) { +func (h *MockGovHooksReceiver) AfterProposalDeposit(ctx context.Context, proposalID uint64, depositorAddr sdk.AccAddress) { h.AfterProposalDepositValid = true } -func (h *MockGovHooksReceiver) AfterProposalVote(ctx sdk.Context, proposalID uint64, voterAddr sdk.AccAddress) { +func (h *MockGovHooksReceiver) AfterProposalVote(ctx context.Context, proposalID uint64, voterAddr sdk.AccAddress) { h.AfterProposalVoteValid = true } -func (h *MockGovHooksReceiver) AfterProposalFailedMinDeposit(ctx sdk.Context, proposalID uint64) { +func (h *MockGovHooksReceiver) AfterProposalFailedMinDeposit(ctx context.Context, proposalID uint64) { h.AfterProposalFailedMinDepositValid = true } -func (h *MockGovHooksReceiver) AfterProposalVotingPeriodEnded(ctx sdk.Context, proposalID uint64) { +func (h *MockGovHooksReceiver) AfterProposalVotingPeriodEnded(ctx context.Context, proposalID uint64) { h.AfterProposalVotingPeriodEndedValid = true } @@ -72,8 +73,9 @@ func TestHooks(t *testing.T) { require.NoError(t, err) require.True(t, govHooksReceiver.AfterProposalSubmissionValid) + params, _ := govKeeper.GetParams(ctx) newHeader := ctx.BlockHeader() - newHeader.Time = ctx.BlockHeader().Time.Add(*govKeeper.GetParams(ctx).MaxDepositPeriod).Add(time.Duration(1) * time.Second) + newHeader.Time = ctx.BlockHeader().Time.Add(*params.MaxDepositPeriod).Add(time.Duration(1) * time.Second) ctx = ctx.WithBlockHeader(newHeader) gov.EndBlocker(ctx, govKeeper) @@ -92,7 +94,7 @@ func TestHooks(t *testing.T) { require.True(t, govHooksReceiver.AfterProposalVoteValid) newHeader = ctx.BlockHeader() - newHeader.Time = ctx.BlockHeader().Time.Add(*govKeeper.GetParams(ctx).VotingPeriod).Add(time.Duration(1) * time.Second) + newHeader.Time = ctx.BlockHeader().Time.Add(*params.VotingPeriod).Add(time.Duration(1) * time.Second) ctx = ctx.WithBlockHeader(newHeader) gov.EndBlocker(ctx, govKeeper) require.True(t, govHooksReceiver.AfterProposalVotingPeriodEndedValid) diff --git a/x/gov/keeper/invariants.go b/x/gov/keeper/invariants.go index c873b4312e7a..540a100e474c 100644 --- a/x/gov/keeper/invariants.go +++ b/x/gov/keeper/invariants.go @@ -26,9 +26,9 @@ func ModuleAccountInvariant(keeper *Keeper, bk types.BankKeeper) sdk.Invariant { return func(ctx sdk.Context) (string, bool) { var expectedDeposits sdk.Coins - keeper.IterateAllDeposits(ctx, func(deposit v1.Deposit) bool { + keeper.IterateAllDeposits(ctx, func(deposit v1.Deposit) error { expectedDeposits = expectedDeposits.Add(deposit.Amount...) - return false + return nil }) macc := keeper.GetGovernanceAccount(ctx) diff --git a/x/gov/keeper/keeper.go b/x/gov/keeper/keeper.go index c1ccf6f049dc..26c018ee7e45 100644 --- a/x/gov/keeper/keeper.go +++ b/x/gov/keeper/keeper.go @@ -1,9 +1,12 @@ package keeper import ( + "context" "fmt" "time" + corestoretypes "cosmossdk.io/core/store" + "cosmossdk.io/errors" "cosmossdk.io/log" storetypes "cosmossdk.io/store/types" @@ -19,7 +22,7 @@ import ( type Keeper struct { authKeeper types.AccountKeeper bankKeeper types.BankKeeper - distrkeeper types.DistributionKeeper + distrKeeper types.DistributionKeeper // The reference to the DelegationSet and ValidatorSet to get information about validators and delegators sk types.StakingKeeper @@ -28,7 +31,7 @@ type Keeper struct { hooks types.GovHooks // The (unexposed) keys used to access the stores from the Context. - storeKey storetypes.StoreKey + storeService corestoretypes.KVStoreService // The codec for binary encoding/decoding. cdc codec.BinaryCodec @@ -59,8 +62,8 @@ func (k Keeper) GetAuthority() string { // // CONTRACT: the parameter Subspace must have the param key table already initialized func NewKeeper( - cdc codec.BinaryCodec, key storetypes.StoreKey, authKeeper types.AccountKeeper, - bankKeeper types.BankKeeper, sk types.StakingKeeper, distrkeeper types.DistributionKeeper, + cdc codec.BinaryCodec, storeService corestoretypes.KVStoreService, authKeeper types.AccountKeeper, + bankKeeper types.BankKeeper, sk types.StakingKeeper, distrKeeper types.DistributionKeeper, router baseapp.MessageRouter, config types.Config, authority string, ) *Keeper { // ensure governance module account is set @@ -78,15 +81,15 @@ func NewKeeper( } return &Keeper{ - storeKey: key, - authKeeper: authKeeper, - bankKeeper: bankKeeper, - distrkeeper: distrkeeper, - sk: sk, - cdc: cdc, - router: router, - config: config, - authority: authority, + storeService: storeService, + authKeeper: authKeeper, + bankKeeper: bankKeeper, + distrKeeper: distrKeeper, + sk: sk, + cdc: cdc, + router: router, + config: config, + authority: authority, } } @@ -121,8 +124,9 @@ func (k *Keeper) SetLegacyRouter(router v1beta1.Router) { } // Logger returns a module-specific logger. -func (k Keeper) Logger(ctx sdk.Context) log.Logger { - return ctx.Logger().With("module", "x/"+types.ModuleName) +func (k Keeper) Logger(ctx context.Context) log.Logger { + sdkCtx := sdk.UnwrapSDKContext(ctx) + return sdkCtx.Logger().With("module", "x/"+types.ModuleName) } // Router returns the gov keeper's router @@ -136,87 +140,105 @@ func (k Keeper) LegacyRouter() v1beta1.Router { } // GetGovernanceAccount returns the governance ModuleAccount -func (k Keeper) GetGovernanceAccount(ctx sdk.Context) sdk.ModuleAccountI { +func (k Keeper) GetGovernanceAccount(ctx context.Context) sdk.ModuleAccountI { return k.authKeeper.GetModuleAccount(ctx, types.ModuleName) } // ProposalQueues // InsertActiveProposalQueue inserts a proposalID into the active proposal queue at endTime -func (k Keeper) InsertActiveProposalQueue(ctx sdk.Context, proposalID uint64, endTime time.Time) { - store := ctx.KVStore(k.storeKey) +func (k Keeper) InsertActiveProposalQueue(ctx context.Context, proposalID uint64, endTime time.Time) error { + store := k.storeService.OpenKVStore(ctx) bz := types.GetProposalIDBytes(proposalID) - store.Set(types.ActiveProposalQueueKey(proposalID, endTime), bz) + return store.Set(types.ActiveProposalQueueKey(proposalID, endTime), bz) } // RemoveFromActiveProposalQueue removes a proposalID from the Active Proposal Queue -func (k Keeper) RemoveFromActiveProposalQueue(ctx sdk.Context, proposalID uint64, endTime time.Time) { - store := ctx.KVStore(k.storeKey) - store.Delete(types.ActiveProposalQueueKey(proposalID, endTime)) +func (k Keeper) RemoveFromActiveProposalQueue(ctx context.Context, proposalID uint64, endTime time.Time) error { + store := k.storeService.OpenKVStore(ctx) + return store.Delete(types.ActiveProposalQueueKey(proposalID, endTime)) } // InsertInactiveProposalQueue inserts a proposalID into the inactive proposal queue at endTime -func (k Keeper) InsertInactiveProposalQueue(ctx sdk.Context, proposalID uint64, endTime time.Time) { - store := ctx.KVStore(k.storeKey) +func (k Keeper) InsertInactiveProposalQueue(ctx context.Context, proposalID uint64, endTime time.Time) error { + store := k.storeService.OpenKVStore(ctx) bz := types.GetProposalIDBytes(proposalID) - store.Set(types.InactiveProposalQueueKey(proposalID, endTime), bz) + return store.Set(types.InactiveProposalQueueKey(proposalID, endTime), bz) } // RemoveFromInactiveProposalQueue removes a proposalID from the Inactive Proposal Queue -func (k Keeper) RemoveFromInactiveProposalQueue(ctx sdk.Context, proposalID uint64, endTime time.Time) { - store := ctx.KVStore(k.storeKey) - store.Delete(types.InactiveProposalQueueKey(proposalID, endTime)) +func (k Keeper) RemoveFromInactiveProposalQueue(ctx context.Context, proposalID uint64, endTime time.Time) error { + store := k.storeService.OpenKVStore(ctx) + return store.Delete(types.InactiveProposalQueueKey(proposalID, endTime)) } // Iterators // IterateActiveProposalsQueue iterates over the proposals in the active proposal queue // and performs a callback function -func (k Keeper) IterateActiveProposalsQueue(ctx sdk.Context, endTime time.Time, cb func(proposal v1.Proposal) (stop bool)) { - iterator := k.ActiveProposalQueueIterator(ctx, endTime) +func (k Keeper) IterateActiveProposalsQueue(ctx context.Context, endTime time.Time, cb func(proposal v1.Proposal) error) error { + iterator, err := k.ActiveProposalQueueIterator(ctx, endTime) + if err != nil { + return err + } defer iterator.Close() for ; iterator.Valid(); iterator.Next() { proposalID, _ := types.SplitActiveProposalQueueKey(iterator.Key()) - proposal, found := k.GetProposal(ctx, proposalID) - if !found { - panic(fmt.Sprintf("proposal %d does not exist", proposalID)) + proposal, err := k.GetProposal(ctx, proposalID) + if err != nil { + return err } - if cb(proposal) { - break + err = cb(proposal) + // exit early without error if cb returns ErrStopIterating + if errors.IsOf(err, errors.ErrStopIterating) { + return nil + } else if err != nil { + return err } } + + return nil } // IterateInactiveProposalsQueue iterates over the proposals in the inactive proposal queue // and performs a callback function -func (k Keeper) IterateInactiveProposalsQueue(ctx sdk.Context, endTime time.Time, cb func(proposal v1.Proposal) (stop bool)) { - iterator := k.InactiveProposalQueueIterator(ctx, endTime) +func (k Keeper) IterateInactiveProposalsQueue(ctx context.Context, endTime time.Time, cb func(proposal v1.Proposal) error) error { + iterator, err := k.InactiveProposalQueueIterator(ctx, endTime) + if err != nil { + return err + } defer iterator.Close() for ; iterator.Valid(); iterator.Next() { proposalID, _ := types.SplitInactiveProposalQueueKey(iterator.Key()) - proposal, found := k.GetProposal(ctx, proposalID) - if !found { - panic(fmt.Sprintf("proposal %d does not exist", proposalID)) + proposal, err := k.GetProposal(ctx, proposalID) + if err != nil { + return err } - if cb(proposal) { - break + err = cb(proposal) + // exit early without error if cb returns ErrStopIterating + if errors.IsOf(err, errors.ErrStopIterating) { + return nil + } else if err != nil { + return err } } + + return nil } -// ActiveProposalQueueIterator returns an storetypes.Iterator for all the proposals in the Active Queue that expire by endTime -func (k Keeper) ActiveProposalQueueIterator(ctx sdk.Context, endTime time.Time) storetypes.Iterator { - store := ctx.KVStore(k.storeKey) +// ActiveProposalQueueIterator returns an corestoretypes.Iterator for all the proposals in the Active Queue that expire by endTime +func (k Keeper) ActiveProposalQueueIterator(ctx context.Context, endTime time.Time) (corestoretypes.Iterator, error) { + store := k.storeService.OpenKVStore(ctx) return store.Iterator(types.ActiveProposalQueuePrefix, storetypes.PrefixEndBytes(types.ActiveProposalByTimeKey(endTime))) } -// InactiveProposalQueueIterator returns an storetypes.Iterator for all the proposals in the Inactive Queue that expire by endTime -func (k Keeper) InactiveProposalQueueIterator(ctx sdk.Context, endTime time.Time) storetypes.Iterator { - store := ctx.KVStore(k.storeKey) +// InactiveProposalQueueIterator returns an corestoretypes.Iterator for all the proposals in the Inactive Queue that expire by endTime +func (k Keeper) InactiveProposalQueueIterator(ctx context.Context, endTime time.Time) (corestoretypes.Iterator, error) { + store := k.storeService.OpenKVStore(ctx) return store.Iterator(types.InactiveProposalQueuePrefix, storetypes.PrefixEndBytes(types.InactiveProposalByTimeKey(endTime))) } diff --git a/x/gov/keeper/keeper_test.go b/x/gov/keeper/keeper_test.go index ab7ba18d64a8..384587fe933a 100644 --- a/x/gov/keeper/keeper_test.go +++ b/x/gov/keeper/keeper_test.go @@ -122,7 +122,7 @@ func TestProposalQueues(t *testing.T) { proposal, err := govKeeper.SubmitProposal(ctx, tp, "", "test", "summary", addrBz, false) require.NoError(t, err) - inactiveIterator := govKeeper.InactiveProposalQueueIterator(ctx, *proposal.DepositEndTime) + inactiveIterator, _ := govKeeper.InactiveProposalQueueIterator(ctx, *proposal.DepositEndTime) require.True(t, inactiveIterator.Valid()) proposalID := types.GetProposalIDFromBytes(inactiveIterator.Value()) @@ -131,10 +131,10 @@ func TestProposalQueues(t *testing.T) { govKeeper.ActivateVotingPeriod(ctx, proposal) - proposal, ok := govKeeper.GetProposal(ctx, proposal.Id) - require.True(t, ok) + proposal, err = govKeeper.GetProposal(ctx, proposal.Id) + require.Nil(t, err) - activeIterator := govKeeper.ActiveProposalQueueIterator(ctx, *proposal.VotingEndTime) + activeIterator, _ := govKeeper.ActiveProposalQueueIterator(ctx, *proposal.VotingEndTime) require.True(t, activeIterator.Valid()) proposalID, _ = types.SplitActiveProposalQueueKey(activeIterator.Key()) diff --git a/x/gov/keeper/migrations.go b/x/gov/keeper/migrations.go index ab66ac0dcdc2..0b60fa6ef687 100644 --- a/x/gov/keeper/migrations.go +++ b/x/gov/keeper/migrations.go @@ -25,20 +25,20 @@ func NewMigrator(keeper *Keeper, legacySubspace exported.ParamSubspace) Migrator // Migrate1to2 migrates from version 1 to 2. func (m Migrator) Migrate1to2(ctx sdk.Context) error { - return v2.MigrateStore(ctx, m.keeper.storeKey, m.keeper.cdc) + return v2.MigrateStore(ctx, m.keeper.storeService, m.keeper.cdc) } // Migrate2to3 migrates from version 2 to 3. func (m Migrator) Migrate2to3(ctx sdk.Context) error { - return v3.MigrateStore(ctx, m.keeper.storeKey, m.keeper.cdc) + return v3.MigrateStore(ctx, m.keeper.storeService, m.keeper.cdc) } // Migrate3to4 migrates from version 3 to 4. func (m Migrator) Migrate3to4(ctx sdk.Context) error { - return v4.MigrateStore(ctx, m.keeper.storeKey, m.legacySubspace, m.keeper.cdc) + return v4.MigrateStore(ctx, m.keeper.storeService, m.legacySubspace, m.keeper.cdc) } // Migrate3to4 migrates from version 4 to 5. func (m Migrator) Migrate4to5(ctx sdk.Context) error { - return v5.MigrateStore(ctx, m.keeper.storeKey, m.keeper.cdc) + return v5.MigrateStore(ctx, m.keeper.storeService, m.keeper.cdc) } diff --git a/x/gov/keeper/msg_server_test.go b/x/gov/keeper/msg_server_test.go index cc45f577ca02..3b8456d3b4cb 100644 --- a/x/gov/keeper/msg_server_test.go +++ b/x/gov/keeper/msg_server_test.go @@ -6,6 +6,7 @@ import ( "time" sdkmath "cosmossdk.io/math" + simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" "github.com/cosmos/cosmos-sdk/testutil/testdata" sdk "github.com/cosmos/cosmos-sdk/types" @@ -33,7 +34,8 @@ func (suite *KeeperTestSuite) TestSubmitProposalReq() { coins := sdk.NewCoins(sdk.NewCoin("stake", sdkmath.NewInt(100))) initialDeposit := coins - minDeposit := suite.govKeeper.GetParams(suite.ctx).MinDeposit + params, _ := suite.govKeeper.GetParams(suite.ctx) + minDeposit := params.MinDeposit bankMsg := &banktypes.MsgSend{ FromAddress: govAcct.String(), ToAddress: proposer.String(), @@ -317,7 +319,8 @@ func (suite *KeeperTestSuite) TestVoteReq() { proposer := addrs[0] coins := sdk.NewCoins(sdk.NewCoin("stake", sdkmath.NewInt(100))) - minDeposit := suite.govKeeper.GetParams(suite.ctx).MinDeposit + params, _ := suite.govKeeper.GetParams(suite.ctx) + minDeposit := params.MinDeposit bankMsg := &banktypes.MsgSend{ FromAddress: govAcct.String(), ToAddress: proposer.String(), @@ -462,7 +465,8 @@ func (suite *KeeperTestSuite) TestVoteWeightedReq() { proposer := simtestutil.AddTestAddrsIncremental(suite.bankKeeper, suite.stakingKeeper, suite.ctx, 1, sdkmath.NewInt(50000000))[0] coins := sdk.NewCoins(sdk.NewCoin("stake", sdkmath.NewInt(100))) - minDeposit := suite.govKeeper.GetParams(suite.ctx).MinDeposit + params, _ := suite.govKeeper.GetParams(suite.ctx) + minDeposit := params.MinDeposit bankMsg := &banktypes.MsgSend{ FromAddress: govAcct.String(), ToAddress: proposer.String(), @@ -707,7 +711,8 @@ func (suite *KeeperTestSuite) TestDepositReq() { proposer := addrs[0] coins := sdk.NewCoins(sdk.NewCoin("stake", sdkmath.NewInt(100))) - minDeposit := suite.govKeeper.GetParams(suite.ctx).MinDeposit + params, _ := suite.govKeeper.GetParams(suite.ctx) + minDeposit := params.MinDeposit bankMsg := &banktypes.MsgSend{ FromAddress: govAcct.String(), ToAddress: proposer.String(), @@ -788,7 +793,8 @@ func (suite *KeeperTestSuite) TestLegacyMsgSubmitProposal() { proposer := simtestutil.AddTestAddrsIncremental(suite.bankKeeper, suite.stakingKeeper, suite.ctx, 1, sdkmath.NewInt(50000000))[0] coins := sdk.NewCoins(sdk.NewCoin("stake", sdkmath.NewInt(100))) initialDeposit := coins - minDeposit := suite.govKeeper.GetParams(suite.ctx).MinDeposit + params, _ := suite.govKeeper.GetParams(suite.ctx) + minDeposit := params.MinDeposit suite.acctKeeper.EXPECT().StringToBytes("").Return(nil, errors.New(emptyAddressError)) @@ -901,7 +907,8 @@ func (suite *KeeperTestSuite) TestLegacyMsgVote() { proposer := addrs[0] coins := sdk.NewCoins(sdk.NewCoin("stake", sdkmath.NewInt(100))) - minDeposit := suite.govKeeper.GetParams(suite.ctx).MinDeposit + params, _ := suite.govKeeper.GetParams(suite.ctx) + minDeposit := params.MinDeposit bankMsg := &banktypes.MsgSend{ FromAddress: govAcct.String(), ToAddress: proposer.String(), @@ -1036,7 +1043,8 @@ func (suite *KeeperTestSuite) TestLegacyVoteWeighted() { proposer := addrs[0] coins := sdk.NewCoins(sdk.NewCoin("stake", sdkmath.NewInt(100))) - minDeposit := suite.govKeeper.GetParams(suite.ctx).MinDeposit + params, _ := suite.govKeeper.GetParams(suite.ctx) + minDeposit := params.MinDeposit bankMsg := &banktypes.MsgSend{ FromAddress: govAcct.String(), ToAddress: proposer.String(), @@ -1289,7 +1297,8 @@ func (suite *KeeperTestSuite) TestLegacyMsgDeposit() { proposer := addrs[0] coins := sdk.NewCoins(sdk.NewCoin("stake", sdkmath.NewInt(100))) - minDeposit := suite.govKeeper.GetParams(suite.ctx).MinDeposit + params, _ := suite.govKeeper.GetParams(suite.ctx) + minDeposit := params.MinDeposit bankMsg := &banktypes.MsgSend{ FromAddress: govAcct.String(), ToAddress: proposer.String(), diff --git a/x/gov/keeper/params.go b/x/gov/keeper/params.go index dc8e93212076..4e81c8ea58d3 100644 --- a/x/gov/keeper/params.go +++ b/x/gov/keeper/params.go @@ -1,32 +1,34 @@ package keeper import ( - sdk "github.com/cosmos/cosmos-sdk/types" + "context" + "github.com/cosmos/cosmos-sdk/x/gov/types" v1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" ) // SetParams sets the gov module's parameters. // CONTRACT: This method performs no validation of the parameters. -func (k Keeper) SetParams(ctx sdk.Context, params v1.Params) error { - store := ctx.KVStore(k.storeKey) +func (k Keeper) SetParams(ctx context.Context, params v1.Params) error { + store := k.storeService.OpenKVStore(ctx) bz, err := k.cdc.Marshal(¶ms) if err != nil { return err } - store.Set(types.ParamsKey, bz) - - return nil + return store.Set(types.ParamsKey, bz) } // GetParams gets the gov module's parameters. -func (k Keeper) GetParams(clientCtx sdk.Context) (params v1.Params) { - store := clientCtx.KVStore(k.storeKey) - bz := store.Get(types.ParamsKey) +func (k Keeper) GetParams(ctx context.Context) (params v1.Params, err error) { + store := k.storeService.OpenKVStore(ctx) + bz, err := store.Get(types.ParamsKey) + if err != nil { + return params, err + } if bz == nil { - return params + return params, nil } - k.cdc.MustUnmarshal(bz, ¶ms) - return params + err = k.cdc.Unmarshal(bz, ¶ms) + return params, err } diff --git a/x/gov/keeper/proposal.go b/x/gov/keeper/proposal.go index 3979a2047c64..c0163661e707 100644 --- a/x/gov/keeper/proposal.go +++ b/x/gov/keeper/proposal.go @@ -1,6 +1,7 @@ package keeper import ( + "context" "errors" "fmt" "time" @@ -9,13 +10,15 @@ import ( storetypes "cosmossdk.io/store/types" "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/runtime" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/gov/types" v1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" ) // SubmitProposal creates a new proposal given an array of messages -func (keeper Keeper) SubmitProposal(ctx sdk.Context, messages []sdk.Msg, metadata, title, summary string, proposer sdk.AccAddress, expedited bool) (v1.Proposal, error) { +func (keeper Keeper) SubmitProposal(ctx context.Context, messages []sdk.Msg, metadata, title, summary string, proposer sdk.AccAddress, expedited bool) (v1.Proposal, error) { + sdkCtx := sdk.UnwrapSDKContext(ctx) err := keeper.assertMetadataLength(metadata) if err != nil { return v1.Proposal{}, err @@ -70,7 +73,7 @@ func (keeper Keeper) SubmitProposal(ctx sdk.Context, messages []sdk.Msg, metadat // They may fail upon execution. // ref: https://github.com/cosmos/cosmos-sdk/pull/10868#discussion_r784872842 if msg, ok := msg.(*v1.MsgExecLegacyContent); ok { - cacheCtx, _ := ctx.CacheContext() + cacheCtx, _ := sdkCtx.CacheContext() if _, err := handler(cacheCtx, msg); err != nil { if errors.Is(types.ErrNoProposalHandlerExists, err) { return v1.Proposal{}, err @@ -86,8 +89,13 @@ func (keeper Keeper) SubmitProposal(ctx sdk.Context, messages []sdk.Msg, metadat return v1.Proposal{}, err } - submitTime := ctx.BlockHeader().Time - depositPeriod := keeper.GetParams(ctx).MaxDepositPeriod + params, err := keeper.GetParams(ctx) + if err != nil { + return v1.Proposal{}, err + } + + submitTime := sdkCtx.BlockHeader().Time + depositPeriod := params.MaxDepositPeriod proposal, err := v1.NewProposal(messages, proposalID, submitTime, submitTime.Add(*depositPeriod), metadata, title, summary, proposer, expedited) if err != nil { @@ -101,7 +109,7 @@ func (keeper Keeper) SubmitProposal(ctx sdk.Context, messages []sdk.Msg, metadat // called right after a proposal is submitted keeper.Hooks().AfterProposalSubmission(ctx, proposalID) - ctx.EventManager().EmitEvent( + sdkCtx.EventManager().EmitEvent( sdk.NewEvent( types.EventTypeSubmitProposal, sdk.NewAttribute(types.AttributeKeyProposalID, fmt.Sprintf("%d", proposalID)), @@ -113,10 +121,11 @@ func (keeper Keeper) SubmitProposal(ctx sdk.Context, messages []sdk.Msg, metadat } // CancelProposal will cancel proposal before the voting period ends -func (keeper Keeper) CancelProposal(ctx sdk.Context, proposalID uint64, proposer string) error { - proposal, ok := keeper.GetProposal(ctx, proposalID) - if !ok { - return errorsmod.Wrapf(types.ErrProposalNotFound, "proposal_id %d", proposalID) +func (keeper Keeper) CancelProposal(ctx context.Context, proposalID uint64, proposer string) error { + sdkCtx := sdk.UnwrapSDKContext(ctx) + proposal, err := keeper.GetProposal(ctx, proposalID) + if err != nil { + return err } // Checking proposal have proposer or not because old proposal doesn't have proposer field, @@ -136,23 +145,33 @@ func (keeper Keeper) CancelProposal(ctx sdk.Context, proposalID uint64, proposer } // Check proposal voting period is ended. - if proposal.VotingEndTime != nil && proposal.VotingEndTime.Before(ctx.BlockTime()) { + if proposal.VotingEndTime != nil && proposal.VotingEndTime.Before(sdkCtx.BlockTime()) { return types.ErrVotingPeriodEnded.Wrapf("voting period is already ended for this proposal %d", proposalID) } // burn the (deposits * proposal_cancel_rate) amount or sent to cancellation destination address. // and deposits * (1 - proposal_cancel_rate) will be sent to depositors. - params := keeper.GetParams(ctx) - err := keeper.ChargeDeposit(ctx, proposal.Id, params.ProposalCancelDest, params.ProposalCancelRatio) + params, err := keeper.GetParams(ctx) + if err != nil { + return err + } + + err = keeper.ChargeDeposit(ctx, proposal.Id, params.ProposalCancelDest, params.ProposalCancelRatio) if err != nil { return err } if proposal.VotingStartTime != nil { - keeper.deleteVotes(ctx, proposal.Id) + err = keeper.deleteVotes(ctx, proposal.Id) + if err != nil { + return err + } } - keeper.DeleteProposal(ctx, proposal.Id) + err = keeper.DeleteProposal(ctx, proposal.Id) + if err != nil { + return err + } keeper.Logger(ctx).Info( "proposal is canceled by proposer", @@ -164,88 +183,108 @@ func (keeper Keeper) CancelProposal(ctx sdk.Context, proposalID uint64, proposer } // GetProposal gets a proposal from store by ProposalID. -// Panics if can't unmarshal the proposal. -func (keeper Keeper) GetProposal(ctx sdk.Context, proposalID uint64) (v1.Proposal, bool) { - store := ctx.KVStore(keeper.storeKey) +func (keeper Keeper) GetProposal(ctx context.Context, proposalID uint64) (proposal v1.Proposal, err error) { + store := keeper.storeService.OpenKVStore(ctx) + + bz, err := store.Get(types.ProposalKey(proposalID)) + if err != nil { + return + } - bz := store.Get(types.ProposalKey(proposalID)) if bz == nil { - return v1.Proposal{}, false + return proposal, types.ErrProposalNotFound.Wrapf("proposal %d doesn't exist", proposalID) } - var proposal v1.Proposal - if err := keeper.UnmarshalProposal(bz, &proposal); err != nil { - panic(err) + if err = keeper.UnmarshalProposal(bz, &proposal); err != nil { + return } - return proposal, true + return proposal, nil } // SetProposal sets a proposal to store. -// Panics if can't marshal the proposal. -func (keeper Keeper) SetProposal(ctx sdk.Context, proposal v1.Proposal) { +func (keeper Keeper) SetProposal(ctx context.Context, proposal v1.Proposal) error { bz, err := keeper.MarshalProposal(proposal) if err != nil { - panic(err) + return err } - store := ctx.KVStore(keeper.storeKey) + store := keeper.storeService.OpenKVStore(ctx) if proposal.Status == v1.StatusVotingPeriod { - store.Set(types.VotingPeriodProposalKey(proposal.Id), []byte{1}) + err = store.Set(types.VotingPeriodProposalKey(proposal.Id), []byte{1}) + if err != nil { + return err + } } else { - store.Delete(types.VotingPeriodProposalKey(proposal.Id)) + err = store.Delete(types.VotingPeriodProposalKey(proposal.Id)) + if err != nil { + return err + } } - store.Set(types.ProposalKey(proposal.Id), bz) + return store.Set(types.ProposalKey(proposal.Id), bz) } // DeleteProposal deletes a proposal from store. -// Panics if the proposal doesn't exist. -func (keeper Keeper) DeleteProposal(ctx sdk.Context, proposalID uint64) { - store := ctx.KVStore(keeper.storeKey) - proposal, ok := keeper.GetProposal(ctx, proposalID) - if !ok { - panic(fmt.Sprintf("couldn't find proposal with id#%d", proposalID)) +func (keeper Keeper) DeleteProposal(ctx context.Context, proposalID uint64) error { + store := keeper.storeService.OpenKVStore(ctx) + proposal, err := keeper.GetProposal(ctx, proposalID) + if err != nil { + return err } if proposal.DepositEndTime != nil { - keeper.RemoveFromInactiveProposalQueue(ctx, proposalID, *proposal.DepositEndTime) + err := keeper.RemoveFromInactiveProposalQueue(ctx, proposalID, *proposal.DepositEndTime) + if err != nil { + return err + } } if proposal.VotingEndTime != nil { - keeper.RemoveFromActiveProposalQueue(ctx, proposalID, *proposal.VotingEndTime) - store.Delete(types.VotingPeriodProposalKey(proposalID)) + err := keeper.RemoveFromActiveProposalQueue(ctx, proposalID, *proposal.VotingEndTime) + if err != nil { + return err + } + + err = store.Delete(types.VotingPeriodProposalKey(proposalID)) + if err != nil { + return err + } } - store.Delete(types.ProposalKey(proposalID)) + return store.Delete(types.ProposalKey(proposalID)) } // IterateProposals iterates over all the proposals and performs a callback function. -// Panics when the iterator encounters a proposal which can't be unmarshaled. -func (keeper Keeper) IterateProposals(ctx sdk.Context, cb func(proposal v1.Proposal) (stop bool)) { - store := ctx.KVStore(keeper.storeKey) - - iterator := storetypes.KVStorePrefixIterator(store, types.ProposalsKeyPrefix) +func (keeper Keeper) IterateProposals(ctx context.Context, cb func(proposal v1.Proposal) error) error { + store := keeper.storeService.OpenKVStore(ctx) + iterator := storetypes.KVStorePrefixIterator(runtime.KVStoreAdapter(store), types.ProposalsKeyPrefix) defer iterator.Close() for ; iterator.Valid(); iterator.Next() { var proposal v1.Proposal err := keeper.UnmarshalProposal(iterator.Value(), &proposal) if err != nil { - panic(err) + return err } - if cb(proposal) { - break + err = cb(proposal) + // exit early without error if cb returns ErrStopIterating + if errorsmod.IsOf(err, errorsmod.ErrStopIterating) { + return nil + } else if err != nil { + return err } } + + return nil } // GetProposals returns all the proposals from store -func (keeper Keeper) GetProposals(ctx sdk.Context) (proposals v1.Proposals) { - keeper.IterateProposals(ctx, func(proposal v1.Proposal) bool { +func (keeper Keeper) GetProposals(ctx context.Context) (proposals v1.Proposals, err error) { + err = keeper.IterateProposals(ctx, func(proposal v1.Proposal) error { proposals = append(proposals, &proposal) - return false + return nil }) return } @@ -259,8 +298,12 @@ func (keeper Keeper) GetProposals(ctx sdk.Context) (proposals v1.Proposals) { // // NOTE: If no filters are provided, all proposals will be returned in paginated // form. -func (keeper Keeper) GetProposalsFiltered(ctx sdk.Context, params v1.QueryProposalsParams) v1.Proposals { - proposals := keeper.GetProposals(ctx) +func (keeper Keeper) GetProposalsFiltered(ctx context.Context, params v1.QueryProposalsParams) (v1.Proposals, error) { + proposals, err := keeper.GetProposals(ctx) + if err != nil { + return nil, err + } + filteredProposals := make([]*v1.Proposal, 0, len(proposals)) for _, p := range proposals { @@ -273,12 +316,16 @@ func (keeper Keeper) GetProposalsFiltered(ctx sdk.Context, params v1.QueryPropos // match voter address (if supplied) if len(params.Voter) > 0 { - _, matchVoter = keeper.GetVote(ctx, p.Id, params.Voter) + _, err = keeper.GetVote(ctx, p.Id, params.Voter) + // if no error, vote found, matchVoter = true + matchVoter = err == nil } // match depositor (if supplied) if len(params.Depositor) > 0 { - _, matchDepositor = keeper.GetDeposit(ctx, p.Id, params.Depositor) + _, err = keeper.GetDeposit(ctx, p.Id, params.Depositor) + // if no error, deposit found, matchDepositor = true + matchDepositor = err == nil } if matchVoter && matchDepositor && matchStatus { @@ -293,13 +340,16 @@ func (keeper Keeper) GetProposalsFiltered(ctx sdk.Context, params v1.QueryPropos filteredProposals = filteredProposals[start:end] } - return filteredProposals + return filteredProposals, nil } // GetProposalID gets the highest proposal ID -func (keeper Keeper) GetProposalID(ctx sdk.Context) (proposalID uint64, err error) { - store := ctx.KVStore(keeper.storeKey) - bz := store.Get(types.ProposalIDKey) +func (keeper Keeper) GetProposalID(ctx context.Context) (proposalID uint64, err error) { + store := keeper.storeService.OpenKVStore(ctx) + bz, err := store.Get(types.ProposalIDKey) + if err != nil { + return 0, err + } if bz == nil { return 0, errorsmod.Wrap(types.ErrInvalidGenesis, "initial proposal ID hasn't been set") } @@ -309,28 +359,41 @@ func (keeper Keeper) GetProposalID(ctx sdk.Context) (proposalID uint64, err erro } // SetProposalID sets the new proposal ID to the store -func (keeper Keeper) SetProposalID(ctx sdk.Context, proposalID uint64) { - store := ctx.KVStore(keeper.storeKey) - store.Set(types.ProposalIDKey, types.GetProposalIDBytes(proposalID)) +func (keeper Keeper) SetProposalID(ctx context.Context, proposalID uint64) error { + store := keeper.storeService.OpenKVStore(ctx) + return store.Set(types.ProposalIDKey, types.GetProposalIDBytes(proposalID)) } // ActivateVotingPeriod activates the voting period of a proposal -func (keeper Keeper) ActivateVotingPeriod(ctx sdk.Context, proposal v1.Proposal) { - startTime := ctx.BlockHeader().Time +func (keeper Keeper) ActivateVotingPeriod(ctx context.Context, proposal v1.Proposal) error { + sdkCtx := sdk.UnwrapSDKContext(ctx) + startTime := sdkCtx.BlockHeader().Time proposal.VotingStartTime = &startTime var votingPeriod *time.Duration + params, err := keeper.GetParams(ctx) + if err != nil { + return err + } + if proposal.Expedited { - votingPeriod = keeper.GetParams(ctx).ExpeditedVotingPeriod + votingPeriod = params.ExpeditedVotingPeriod } else { - votingPeriod = keeper.GetParams(ctx).VotingPeriod + votingPeriod = params.VotingPeriod } endTime := proposal.VotingStartTime.Add(*votingPeriod) proposal.VotingEndTime = &endTime proposal.Status = v1.StatusVotingPeriod - keeper.SetProposal(ctx, proposal) + err = keeper.SetProposal(ctx, proposal) + if err != nil { + return err + } + + err = keeper.RemoveFromInactiveProposalQueue(ctx, proposal.Id, *proposal.DepositEndTime) + if err != nil { + return err + } - keeper.RemoveFromInactiveProposalQueue(ctx, proposal.Id, *proposal.DepositEndTime) - keeper.InsertActiveProposalQueue(ctx, proposal.Id, *proposal.VotingEndTime) + return keeper.InsertActiveProposalQueue(ctx, proposal.Id, *proposal.VotingEndTime) } // MarshalProposal marshals the proposal and returns binary encoded bytes. diff --git a/x/gov/keeper/proposal_test.go b/x/gov/keeper/proposal_test.go index 2a888cf14816..0029e27bd39f 100644 --- a/x/gov/keeper/proposal_test.go +++ b/x/gov/keeper/proposal_test.go @@ -33,8 +33,8 @@ func (suite *KeeperTestSuite) TestGetSetProposal() { proposalID := proposal.Id suite.govKeeper.SetProposal(suite.ctx, proposal) - gotProposal, ok := suite.govKeeper.GetProposal(suite.ctx, proposalID) - suite.Require().True(ok) + gotProposal, err := suite.govKeeper.GetProposal(suite.ctx, proposalID) + suite.Require().Nil(err) suite.Require().Equal(proposal, gotProposal) } } @@ -51,11 +51,8 @@ func (suite *KeeperTestSuite) TestDeleteProposal() { for _, tc := range testCases { // delete non-existing proposal - suite.Require().PanicsWithValue(fmt.Sprintf("couldn't find proposal with id#%d", 10), - func() { - suite.govKeeper.DeleteProposal(suite.ctx, 10) - }, - ) + suite.Require().ErrorIs(suite.govKeeper.DeleteProposal(suite.ctx, 10), types.ErrProposalNotFound.Wrapf("proposal_id %d", 10)) + tp := TestProposal proposal, err := suite.govKeeper.SubmitProposal(suite.ctx, tp, "", "test", "summary", suite.addrs[0], tc.expedited) suite.Require().NoError(err) @@ -85,11 +82,11 @@ func (suite *KeeperTestSuite) TestActivateVotingPeriod() { suite.govKeeper.ActivateVotingPeriod(suite.ctx, proposal) - proposal, ok := suite.govKeeper.GetProposal(suite.ctx, proposal.Id) - suite.Require().True(ok) + proposal, err = suite.govKeeper.GetProposal(suite.ctx, proposal.Id) + suite.Require().Nil(err) suite.Require().True(proposal.VotingStartTime.Equal(suite.ctx.BlockHeader().Time)) - activeIterator := suite.govKeeper.ActiveProposalQueueIterator(suite.ctx, *proposal.VotingEndTime) + activeIterator, _ := suite.govKeeper.ActiveProposalQueueIterator(suite.ctx, *proposal.VotingEndTime) suite.Require().True(activeIterator.Valid()) proposalID := types.GetProposalIDFromBytes(activeIterator.Value()) @@ -121,11 +118,11 @@ func (suite *KeeperTestSuite) TestDeleteProposalInVotingPeriod() { suite.govKeeper.ActivateVotingPeriod(suite.ctx, proposal) - proposal, ok := suite.govKeeper.GetProposal(suite.ctx, proposal.Id) - suite.Require().True(ok) + proposal, err = suite.govKeeper.GetProposal(suite.ctx, proposal.Id) + suite.Require().Nil(err) suite.Require().True(proposal.VotingStartTime.Equal(suite.ctx.BlockHeader().Time)) - activeIterator := suite.govKeeper.ActiveProposalQueueIterator(suite.ctx, *proposal.VotingEndTime) + activeIterator, _ := suite.govKeeper.ActiveProposalQueueIterator(suite.ctx, *proposal.VotingEndTime) suite.Require().True(activeIterator.Valid()) proposalID := types.GetProposalIDFromBytes(activeIterator.Value()) @@ -231,7 +228,7 @@ func (suite *KeeperTestSuite) TestGetProposalsFiltered() { for i, tc := range testCases { suite.Run(fmt.Sprintf("Test Case %d", i), func() { - proposals := suite.govKeeper.GetProposalsFiltered(suite.ctx, tc.params) + proposals, _ := suite.govKeeper.GetProposalsFiltered(suite.ctx, tc.params) suite.Require().Len(proposals, tc.expectedNumResults) for _, p := range proposals { @@ -255,8 +252,8 @@ func (suite *KeeperTestSuite) TestCancelProposal() { proposal2Resp, err := suite.govKeeper.SubmitProposal(suite.ctx, []sdk.Msg{prop}, "", "title", "summary", suite.addrs[1], true) proposal2ID := proposal2Resp.Id makeProposalPass := func() { - proposal2, ok := suite.govKeeper.GetProposal(suite.ctx, proposal2ID) - suite.Require().True(ok) + proposal2, err := suite.govKeeper.GetProposal(suite.ctx, proposal2ID) + suite.Require().Nil(err) proposal2.Status = v1.ProposalStatus_PROPOSAL_STATUS_PASSED suite.govKeeper.SetProposal(suite.ctx, proposal2) diff --git a/x/gov/keeper/tally.go b/x/gov/keeper/tally.go index 48321d2effcf..ed1084e7038b 100644 --- a/x/gov/keeper/tally.go +++ b/x/gov/keeper/tally.go @@ -1,7 +1,10 @@ package keeper import ( + "context" + "cosmossdk.io/math" + sdk "github.com/cosmos/cosmos-sdk/types" v1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" @@ -11,7 +14,7 @@ import ( // Tally iterates over the votes and updates the tally of a proposal based on the voting power of the // voters -func (keeper Keeper) Tally(ctx sdk.Context, proposal v1.Proposal) (passes, burnDeposits bool, tallyResults v1.TallyResult) { +func (keeper Keeper) Tally(ctx context.Context, proposal v1.Proposal) (passes, burnDeposits bool, tallyResults v1.TallyResult, err error) { results := make(map[v1.VoteOption]math.LegacyDec) results[v1.OptionYes] = math.LegacyZeroDec() results[v1.OptionAbstain] = math.LegacyZeroDec() @@ -22,7 +25,8 @@ func (keeper Keeper) Tally(ctx sdk.Context, proposal v1.Proposal) (passes, burnD currValidators := make(map[string]v1.ValidatorGovInfo) // fetch all the bonded validators, insert them into currValidators - keeper.sk.IterateBondedValidatorsByPower(ctx, func(index int64, validator stakingtypes.ValidatorI) (stop bool) { + sdkCtx := sdk.UnwrapSDKContext(ctx) + keeper.sk.IterateBondedValidatorsByPower(sdkCtx, func(index int64, validator stakingtypes.ValidatorI) (stop bool) { currValidators[validator.GetOperator().String()] = v1.NewValidatorGovInfo( validator.GetOperator(), validator.GetBondedTokens(), @@ -34,11 +38,11 @@ func (keeper Keeper) Tally(ctx sdk.Context, proposal v1.Proposal) (passes, burnD return false }) - keeper.IterateVotes(ctx, proposal.Id, func(vote v1.Vote) bool { + err = keeper.IterateVotes(ctx, proposal.Id, func(vote v1.Vote) error { // if validator, just record it in the map voter, err := keeper.authKeeper.StringToBytes(vote.Voter) if err != nil { - panic(err) + return err } valAddrStr := sdk.ValAddress(voter).String() @@ -48,7 +52,7 @@ func (keeper Keeper) Tally(ctx sdk.Context, proposal v1.Proposal) (passes, burnD } // iterate over all delegations from voter, deduct from any delegated-to validators - keeper.sk.IterateDelegations(ctx, voter, func(index int64, delegation stakingtypes.DelegationI) (stop bool) { + keeper.sk.IterateDelegations(sdkCtx, voter, func(index int64, delegation stakingtypes.DelegationI) (stop bool) { valAddrStr := delegation.GetValidatorAddr().String() if val, ok := currValidators[valAddrStr]; ok { @@ -71,10 +75,13 @@ func (keeper Keeper) Tally(ctx sdk.Context, proposal v1.Proposal) (passes, burnD return false }) - keeper.deleteVote(ctx, vote.ProposalId, voter) - return false + return keeper.deleteVote(ctx, vote.ProposalId, voter) }) + if err != nil { + return false, false, tallyResults, err + } + // iterate over the validators again to tally their voting power for _, val := range currValidators { if len(val.Vote) == 0 { @@ -92,31 +99,34 @@ func (keeper Keeper) Tally(ctx sdk.Context, proposal v1.Proposal) (passes, burnD totalVotingPower = totalVotingPower.Add(votingPower) } - params := keeper.GetParams(ctx) + params, err := keeper.GetParams(ctx) + if err != nil { + return false, false, tallyResults, err + } tallyResults = v1.NewTallyResultFromMap(results) // TODO: Upgrade the spec to cover all of these cases & remove pseudocode. // If there is no staked coins, the proposal fails - if keeper.sk.TotalBondedTokens(ctx).IsZero() { - return false, false, tallyResults + if keeper.sk.TotalBondedTokens(sdkCtx).IsZero() { + return false, false, tallyResults, nil } // If there is not enough quorum of votes, the proposal fails - percentVoting := totalVotingPower.Quo(math.LegacyNewDecFromInt(keeper.sk.TotalBondedTokens(ctx))) + percentVoting := totalVotingPower.Quo(math.LegacyNewDecFromInt(keeper.sk.TotalBondedTokens(sdkCtx))) quorum, _ := math.LegacyNewDecFromStr(params.Quorum) if percentVoting.LT(quorum) { - return false, params.BurnVoteQuorum, tallyResults + return false, params.BurnVoteQuorum, tallyResults, nil } // If no one votes (everyone abstains), proposal fails if totalVotingPower.Sub(results[v1.OptionAbstain]).Equal(math.LegacyZeroDec()) { - return false, false, tallyResults + return false, false, tallyResults, nil } // If more than 1/3 of voters veto, proposal fails vetoThreshold, _ := math.LegacyNewDecFromStr(params.VetoThreshold) if results[v1.OptionNoWithVeto].Quo(totalVotingPower).GT(vetoThreshold) { - return false, params.BurnVoteVeto, tallyResults + return false, params.BurnVoteVeto, tallyResults, nil } // If more than 1/2 of non-abstaining voters vote Yes, proposal passes @@ -129,10 +139,11 @@ func (keeper Keeper) Tally(ctx sdk.Context, proposal v1.Proposal) (passes, burnD } threshold, _ := math.LegacyNewDecFromStr(thresholdStr) + if results[v1.OptionYes].Quo(totalVotingPower.Sub(results[v1.OptionAbstain])).GT(threshold) { - return true, false, tallyResults + return true, false, tallyResults, nil } // If more than 1/2 of non-abstaining voters vote No, proposal fails - return false, false, tallyResults + return false, false, tallyResults, nil } diff --git a/x/gov/keeper/vote.go b/x/gov/keeper/vote.go index 0a1e2b6f6cf5..294f31dd7a9f 100644 --- a/x/gov/keeper/vote.go +++ b/x/gov/keeper/vote.go @@ -1,25 +1,32 @@ package keeper import ( + "context" "fmt" "cosmossdk.io/errors" storetypes "cosmossdk.io/store/types" + "github.com/cosmos/cosmos-sdk/runtime" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/gov/types" v1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" ) // AddVote adds a vote on a specific proposal -func (keeper Keeper) AddVote(ctx sdk.Context, proposalID uint64, voterAddr sdk.AccAddress, options v1.WeightedVoteOptions, metadata string) error { +func (keeper Keeper) AddVote(ctx context.Context, proposalID uint64, voterAddr sdk.AccAddress, options v1.WeightedVoteOptions, metadata string) error { // Check if proposal is in voting period. - store := ctx.KVStore(keeper.storeKey) - if !store.Has(types.VotingPeriodProposalKey(proposalID)) { + store := keeper.storeService.OpenKVStore(ctx) + inVotingPeriod, err := store.Has(types.VotingPeriodProposalKey(proposalID)) + if err != nil { + return err + } + + if !inVotingPeriod { return errors.Wrapf(types.ErrInactiveProposal, "%d", proposalID) } - err := keeper.assertMetadataLength(metadata) + err = keeper.assertMetadataLength(metadata) if err != nil { return err } @@ -31,12 +38,16 @@ func (keeper Keeper) AddVote(ctx sdk.Context, proposalID uint64, voterAddr sdk.A } vote := v1.NewVote(proposalID, voterAddr, options, metadata) - keeper.SetVote(ctx, vote) + err = keeper.SetVote(ctx, vote) + if err != nil { + return err + } // called after a vote on a proposal is cast keeper.Hooks().AfterProposalVote(ctx, proposalID, voterAddr) - ctx.EventManager().EmitEvent( + sdkCtx := sdk.UnwrapSDKContext(ctx) + sdkCtx.EventManager().EmitEvent( sdk.NewEvent( types.EventTypeProposalVote, sdk.NewAttribute(types.AttributeKeyOption, options.String()), @@ -48,88 +59,117 @@ func (keeper Keeper) AddVote(ctx sdk.Context, proposalID uint64, voterAddr sdk.A } // GetAllVotes returns all the votes from the store -func (keeper Keeper) GetAllVotes(ctx sdk.Context) (votes v1.Votes) { - keeper.IterateAllVotes(ctx, func(vote v1.Vote) bool { +func (keeper Keeper) GetAllVotes(ctx context.Context) (votes v1.Votes, err error) { + err = keeper.IterateAllVotes(ctx, func(vote v1.Vote) error { votes = append(votes, &vote) - return false + return nil }) return } // GetVotes returns all the votes from a proposal -func (keeper Keeper) GetVotes(ctx sdk.Context, proposalID uint64) (votes v1.Votes) { - keeper.IterateVotes(ctx, proposalID, func(vote v1.Vote) bool { +func (keeper Keeper) GetVotes(ctx context.Context, proposalID uint64) (votes v1.Votes, err error) { + err = keeper.IterateVotes(ctx, proposalID, func(vote v1.Vote) error { votes = append(votes, &vote) - return false + return nil }) return } // GetVote gets the vote from an address on a specific proposal -func (keeper Keeper) GetVote(ctx sdk.Context, proposalID uint64, voterAddr sdk.AccAddress) (vote v1.Vote, found bool) { - store := ctx.KVStore(keeper.storeKey) - bz := store.Get(types.VoteKey(proposalID, voterAddr)) +func (keeper Keeper) GetVote(ctx context.Context, proposalID uint64, voterAddr sdk.AccAddress) (vote v1.Vote, err error) { + store := keeper.storeService.OpenKVStore(ctx) + bz, err := store.Get(types.VoteKey(proposalID, voterAddr)) + if err != nil { + return vote, err + } + if bz == nil { - return vote, false + return vote, types.ErrVoteNotFound } - keeper.cdc.MustUnmarshal(bz, &vote) + err = keeper.cdc.Unmarshal(bz, &vote) + if err != nil { + return vote, err + } - return vote, true + return vote, nil } // SetVote sets a Vote to the gov store -func (keeper Keeper) SetVote(ctx sdk.Context, vote v1.Vote) { - store := ctx.KVStore(keeper.storeKey) - bz := keeper.cdc.MustMarshal(&vote) +func (keeper Keeper) SetVote(ctx context.Context, vote v1.Vote) error { + store := keeper.storeService.OpenKVStore(ctx) + bz, err := keeper.cdc.Marshal(&vote) + if err != nil { + return err + } + addr, err := keeper.authKeeper.StringToBytes(vote.Voter) if err != nil { - panic(err) + return err } - store.Set(types.VoteKey(vote.ProposalId, addr), bz) + return store.Set(types.VoteKey(vote.ProposalId, addr), bz) } // IterateAllVotes iterates over all the stored votes and performs a callback function -func (keeper Keeper) IterateAllVotes(ctx sdk.Context, cb func(vote v1.Vote) (stop bool)) { - store := ctx.KVStore(keeper.storeKey) - iterator := storetypes.KVStorePrefixIterator(store, types.VotesKeyPrefix) +func (keeper Keeper) IterateAllVotes(ctx context.Context, cb func(vote v1.Vote) error) error { + store := keeper.storeService.OpenKVStore(ctx) + iterator := storetypes.KVStorePrefixIterator(runtime.KVStoreAdapter(store), types.VotesKeyPrefix) defer iterator.Close() for ; iterator.Valid(); iterator.Next() { var vote v1.Vote - keeper.cdc.MustUnmarshal(iterator.Value(), &vote) + err := keeper.cdc.Unmarshal(iterator.Value(), &vote) + if err != nil { + return err + } - if cb(vote) { - break + err = cb(vote) + // exit early without error if cb returns ErrStopIterating + if errors.IsOf(err, errors.ErrStopIterating) { + return nil + } else if err != nil { + return err } } + + return nil } // IterateVotes iterates over all the proposals votes and performs a callback function -func (keeper Keeper) IterateVotes(ctx sdk.Context, proposalID uint64, cb func(vote v1.Vote) (stop bool)) { - store := ctx.KVStore(keeper.storeKey) - iterator := storetypes.KVStorePrefixIterator(store, types.VotesKey(proposalID)) +func (keeper Keeper) IterateVotes(ctx context.Context, proposalID uint64, cb func(vote v1.Vote) error) error { + store := keeper.storeService.OpenKVStore(ctx) + iterator := storetypes.KVStorePrefixIterator(runtime.KVStoreAdapter(store), types.VotesKey(proposalID)) defer iterator.Close() for ; iterator.Valid(); iterator.Next() { var vote v1.Vote - keeper.cdc.MustUnmarshal(iterator.Value(), &vote) + err := keeper.cdc.Unmarshal(iterator.Value(), &vote) + if err != nil { + return err + } - if cb(vote) { - break + err = cb(vote) + // exit early without error if cb returns ErrStopIterating + if errors.IsOf(err, errors.ErrStopIterating) { + return nil + } else if err != nil { + return err } } + + return nil } // deleteVotes deletes the all votes from a given proposalID. -func (keeper Keeper) deleteVotes(ctx sdk.Context, proposalID uint64) { - store := ctx.KVStore(keeper.storeKey) - store.Delete(types.VotesKey(proposalID)) +func (keeper Keeper) deleteVotes(ctx context.Context, proposalID uint64) error { + store := keeper.storeService.OpenKVStore(ctx) + return store.Delete(types.VotesKey(proposalID)) } // deleteVote deletes a vote from a given proposalID and voter from the store -func (keeper Keeper) deleteVote(ctx sdk.Context, proposalID uint64, voterAddr sdk.AccAddress) { - store := ctx.KVStore(keeper.storeKey) - store.Delete(types.VoteKey(proposalID, voterAddr)) +func (keeper Keeper) deleteVote(ctx context.Context, proposalID uint64, voterAddr sdk.AccAddress) error { + store := keeper.storeService.OpenKVStore(ctx) + return store.Delete(types.VoteKey(proposalID, voterAddr)) } diff --git a/x/gov/keeper/vote_test.go b/x/gov/keeper/vote_test.go index 29e1e89722f4..2f72cbc15a22 100644 --- a/x/gov/keeper/vote_test.go +++ b/x/gov/keeper/vote_test.go @@ -8,6 +8,7 @@ import ( simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/gov/types" v1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" ) @@ -37,8 +38,8 @@ func TestVotes(t *testing.T) { // Test first vote require.NoError(t, govKeeper.AddVote(ctx, proposalID, addrs[0], v1.NewNonSplitVoteOption(v1.OptionAbstain), metadata)) - vote, found := govKeeper.GetVote(ctx, proposalID, addrs[0]) - require.True(t, found) + vote, err := govKeeper.GetVote(ctx, proposalID, addrs[0]) + require.Nil(t, err) require.Equal(t, addrs[0].String(), vote.Voter) require.Equal(t, proposalID, vote.ProposalId) require.True(t, len(vote.Options) == 1) @@ -46,8 +47,8 @@ func TestVotes(t *testing.T) { // Test change of vote require.NoError(t, govKeeper.AddVote(ctx, proposalID, addrs[0], v1.NewNonSplitVoteOption(v1.OptionYes), "")) - vote, found = govKeeper.GetVote(ctx, proposalID, addrs[0]) - require.True(t, found) + vote, err = govKeeper.GetVote(ctx, proposalID, addrs[0]) + require.Nil(t, err) require.Equal(t, addrs[0].String(), vote.Voter) require.Equal(t, proposalID, vote.ProposalId) require.True(t, len(vote.Options) == 1) @@ -60,8 +61,8 @@ func TestVotes(t *testing.T) { v1.NewWeightedVoteOption(v1.OptionAbstain, sdkmath.LegacyNewDecWithPrec(5, 2)), v1.NewWeightedVoteOption(v1.OptionNoWithVeto, sdkmath.LegacyNewDecWithPrec(5, 2)), }, "")) - vote, found = govKeeper.GetVote(ctx, proposalID, addrs[1]) - require.True(t, found) + vote, err = govKeeper.GetVote(ctx, proposalID, addrs[1]) + require.Nil(t, err) require.Equal(t, addrs[1].String(), vote.Voter) require.Equal(t, proposalID, vote.ProposalId) require.True(t, len(vote.Options) == 4) @@ -76,9 +77,10 @@ func TestVotes(t *testing.T) { // Test vote iterator // NOTE order of deposits is determined by the addresses - votes := govKeeper.GetAllVotes(ctx) + votes, _ := govKeeper.GetAllVotes(ctx) require.Len(t, votes, 2) - require.Equal(t, votes, govKeeper.GetVotes(ctx, proposalID)) + propVotes, _ := govKeeper.GetVotes(ctx, proposalID) + require.Equal(t, votes, propVotes) require.Equal(t, addrs[0].String(), votes[0].Voter) require.Equal(t, proposalID, votes[0].ProposalId) require.True(t, len(votes[0].Options) == 1) @@ -90,4 +92,8 @@ func TestVotes(t *testing.T) { require.Equal(t, votes[1].Options[1].Weight, sdkmath.LegacyNewDecWithPrec(30, 2).String()) require.Equal(t, votes[1].Options[2].Weight, sdkmath.LegacyNewDecWithPrec(5, 2).String()) require.Equal(t, votes[1].Options[3].Weight, sdkmath.LegacyNewDecWithPrec(5, 2).String()) + + // non existent vote + _, err = govKeeper.GetVote(ctx, proposalID+100, addrs[1]) + require.ErrorIs(t, err, types.ErrVoteNotFound) } diff --git a/x/gov/migrations/v2/store.go b/x/gov/migrations/v2/store.go index de69b56859d4..151df2f55bd4 100644 --- a/x/gov/migrations/v2/store.go +++ b/x/gov/migrations/v2/store.go @@ -3,10 +3,12 @@ package v2 import ( "fmt" + corestoretypes "cosmossdk.io/core/store" "cosmossdk.io/store/prefix" storetypes "cosmossdk.io/store/types" "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/runtime" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/address" "github.com/cosmos/cosmos-sdk/x/gov/types" @@ -19,8 +21,8 @@ const proposalIDLen = 8 // // into format: // -func migratePrefixProposalAddress(store storetypes.KVStore, prefixBz []byte) { - oldStore := prefix.NewStore(store, prefixBz) +func migratePrefixProposalAddress(store corestoretypes.KVStore, prefixBz []byte) error { + oldStore := prefix.NewStore(runtime.KVStoreAdapter(store), prefixBz) oldStoreIter := oldStore.Iterator(nil, nil) defer oldStoreIter.Close() @@ -31,9 +33,13 @@ func migratePrefixProposalAddress(store storetypes.KVStore, prefixBz []byte) { newStoreKey := append(append(prefixBz, proposalID...), address.MustLengthPrefix(addr)...) // Set new key on store. Values don't change. - store.Set(newStoreKey, oldStoreIter.Value()) + err := store.Set(newStoreKey, oldStoreIter.Value()) + if err != nil { + return err + } oldStore.Delete(oldStoreIter.Key()) } + return nil } // migrateStoreWeightedVotes migrates a legacy vote to an ADR-037 weighted vote. @@ -48,8 +54,8 @@ func migrateVote(oldVote v1beta1.Vote) v1beta1.Vote { } // migrateStoreWeightedVotes migrates in-place all legacy votes to ADR-037 weighted votes. -func migrateStoreWeightedVotes(store storetypes.KVStore, cdc codec.BinaryCodec) error { - iterator := storetypes.KVStorePrefixIterator(store, types.VotesKeyPrefix) +func migrateStoreWeightedVotes(store corestoretypes.KVStore, cdc codec.BinaryCodec) error { + iterator := storetypes.KVStorePrefixIterator(runtime.KVStoreAdapter(store), types.VotesKeyPrefix) defer iterator.Close() for ; iterator.Valid(); iterator.Next() { @@ -66,7 +72,10 @@ func migrateStoreWeightedVotes(store storetypes.KVStore, cdc codec.BinaryCodec) return err } - store.Set(iterator.Key(), bz) + err = store.Set(iterator.Key(), bz) + if err != nil { + return err + } } return nil @@ -77,9 +86,17 @@ func migrateStoreWeightedVotes(store storetypes.KVStore, cdc codec.BinaryCodec) // // - Change addresses to be length-prefixed. // - Change all legacy votes to ADR-037 weighted votes. -func MigrateStore(ctx sdk.Context, storeKey storetypes.StoreKey, cdc codec.BinaryCodec) error { - store := ctx.KVStore(storeKey) - migratePrefixProposalAddress(store, types.DepositsKeyPrefix) - migratePrefixProposalAddress(store, types.VotesKeyPrefix) +func MigrateStore(ctx sdk.Context, storeService corestoretypes.KVStoreService, cdc codec.BinaryCodec) error { + store := storeService.OpenKVStore(ctx) + err := migratePrefixProposalAddress(store, types.DepositsKeyPrefix) + if err != nil { + return err + } + + err = migratePrefixProposalAddress(store, types.VotesKeyPrefix) + if err != nil { + return err + } + return migrateStoreWeightedVotes(store, cdc) } diff --git a/x/gov/migrations/v2/store_test.go b/x/gov/migrations/v2/store_test.go index 05a63ec85acd..24cc9b416d6f 100644 --- a/x/gov/migrations/v2/store_test.go +++ b/x/gov/migrations/v2/store_test.go @@ -10,6 +10,7 @@ import ( storetypes "cosmossdk.io/store/types" + "github.com/cosmos/cosmos-sdk/runtime" "github.com/cosmos/cosmos-sdk/testutil" "github.com/cosmos/cosmos-sdk/testutil/testdata" moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil" @@ -78,7 +79,8 @@ func TestMigrateStore(t *testing.T) { } // Run migratio - err := v2.MigrateStore(ctx, govKey, cdc) + storeService := runtime.NewKVStoreService(govKey) + err := v2.MigrateStore(ctx, storeService, cdc) require.NoError(t, err) // Make sure the new keys are set and old keys are deleted. diff --git a/x/gov/migrations/v3/store.go b/x/gov/migrations/v3/store.go index cdbb419f61ce..b1a17b8ef202 100644 --- a/x/gov/migrations/v3/store.go +++ b/x/gov/migrations/v3/store.go @@ -1,10 +1,12 @@ package v3 import ( + corestoretypes "cosmossdk.io/core/store" "cosmossdk.io/store/prefix" storetypes "cosmossdk.io/store/types" "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/runtime" sdk "github.com/cosmos/cosmos-sdk/types" v1 "github.com/cosmos/cosmos-sdk/x/gov/migrations/v1" govv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" @@ -85,12 +87,12 @@ func migrateVotes(store storetypes.KVStore, cdc codec.BinaryCodec) error { // migration includes: // // - Migrate proposals to be Msg-based. -func MigrateStore(ctx sdk.Context, storeKey storetypes.StoreKey, cdc codec.BinaryCodec) error { - store := ctx.KVStore(storeKey) +func MigrateStore(ctx sdk.Context, storeService corestoretypes.KVStoreService, cdc codec.BinaryCodec) error { + store := storeService.OpenKVStore(ctx) - if err := migrateVotes(store, cdc); err != nil { + if err := migrateVotes(runtime.KVStoreAdapter(store), cdc); err != nil { return err } - return migrateProposals(store, cdc) + return migrateProposals(runtime.KVStoreAdapter(store), cdc) } diff --git a/x/gov/migrations/v3/store_test.go b/x/gov/migrations/v3/store_test.go index b145fe89acb5..d7f25d361e67 100644 --- a/x/gov/migrations/v3/store_test.go +++ b/x/gov/migrations/v3/store_test.go @@ -8,6 +8,7 @@ import ( storetypes "cosmossdk.io/store/types" + "github.com/cosmos/cosmos-sdk/runtime" "github.com/cosmos/cosmos-sdk/testutil" sdk "github.com/cosmos/cosmos-sdk/types" moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil" @@ -50,7 +51,8 @@ func TestMigrateStore(t *testing.T) { store.Set(v1gov.VoteKey(1, voter), vote1Bz) // Run migrations. - err = v3gov.MigrateStore(ctx, govKey, cdc) + storeService := runtime.NewKVStoreService(govKey) + err = v3gov.MigrateStore(ctx, storeService, cdc) require.NoError(t, err) var newProp1 v1.Proposal diff --git a/x/gov/migrations/v4/store.go b/x/gov/migrations/v4/store.go index 6ae73cc12a11..0124b4167d54 100644 --- a/x/gov/migrations/v4/store.go +++ b/x/gov/migrations/v4/store.go @@ -4,10 +4,12 @@ import ( "fmt" "sort" + corestoretypes "cosmossdk.io/core/store" "cosmossdk.io/store/prefix" storetypes "cosmossdk.io/store/types" "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/runtime" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/gov/exported" v1 "github.com/cosmos/cosmos-sdk/x/gov/migrations/v1" @@ -15,9 +17,7 @@ import ( govv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" ) -func migrateParams(ctx sdk.Context, storeKey storetypes.StoreKey, legacySubspace exported.ParamSubspace, cdc codec.BinaryCodec) error { - store := ctx.KVStore(storeKey) - +func migrateParams(ctx sdk.Context, store storetypes.KVStore, legacySubspace exported.ParamSubspace, cdc codec.BinaryCodec) error { dp := govv1.DepositParams{} vp := govv1.VotingParams{} tp := govv1.TallyParams{} @@ -54,8 +54,7 @@ func migrateParams(ctx sdk.Context, storeKey storetypes.StoreKey, legacySubspace return nil } -func migrateProposalVotingPeriod(ctx sdk.Context, storeKey storetypes.StoreKey, cdc codec.BinaryCodec) error { - store := ctx.KVStore(storeKey) +func migrateProposalVotingPeriod(ctx sdk.Context, store storetypes.KVStore, cdc codec.BinaryCodec) error { propStore := prefix.NewStore(store, v1.ProposalsKeyPrefix) iter := propStore.Iterator(nil, nil) @@ -82,16 +81,17 @@ func migrateProposalVotingPeriod(ctx sdk.Context, storeKey storetypes.StoreKey, // Params migrations from x/params to gov // Addition of the new min initial deposit ratio parameter that is set to 0 by default. // Proposals in voting period are tracked in a separate index. -func MigrateStore(ctx sdk.Context, storeKey storetypes.StoreKey, legacySubspace exported.ParamSubspace, cdc codec.BinaryCodec) error { - if err := migrateProposalVotingPeriod(ctx, storeKey, cdc); err != nil { +func MigrateStore(ctx sdk.Context, storeService corestoretypes.KVStoreService, legacySubspace exported.ParamSubspace, cdc codec.BinaryCodec) error { + store := runtime.KVStoreAdapter(storeService.OpenKVStore(ctx)) + if err := migrateProposalVotingPeriod(ctx, store, cdc); err != nil { return err } - return migrateParams(ctx, storeKey, legacySubspace, cdc) + return migrateParams(ctx, store, legacySubspace, cdc) } // AddProposerAddressToProposal will add proposer to proposal and set to the store. This function is optional. -func AddProposerAddressToProposal(ctx sdk.Context, storeKey storetypes.StoreKey, cdc codec.BinaryCodec, proposals map[uint64]string) error { +func AddProposerAddressToProposal(ctx sdk.Context, storeService corestoretypes.KVStoreService, cdc codec.BinaryCodec, proposals map[uint64]string) error { proposalIDs := make([]uint64, 0, len(proposals)) for proposalID := range proposals { @@ -101,7 +101,7 @@ func AddProposerAddressToProposal(ctx sdk.Context, storeKey storetypes.StoreKey, // sort the proposalIDs sort.Slice(proposalIDs, func(i, j int) bool { return proposalIDs[i] < proposalIDs[j] }) - store := ctx.KVStore(storeKey) + store := runtime.KVStoreAdapter(storeService.OpenKVStore(ctx)) for _, proposalID := range proposalIDs { if len(proposals[proposalID]) == 0 { diff --git a/x/gov/migrations/v4/store_test.go b/x/gov/migrations/v4/store_test.go index cadc1d14308d..354cd6b77fe0 100644 --- a/x/gov/migrations/v4/store_test.go +++ b/x/gov/migrations/v4/store_test.go @@ -9,6 +9,7 @@ import ( sdkmath "cosmossdk.io/math" storetypes "cosmossdk.io/store/types" + "github.com/cosmos/cosmos-sdk/runtime" "github.com/cosmos/cosmos-sdk/testutil" "github.com/cosmos/cosmos-sdk/testutil/testdata" sdk "github.com/cosmos/cosmos-sdk/types" @@ -91,7 +92,8 @@ func TestMigrateStore(t *testing.T) { store.Set(v1gov.ProposalKey(proposal2.Id), prop2Bz) // Run migrations. - err = v4.MigrateStore(ctx, govKey, legacySubspace, cdc) + storeService := runtime.NewKVStoreService(govKey) + err = v4.MigrateStore(ctx, storeService, legacySubspace, cdc) require.NoError(t, err) // Check params diff --git a/x/gov/migrations/v5/store.go b/x/gov/migrations/v5/store.go index 489566149b1f..1af0ea4ba854 100644 --- a/x/gov/migrations/v5/store.go +++ b/x/gov/migrations/v5/store.go @@ -1,7 +1,7 @@ package v5 import ( - storetypes "cosmossdk.io/store/types" + corestoretypes "cosmossdk.io/core/store" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" @@ -13,12 +13,18 @@ import ( // migration includes: // // Addition of the new proposal expedited parameters that are set to 0 by default. -func MigrateStore(ctx sdk.Context, storeKey storetypes.StoreKey, cdc codec.BinaryCodec) error { - store := ctx.KVStore(storeKey) - paramsBz := store.Get(v4.ParamsKey) +func MigrateStore(ctx sdk.Context, storeService corestoretypes.KVStoreService, cdc codec.BinaryCodec) error { + store := storeService.OpenKVStore(ctx) + paramsBz, err := store.Get(v4.ParamsKey) + if err != nil { + return err + } var params govv1.Params - cdc.MustUnmarshal(paramsBz, ¶ms) + err = cdc.Unmarshal(paramsBz, ¶ms) + if err != nil { + return err + } defaultParams := govv1.DefaultParams() params.ExpeditedMinDeposit = defaultParams.ExpeditedMinDeposit diff --git a/x/gov/migrations/v5/store_test.go b/x/gov/migrations/v5/store_test.go index 24260871b283..e4e4ba683266 100644 --- a/x/gov/migrations/v5/store_test.go +++ b/x/gov/migrations/v5/store_test.go @@ -8,6 +8,7 @@ import ( storetypes "cosmossdk.io/store/types" + "github.com/cosmos/cosmos-sdk/runtime" "github.com/cosmos/cosmos-sdk/testutil" moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil" "github.com/cosmos/cosmos-sdk/x/bank" @@ -31,7 +32,8 @@ func TestMigrateStore(t *testing.T) { require.Equal(t, (*time.Duration)(nil), params.ExpeditedVotingPeriod) // Run migrations. - err := v5.MigrateStore(ctx, govKey, cdc) + storeService := runtime.NewKVStoreService(govKey) + err := v5.MigrateStore(ctx, storeService, cdc) require.NoError(t, err) // Check params diff --git a/x/gov/module.go b/x/gov/module.go index 1f46cab77d4e..d4a1e6f0949e 100644 --- a/x/gov/module.go +++ b/x/gov/module.go @@ -17,7 +17,7 @@ import ( "cosmossdk.io/core/appmodule" "cosmossdk.io/depinject" - store "cosmossdk.io/store/types" + store "cosmossdk.io/core/store" "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/client" @@ -170,7 +170,7 @@ type ModuleInputs struct { Config *modulev1.Module Cdc codec.Codec - Key *store.KVStoreKey + StoreService store.KVStoreService ModuleKey depinject.OwnModuleKey MsgServiceRouter baseapp.MessageRouter @@ -205,7 +205,7 @@ func ProvideModule(in ModuleInputs) ModuleOutputs { k := keeper.NewKeeper( in.Cdc, - in.Key, + in.StoreService, in.AccountKeeper, in.BankKeeper, in.StakingKeeper, @@ -316,7 +316,10 @@ func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, data json. // ExportGenesis returns the exported genesis state as raw bytes for the gov // module. func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.RawMessage { - gs := ExportGenesis(ctx, am.keeper) + gs, err := ExportGenesis(ctx, am.keeper) + if err != nil { + panic(err) + } return cdc.MustMarshalJSON(gs) } @@ -327,8 +330,7 @@ func (AppModule) ConsensusVersion() uint64 { return ConsensusVersion } // updates. func (am AppModule) EndBlock(ctx context.Context) error { c := sdk.UnwrapSDKContext(ctx) - EndBlocker(c, am.keeper) - return nil + return EndBlocker(c, am.keeper) } // AppModuleSimulation functions diff --git a/x/gov/simulation/operations.go b/x/gov/simulation/operations.go index 97a0e7734337..43ffaa313b9f 100644 --- a/x/gov/simulation/operations.go +++ b/x/gov/simulation/operations.go @@ -291,7 +291,8 @@ func simulateMsgSubmitProposal( // didntVote := whoVotes[numVotes:] whoVotes = whoVotes[:numVotes] - votingPeriod := k.GetParams(ctx).VotingPeriod + params, _ := k.GetParams(ctx) + votingPeriod := params.VotingPeriod fops := make([]simtypes.FutureOperation, numVotes+1) for i := 0; i < numVotes; i++ { @@ -556,7 +557,7 @@ func randomDeposit( return nil, true, nil // skip } - params := k.GetParams(ctx) + params, _ := k.GetParams(ctx) minDeposit := params.MinDeposit if expedited { minDeposit = params.ExpeditedMinDeposit @@ -596,7 +597,7 @@ func randomDeposit( // randomProposal func randomProposal(r *rand.Rand, k *keeper.Keeper, ctx sdk.Context) *v1.Proposal { - proposals := k.GetProposals(ctx) + proposals, _ := k.GetProposals(ctx) if len(proposals) == 0 { return nil } @@ -622,8 +623,8 @@ func randomProposalID(r *rand.Rand, k *keeper.Keeper, ctx sdk.Context, status v1 initialProposalID = proposalID } - proposal, ok := k.GetProposal(ctx, proposalID) - if !ok || proposal.Status != status { + proposal, err := k.GetProposal(ctx, proposalID) + if err != nil || proposal.Status != status { return proposalID, false } diff --git a/x/gov/simulation/operations_test.go b/x/gov/simulation/operations_test.go index 0e8419ba24f4..c545c8be8c59 100644 --- a/x/gov/simulation/operations_test.go +++ b/x/gov/simulation/operations_test.go @@ -212,7 +212,8 @@ func TestSimulateMsgCancelProposal(t *testing.T) { require.NoError(t, err) submitTime := ctx.BlockHeader().Time - depositPeriod := suite.GovKeeper.GetParams(ctx).MaxDepositPeriod + params, _ := suite.GovKeeper.GetParams(ctx) + depositPeriod := params.MaxDepositPeriod proposal, err := v1.NewProposal([]sdk.Msg{contentMsg}, 1, submitTime, submitTime.Add(*depositPeriod), "", "title", "summary", proposer, false) require.NoError(t, err) @@ -256,7 +257,8 @@ func TestSimulateMsgDeposit(t *testing.T) { require.NoError(t, err) submitTime := ctx.BlockHeader().Time - depositPeriod := suite.GovKeeper.GetParams(ctx).MaxDepositPeriod + params, _ := suite.GovKeeper.GetParams(ctx) + depositPeriod := params.MaxDepositPeriod proposal, err := v1.NewProposal([]sdk.Msg{contentMsg}, 1, submitTime, submitTime.Add(*depositPeriod), "", "text proposal", "description", sdk.AccAddress("cosmos1ghekyjucln7y67ntx7cf27m9dpuxxemn4c8g4r"), false) require.NoError(t, err) @@ -302,7 +304,8 @@ func TestSimulateMsgVote(t *testing.T) { require.NoError(t, err) submitTime := ctx.BlockHeader().Time - depositPeriod := suite.GovKeeper.GetParams(ctx).MaxDepositPeriod + params, _ := suite.GovKeeper.GetParams(ctx) + depositPeriod := params.MaxDepositPeriod proposal, err := v1.NewProposal([]sdk.Msg{contentMsg}, 1, submitTime, submitTime.Add(*depositPeriod), "", "text proposal", "description", sdk.AccAddress("cosmos1ghekyjucln7y67ntx7cf27m9dpuxxemn4c8g4r"), false) require.NoError(t, err) @@ -345,7 +348,8 @@ func TestSimulateMsgVoteWeighted(t *testing.T) { contentMsg, err := v1.NewLegacyContent(v1beta1.NewTextProposal("Test", "description"), govAcc) require.NoError(t, err) submitTime := ctx.BlockHeader().Time - depositPeriod := suite.GovKeeper.GetParams(ctx).MaxDepositPeriod + params, _ := suite.GovKeeper.GetParams(ctx) + depositPeriod := params.MaxDepositPeriod proposal, err := v1.NewProposal([]sdk.Msg{contentMsg}, 1, submitTime, submitTime.Add(*depositPeriod), "", "text proposal", "test", sdk.AccAddress("cosmos1ghekyjucln7y67ntx7cf27m9dpuxxemn4c8g4r"), false) require.NoError(t, err) diff --git a/x/gov/types/errors.go b/x/gov/types/errors.go index ae9142c92c0e..8920fccfdf64 100644 --- a/x/gov/types/errors.go +++ b/x/gov/types/errors.go @@ -27,4 +27,6 @@ var ( ErrNoDeposits = errors.Register(ModuleName, 19, "no deposits found") ErrVotingPeriodEnded = errors.Register(ModuleName, 20, "voting period already ended") ErrInvalidProposal = errors.Register(ModuleName, 21, "invalid proposal") + ErrDepositNotFound = errors.Register(ModuleName, 22, "deposit is not found") + ErrVoteNotFound = errors.Register(ModuleName, 23, "vote is not found") ) diff --git a/x/gov/types/expected_keepers.go b/x/gov/types/expected_keepers.go index 3588ee757a02..d171584455e0 100644 --- a/x/gov/types/expected_keepers.go +++ b/x/gov/types/expected_keepers.go @@ -66,11 +66,11 @@ type BankKeeper interface { // GovHooks event hooks for governance proposal object (noalias) type GovHooks interface { - AfterProposalSubmission(ctx sdk.Context, proposalID uint64) // Must be called after proposal is submitted - AfterProposalDeposit(ctx sdk.Context, proposalID uint64, depositorAddr sdk.AccAddress) // Must be called after a deposit is made - AfterProposalVote(ctx sdk.Context, proposalID uint64, voterAddr sdk.AccAddress) // Must be called after a vote on a proposal is cast - AfterProposalFailedMinDeposit(ctx sdk.Context, proposalID uint64) // Must be called when proposal fails to reach min deposit - AfterProposalVotingPeriodEnded(ctx sdk.Context, proposalID uint64) // Must be called when proposal's finishes it's voting period + AfterProposalSubmission(ctx context.Context, proposalID uint64) // Must be called after proposal is submitted + AfterProposalDeposit(ctx context.Context, proposalID uint64, depositorAddr sdk.AccAddress) // Must be called after a deposit is made + AfterProposalVote(ctx context.Context, proposalID uint64, voterAddr sdk.AccAddress) // Must be called after a vote on a proposal is cast + AfterProposalFailedMinDeposit(ctx context.Context, proposalID uint64) // Must be called when proposal fails to reach min deposit + AfterProposalVotingPeriodEnded(ctx context.Context, proposalID uint64) // Must be called when proposal's finishes it's voting period } type GovHooksWrapper struct{ GovHooks } diff --git a/x/gov/types/hooks.go b/x/gov/types/hooks.go index 0a361687d9d2..099e7d0da1db 100644 --- a/x/gov/types/hooks.go +++ b/x/gov/types/hooks.go @@ -1,6 +1,8 @@ package types import ( + "context" + sdk "github.com/cosmos/cosmos-sdk/types" ) @@ -13,31 +15,31 @@ func NewMultiGovHooks(hooks ...GovHooks) MultiGovHooks { return hooks } -func (h MultiGovHooks) AfterProposalSubmission(ctx sdk.Context, proposalID uint64) { +func (h MultiGovHooks) AfterProposalSubmission(ctx context.Context, proposalID uint64) { for i := range h { h[i].AfterProposalSubmission(ctx, proposalID) } } -func (h MultiGovHooks) AfterProposalDeposit(ctx sdk.Context, proposalID uint64, depositorAddr sdk.AccAddress) { +func (h MultiGovHooks) AfterProposalDeposit(ctx context.Context, proposalID uint64, depositorAddr sdk.AccAddress) { for i := range h { h[i].AfterProposalDeposit(ctx, proposalID, depositorAddr) } } -func (h MultiGovHooks) AfterProposalVote(ctx sdk.Context, proposalID uint64, voterAddr sdk.AccAddress) { +func (h MultiGovHooks) AfterProposalVote(ctx context.Context, proposalID uint64, voterAddr sdk.AccAddress) { for i := range h { h[i].AfterProposalVote(ctx, proposalID, voterAddr) } } -func (h MultiGovHooks) AfterProposalFailedMinDeposit(ctx sdk.Context, proposalID uint64) { +func (h MultiGovHooks) AfterProposalFailedMinDeposit(ctx context.Context, proposalID uint64) { for i := range h { h[i].AfterProposalFailedMinDeposit(ctx, proposalID) } } -func (h MultiGovHooks) AfterProposalVotingPeriodEnded(ctx sdk.Context, proposalID uint64) { +func (h MultiGovHooks) AfterProposalVotingPeriodEnded(ctx context.Context, proposalID uint64) { for i := range h { h[i].AfterProposalVotingPeriodEnded(ctx, proposalID) }