Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(x/gov): limit execution in gov #20348

Merged
merged 24 commits into from
Jun 12, 2024
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
209 changes: 136 additions & 73 deletions api/cosmos/gov/v1/gov.pulsar.go

Large diffs are not rendered by default.

14 changes: 5 additions & 9 deletions x/accounts/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ require (
cosmossdk.io/collections v0.4.0
cosmossdk.io/core v0.12.1-0.20231114100755-569e3ff6a0d7
cosmossdk.io/depinject v1.0.0-alpha.4
cosmossdk.io/x/bank v0.0.0-20240226161501-23359a0b6d91
cosmossdk.io/x/tx v0.13.3
github.com/cosmos/cosmos-sdk v0.51.0
github.com/cosmos/gogoproto v1.4.12
Expand All @@ -17,23 +18,16 @@ require (
google.golang.org/protobuf v1.34.1
)

require cosmossdk.io/x/consensus v0.0.0-00010101000000-000000000000 // indirect

require (
cosmossdk.io/log v1.3.1 // indirect
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
go.opencensus.io v0.24.0 // indirect
)

require (
buf.build/gen/go/cometbft/cometbft/protocolbuffers/go v1.34.1-20240312114316-c0d3497e35d6.1 // indirect
buf.build/gen/go/cosmos/gogo-proto/protocolbuffers/go v1.34.1-20240130113600-88ef6483f90f.1 // indirect
cosmossdk.io/errors v1.0.1 // indirect
cosmossdk.io/log v1.3.1 // indirect
cosmossdk.io/math v1.3.0
cosmossdk.io/store v1.1.1-0.20240418092142-896cdf1971bc // indirect
cosmossdk.io/x/accounts/defaults/lockup v0.0.0-20240417181816-5e7aae0db1f5
cosmossdk.io/x/auth v0.0.0-00010101000000-000000000000 // indirect
cosmossdk.io/x/bank v0.0.0-20240226161501-23359a0b6d91
cosmossdk.io/x/consensus v0.0.0-00010101000000-000000000000 // indirect
cosmossdk.io/x/staking v0.0.0-00010101000000-000000000000 // indirect
filippo.io/edwards25519 v1.1.0 // indirect
github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect
Expand Down Expand Up @@ -99,6 +93,7 @@ require (
github.com/hashicorp/go-metrics v0.5.3 // indirect
github.com/hashicorp/go-plugin v1.6.1 // indirect
github.com/hashicorp/golang-lru v1.0.2 // indirect
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/hashicorp/yamux v0.1.1 // indirect
github.com/hdevalence/ed25519consensus v0.2.0 // indirect
Expand Down Expand Up @@ -151,6 +146,7 @@ require (
gitlab.com/yawning/secp256k1-voi v0.0.0-20230925100816-f2616030848b // indirect
gitlab.com/yawning/tuplehash v0.0.0-20230713102510-df83abbf9a02 // indirect
go.etcd.io/bbolt v1.4.0-alpha.0.0.20240404170359-43604f3112c5 // indirect
go.opencensus.io v0.24.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/crypto v0.23.0 // indirect
golang.org/x/exp v0.0.0-20240531132922-fd00a4e0eefc // indirect
Expand Down
1 change: 1 addition & 0 deletions x/gov/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
* [#18762](https://github.com/cosmos/cosmos-sdk/pull/18762) Add multiple choice proposals.
* [#18856](https://github.com/cosmos/cosmos-sdk/pull/18856) Add `ProposalCancelMaxPeriod` parameters.
* [#19167](https://github.com/cosmos/cosmos-sdk/pull/19167) Add `YesQuorum` parameter.
* [#20348](https://github.com/cosmos/cosmos-sdk/pull/20348) Limit gov execution of proposals to a max gas limit. The limit was added to parameters and can be modified. With this version the default is set to 10 million gas. Before it was infinite gas.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a comma for better readability.

- With this version the default is set to 10 million gas.
+ With this version, the default is set to 10 million gas.
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
* [#20348](https://github.com/cosmos/cosmos-sdk/pull/20348) Limit gov execution of proposals to a max gas limit. The limit was added to parameters and can be modified. With this version the default is set to 10 million gas. Before it was infinite gas.
* [#20348](https://github.com/cosmos/cosmos-sdk/pull/20348) Limit gov execution of proposals to a max gas limit. The limit was added to parameters and can be modified. With this version, the default is set to 10 million gas. Before it was infinite gas.
Tools
LanguageTool

[typographical] ~58-~58: It appears that a comma is missing. (DURING_THAT_TIME_COMMA)
Context: ...rameters and can be modified. With this version the default is set to 10 million gas. B...


[grammar] ~58-~58: After the number ‘10’, use a plural noun. Did you mean “gases”, “gasses”? (CD_NNU)
Context: ...ersion the default is set to 10 million gas. Before it was infinite gas. ### Clien...


Correct the pluralization for grammatical accuracy.

- Before it was infinite gas.
+ Before it was an infinite amount of gas.
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
* [#20348](https://github.com/cosmos/cosmos-sdk/pull/20348) Limit gov execution of proposals to a max gas limit. The limit was added to parameters and can be modified. With this version the default is set to 10 million gas. Before it was infinite gas.
* [#20348](https://github.com/cosmos/cosmos-sdk/pull/20348) Limit gov execution of proposals to a max gas limit. The limit was added to parameters and can be modified. With this version the default is set to 10 million gas. Before it was an infinite amount of gas.
Tools
LanguageTool

[typographical] ~58-~58: It appears that a comma is missing. (DURING_THAT_TIME_COMMA)
Context: ...rameters and can be modified. With this version the default is set to 10 million gas. B...


[grammar] ~58-~58: After the number ‘10’, use a plural noun. Did you mean “gases”, “gasses”? (CD_NNU)
Context: ...ersion the default is set to 10 million gas. Before it was infinite gas. ### Clien...


Refine the changelog entry for better clarity and correctness.

- * [#20348](https://github.com/cosmos/cosmos-sdk/pull/20348) Limit gov execution of proposals to a max gas limit. The limit was added to parameters and can be modified. With this version the default is set to 10 million gas. Before it was infinite gas.
+ * [#20348](https://github.com/cosmos/cosmos-sdk/pull/20348) Introduce a configurable maximum gas limit for governance proposal execution, enhancing control over resource usage. The default limit is now set to 10 million gas units, replacing the previous infinite limit.
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
* [#20348](https://github.com/cosmos/cosmos-sdk/pull/20348) Limit gov execution of proposals to a max gas limit. The limit was added to parameters and can be modified. With this version the default is set to 10 million gas. Before it was infinite gas.
* [#20348](https://github.com/cosmos/cosmos-sdk/pull/20348) Introduce a configurable maximum gas limit for governance proposal execution, enhancing control over resource usage. The default limit is now set to 10 million gas units, replacing the previous infinite limit.
Tools
LanguageTool

[typographical] ~58-~58: It appears that a comma is missing. (DURING_THAT_TIME_COMMA)
Context: ...rameters and can be modified. With this version the default is set to 10 million gas. B...


[grammar] ~58-~58: After the number ‘10’, use a plural noun. Did you mean “gases”, “gasses”? (CD_NNU)
Context: ...ersion the default is set to 10 million gas. Before it was infinite gas. ### Clien...


### Client Breaking Changes

Expand Down
6 changes: 6 additions & 0 deletions x/gov/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,12 @@ There are three parameters that define if the deposit of a proposal should be bu

> Note: These parameters are modifiable via governance.

#### Execution

Execution is the process of executing the messages contained in a proposal. The execution phase will commence after the proposal has been accepted by the network. The messages contained in the proposal will be executed in the order they were submitted.

Execution has a upper limit on how much gas can be consumed in a single block. This limit is defined by the `ProposalExecutionGas` parameter.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct the article usage for better grammatical accuracy.

- Execution has a upper limit on how much gas can be consumed in a single block.
+ Execution has an upper limit on how much gas can be consumed in a single block.
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
Execution has a upper limit on how much gas can be consumed in a single block. This limit is defined by the `ProposalExecutionGas` parameter.
Execution has an upper limit on how much gas can be consumed in a single block. This limit is defined by the `ProposalExecutionGas` parameter.
Tools
LanguageTool

[misspelling] ~285-~285: Use “an” instead of ‘a’ if the following word starts with a vowel sound, e.g. ‘an article’, ‘an hour’.
Context: ...der they were submitted. Execution has a upper limit on how much gas can be cons...


## State

### Constitution
Expand Down
4 changes: 2 additions & 2 deletions x/gov/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ require (
cosmossdk.io/math v1.3.0
cosmossdk.io/store v1.1.1-0.20240418092142-896cdf1971bc
cosmossdk.io/x/accounts v0.0.0-20240226161501-23359a0b6d91 // indirect
cosmossdk.io/x/auth v0.0.0-00010101000000-000000000000
cosmossdk.io/x/bank v0.0.0-20240226161501-23359a0b6d91
cosmossdk.io/x/consensus v0.0.0-00010101000000-000000000000 // indirect
cosmossdk.io/x/protocolpool v0.0.0-20230925135524-a1bc045b3190
cosmossdk.io/x/staking v0.0.0-00010101000000-000000000000
github.com/chzyer/readline v1.5.1
Expand All @@ -39,8 +41,6 @@ require (
require (
buf.build/gen/go/cometbft/cometbft/protocolbuffers/go v1.34.1-20240312114316-c0d3497e35d6.1 // indirect
cosmossdk.io/x/accounts/defaults/lockup v0.0.0-20240417181816-5e7aae0db1f5 // indirect
cosmossdk.io/x/auth v0.0.0-00010101000000-000000000000
cosmossdk.io/x/consensus v0.0.0-00010101000000-000000000000 // indirect
cosmossdk.io/x/tx v0.13.3 // indirect
filippo.io/edwards25519 v1.1.0 // indirect
github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect
Expand Down
40 changes: 23 additions & 17 deletions x/gov/keeper/abci.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (

"github.com/cosmos/cosmos-sdk/telemetry"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
)

// EndBlocker is called every block.
Expand All @@ -35,6 +36,11 @@ func (k Keeper) EndBlocker(ctx context.Context) error {
return err
}

params, err := k.Params.Get(ctx)
Dismissed Show dismissed Hide dismissed
if err != nil {
return err
}

for _, prop := range inactiveProps {
proposal, err := k.Proposals.Get(ctx, prop.Key.K2())
if err != nil {
Expand All @@ -61,10 +67,6 @@ func (k Keeper) EndBlocker(ctx context.Context) error {
return err
}

params, err := k.Params.Get(ctx)
if err != nil {
return err
}
if !params.BurnProposalDepositPrevote {
err = k.RefundAndDeleteDeposits(ctx, proposal.Id) // refund deposit if proposal got removed without getting 100% of the proposal
} else {
Expand All @@ -77,7 +79,7 @@ func (k Keeper) EndBlocker(ctx context.Context) error {

// called when proposal become inactive
// call hook when proposal become inactive
if err := k.BranchService.Execute(ctx, func(ctx context.Context) error {
if err = k.BranchService.Execute(ctx, func(ctx context.Context) error {
return k.Hooks().AfterProposalFailedMinDeposit(ctx, proposal.Id)
}); err != nil {
// purposely ignoring the error here not to halt the chain if the hook fails
Expand Down Expand Up @@ -193,16 +195,10 @@ func (k Keeper) EndBlocker(ctx context.Context) error {
// Messages may mutate state thus we use a cached context. If one of
// the handlers fails, no state mutation is written and the error
// message is logged.
if err := k.BranchService.Execute(ctx, func(ctx context.Context) error {
_, err = k.BranchService.ExecuteWithGasLimit(ctx, params.ProposalExecutionGas, func(ctx context.Context) error {
// execute all messages
for idx, msg = range messages {
if _, err := safeExecuteHandler(ctx, msg, k.MsgRouterService); err != nil {
// `idx` and `err` are populated with the msg index and error.
proposal.Status = v1.StatusFailed
proposal.FailedReason = err.Error()
tagValue = types.AttributeValueProposalFailed
logMsg = fmt.Sprintf("passed, but msg %d (%s) failed on execution: %s", idx, sdk.MsgTypeURL(msg), err)

return err
}
}
Expand All @@ -212,7 +208,21 @@ func (k Keeper) EndBlocker(ctx context.Context) error {
logMsg = "passed"

return nil
}); err != nil {
})
if err != nil {
// update proposal if error is out of gas
if errors.Is(err, sdkerrors.ErrOutOfGas) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

problem is branch service implementation of stf doesn't return this error

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should it be in all cases we set the proposal to fail? if not then we need to see how to make this work correctly

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was this solved?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't think so yet

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pushed what i think you mean, not sure where to store the proposal idx

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we need to remove L214-L219 and make the error log more generic (as it can be out of gas or proposal execution error (at handling)). As it is only used in the log, let's skip it?

proposal.Status = v1.StatusFailed
proposal.FailedReason = err.Error()
tagValue = types.AttributeValueProposalFailed
logMsg = "passed proposal failed due to out of gas"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a break missing or this is overwritten in L224.
Status, FailedReason and tagValue are the same as for other errors. Would it make sense to move the error check below and have an if/else for the logMsg only?

Is there a way for people to find out the required gas amount? If the original error msg contains this information it feels like the better choice.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That whole if condition above should be removed (L214-L219)
Given that we cannot know if it is out of gas or execution error (or anything else).
Imho, the log message should stay generic.

}
// `idx` and `err` are populated with the msg index and error.
proposal.Status = v1.StatusFailed
proposal.FailedReason = err.Error()
tagValue = types.AttributeValueProposalFailed
logMsg = fmt.Sprintf("passed, but msg %d (%s) failed on execution: %s", idx, sdk.MsgTypeURL(msg), err)

break // We do not anything with the error. Returning an error halts the chain, and proposal struct is already updated.
}
case !burnDeposits && (proposal.ProposalType == v1.ProposalType_PROPOSAL_TYPE_EXPEDITED ||
Expand All @@ -222,10 +232,6 @@ func (k Keeper) EndBlocker(ctx context.Context) error {
// once the regular voting period expires again, the tally is repeated
// according to the regular proposal rules.
proposal.ProposalType = v1.ProposalType_PROPOSAL_TYPE_STANDARD
params, err := k.Params.Get(ctx)
if err != nil {
return err
}
endTime := proposal.VotingStartTime.Add(*params.VotingPeriod)
proposal.VotingEndTime = &endTime

Expand Down
3 changes: 2 additions & 1 deletion x/gov/migrations/v6/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (

var votingPeriodProposalKeyPrefix = collections.NewPrefix(4) // VotingPeriodProposalKeyPrefix stores which proposals are on voting period.

// MigrateStore performs in-place store migrations from v5 (v0.50) to v6 (v0.51). The
// MigrateStore performs in-place store migrations from v5 (v0.50) to v6 (v0.52). The
// migration includes:
//
// Addition of new field in params to store types of proposals that can be submitted.
Expand Down Expand Up @@ -56,6 +56,7 @@ func MigrateStore(ctx context.Context, storeService corestoretypes.KVStoreServic
govParams.OptimisticAuthorizedAddresses = defaultParams.OptimisticAuthorizedAddresses
govParams.OptimisticRejectedThreshold = defaultParams.OptimisticRejectedThreshold
govParams.ProposalCancelMaxPeriod = defaultParams.ProposalCancelMaxPeriod
govParams.ProposalExecutionGas = defaultParams.ProposalExecutionGas
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍


return paramsCollection.Set(ctx, govParams)
}
4 changes: 3 additions & 1 deletion x/gov/proto/cosmos/gov/v1/gov.proto
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,8 @@ message Params {
// Minimum percentage of total stake needed to vote for a result to be
// considered valid for an expedited proposal.
string expedited_quorum = 21 [(cosmos_proto.scalar) = "cosmos.Dec", (cosmos_proto.field_added_in) = "x/gov v1.0.0"];

uint64 proposal_execution_gas = 22 [(cosmos_proto.field_added_in) = "x/gov v0.2.0"];
}

// MessageBasedParams defines the parameters of specific messages in a proposal.
Expand All @@ -365,4 +367,4 @@ message MessageBasedParams {

// Minimum value of Veto votes to Total votes ratio for proposal to be vetoed.
string veto_threshold = 4 [(cosmos_proto.scalar) = "cosmos.Dec"];
}
}
1 change: 1 addition & 0 deletions x/gov/simulation/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ func RandomizedGenState(simState *module.SimulationState) {
minDepositRatio.String(),
optimisticRejectedThreshold.String(),
[]string{},
10_000_000,
),
)

Expand Down
Loading
Loading