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

Add sudo and execute proposal types #730

Merged
merged 13 commits into from
Jan 24, 2022
5 changes: 3 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,13 @@
- Go 1.17 provides a much clearer go.mod file [\#679](https://github.com/CosmWasm/wasmd/pull/679) ([faddat](https://github.com/faddat))
- Autopin wasm code uploaded by gov proposal [\#726](https://github.com/CosmWasm/wasmd/pull/726) ([ethanfrey](https://github.com/ethanfrey))
- You must explicitly declare --no-admin on cli instantiate if that is what you want [\#727](https://github.com/CosmWasm/wasmd/pull/727) ([ethanfrey](https://github.com/ethanfrey))

- Add governance proposals for Wasm Execute and Sudo [\#730](https://github.com/CosmWasm/wasmd/pull/730) ([ethanfrey](https://github.com/ethanfrey))
- Remove unused run-as flag from Wasm Migrate proposals [\#730](https://github.com/CosmWasm/wasmd/pull/730) ([ethanfrey](https://github.com/ethanfrey))
- Expose wasm/Keeper.SetParams [\#732](https://github.com/CosmWasm/wasmd/pull/732) ([ethanfrey](https://github.com/ethanfrey))

[Full Changelog](https://github.com/CosmWasm/wasmd/compare/v0.22.0...v0.21.0)



## [v0.21.0](https://github.com/CosmWasm/wasmd/tree/v0.21.0) (2021-11-17)

[Full Changelog](https://github.com/CosmWasm/wasmd/compare/v0.21.0...v0.20.0)
Expand Down
48 changes: 45 additions & 3 deletions docs/proto/proto-docs.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,12 @@

- [cosmwasm/wasm/v1/proposal.proto](#cosmwasm/wasm/v1/proposal.proto)
- [ClearAdminProposal](#cosmwasm.wasm.v1.ClearAdminProposal)
- [ExecuteContractProposal](#cosmwasm.wasm.v1.ExecuteContractProposal)
- [InstantiateContractProposal](#cosmwasm.wasm.v1.InstantiateContractProposal)
- [MigrateContractProposal](#cosmwasm.wasm.v1.MigrateContractProposal)
- [PinCodesProposal](#cosmwasm.wasm.v1.PinCodesProposal)
- [StoreCodeProposal](#cosmwasm.wasm.v1.StoreCodeProposal)
- [SudoContractProposal](#cosmwasm.wasm.v1.SudoContractProposal)
- [UnpinCodesProposal](#cosmwasm.wasm.v1.UnpinCodesProposal)
- [UpdateAdminProposal](#cosmwasm.wasm.v1.UpdateAdminProposal)

Expand Down Expand Up @@ -658,6 +660,27 @@ contract.



<a name="cosmwasm.wasm.v1.ExecuteContractProposal"></a>

### ExecuteContractProposal
ExecuteContractProposal gov proposal content type to call execute on a
contract.


| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| `title` | [string](#string) | | Title is a short summary |
| `description` | [string](#string) | | Description is a human readable text |
| `run_as` | [string](#string) | | RunAs is the address that is passed to the contract's environment as sender |
| `contract` | [string](#string) | | Contract is the address of the smart contract |
| `msg` | [bytes](#bytes) | | Msg json encoded message to be passed to the contract as execute |
| `funds` | [cosmos.base.v1beta1.Coin](#cosmos.base.v1beta1.Coin) | repeated | Funds coins that are transferred to the contract on instantiation |






<a name="cosmwasm.wasm.v1.InstantiateContractProposal"></a>

### InstantiateContractProposal
Expand Down Expand Up @@ -690,10 +713,11 @@ MigrateContractProposal gov proposal content type to migrate a contract.
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| `title` | [string](#string) | | Title is a short summary |
| `description` | [string](#string) | | Description is a human readable text |
| `run_as` | [string](#string) | | RunAs is the address that is passed to the contract's environment as sender |
| `description` | [string](#string) | | Description is a human readable text

Note: skipping 3 as this was previously used for unneeded run_as |
| `contract` | [string](#string) | | Contract is the address of the smart contract |
| `code_id` | [uint64](#uint64) | | CodeID references the new WASM code |
| `code_id` | [uint64](#uint64) | | CodeID references the new WASM codesudo |
| `msg` | [bytes](#bytes) | | Msg json encoded message to be passed to the contract on migration |


Expand Down Expand Up @@ -738,6 +762,24 @@ StoreCodeProposal gov proposal content type to submit WASM code to the system



<a name="cosmwasm.wasm.v1.SudoContractProposal"></a>

### SudoContractProposal
SudoContractProposal gov proposal content type to call sudo on a contract.


| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| `title` | [string](#string) | | Title is a short summary |
| `description` | [string](#string) | | Description is a human readable text |
| `contract` | [string](#string) | | Contract is the address of the smart contract |
| `msg` | [bytes](#bytes) | | Msg json encoded message to be passed to the contract as sudo |






<a name="cosmwasm.wasm.v1.UnpinCodesProposal"></a>

### UnpinCodesProposal
Expand Down
38 changes: 35 additions & 3 deletions proto/cosmwasm/wasm/v1/proposal.proto
Original file line number Diff line number Diff line change
Expand Up @@ -56,16 +56,48 @@ message MigrateContractProposal {
string title = 1;
// Description is a human readable text
string description = 2;
// RunAs is the address that is passed to the contract's environment as sender
string run_as = 3;
// Note: skipping 3 as this was previously used for unneeded run_as

// Contract is the address of the smart contract
string contract = 4;
// CodeID references the new WASM code
// CodeID references the new WASM codesudo
uint64 code_id = 5 [ (gogoproto.customname) = "CodeID" ];
// Msg json encoded message to be passed to the contract on migration
bytes msg = 6 [ (gogoproto.casttype) = "RawContractMessage" ];
}

// SudoContractProposal gov proposal content type to call sudo on a contract.
message SudoContractProposal {
// Title is a short summary
string title = 1;
// Description is a human readable text
string description = 2;
// Contract is the address of the smart contract
string contract = 3;
// Msg json encoded message to be passed to the contract as sudo
bytes msg = 4 [ (gogoproto.casttype) = "RawContractMessage" ];
}

// ExecuteContractProposal gov proposal content type to call execute on a
// contract.
message ExecuteContractProposal {
// Title is a short summary
string title = 1;
// Description is a human readable text
string description = 2;
// RunAs is the address that is passed to the contract's environment as sender
string run_as = 3;
// Contract is the address of the smart contract
string contract = 4;
// Msg json encoded message to be passed to the contract as execute
bytes msg = 5 [ (gogoproto.casttype) = "RawContractMessage" ];
// Funds coins that are transferred to the contract on instantiation
repeated cosmos.base.v1beta1.Coin funds = 6 [
(gogoproto.nullable) = false,
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"
];
}

// UpdateAdminProposal gov proposal content type to set an admin for a contract.
message UpdateAdminProposal {
// Title is a short summary
Expand Down
9 changes: 5 additions & 4 deletions x/wasm/Governance.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,20 @@ a high-level, technical introduction meant to provide context before
looking into the code, or constructing proposals.

## Proposal Types
We have added 5 new wasm specific proposal types that cover the contract's live cycle and authorization:
We have added 9 new wasm specific proposal types that cover the contract's live cycle and authorization:

* `StoreCodeProposal` - upload a wasm binary
* `InstantiateContractProposal` - instantiate a wasm contract
* `MigrateContractProposal` - migrate a wasm contract to a new code version
* `SudoContractProposal` - call into the protected `sudo` entry point of a contract
* `ExecuteContractProposal` - execute a wasm contract as an arbitrary user
* `UpdateAdminProposal` - set a new admin for a contract
* `ClearAdminProposal` - clear admin for a contract to prevent further migrations
* `PinCodes` - pin the given code ids in cache. This trades memory for reduced startup time and lowers gas cost
* `UnpinCodes` - unpin the given code ids from the cache. This frees up memory and returns to standard speed and gas cost

For details see the proposal type [implementation](https://github.com/CosmWasm/wasmd/blob/master/x/wasm/types/proposal.go)

A wasm message but no proposal type:
* `ExecuteContract` - execute a command on a wasm contract

### Unit tests
[Proposal type validations](https://github.com/CosmWasm/wasmd/blob/master/x/wasm/types/proposal_test.go)

Expand Down
138 changes: 134 additions & 4 deletions x/wasm/client/cli/gov_tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,10 +181,79 @@ func ProposalMigrateContractCmd() *cobra.Command {
return err
}

proposalTitle, err := cmd.Flags().GetString(cli.FlagTitle)
if err != nil {
return fmt.Errorf("proposal title: %s", err)
}
proposalDescr, err := cmd.Flags().GetString(cli.FlagDescription)
if err != nil {
return fmt.Errorf("proposal description: %s", err)
}
depositArg, err := cmd.Flags().GetString(cli.FlagDeposit)
if err != nil {
return err
}
deposit, err := sdk.ParseCoinsNormalized(depositArg)
if err != nil {
return err
}

content := types.MigrateContractProposal{
Title: proposalTitle,
Description: proposalDescr,
Contract: src.Contract,
CodeID: src.CodeID,
Msg: src.Msg,
}

msg, err := govtypes.NewMsgSubmitProposal(&content, deposit, clientCtx.GetFromAddress())
if err != nil {
return err
}
if err = msg.ValidateBasic(); err != nil {
return err
}

return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
},
}

// proposal flags
cmd.Flags().String(cli.FlagTitle, "", "Title of proposal")
cmd.Flags().String(cli.FlagDescription, "", "Description of proposal")
cmd.Flags().String(cli.FlagDeposit, "", "Deposit of proposal")
cmd.Flags().String(cli.FlagProposal, "", "Proposal file path (if this path is given, other proposal flags are ignored)")
// type values must match the "ProposalHandler" "routes" in cli
cmd.Flags().String(flagProposalType, "", "Permission of proposal, types: store-code/instantiate/migrate/update-admin/clear-admin/text/parameter_change/software_upgrade")
return cmd
}

func ProposalExecuteContractCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "execute-contract [contract_addr_bech32] [json_encoded_migration_args]",
Short: "Submit a execute wasm contract proposal (run by any address)",
Args: cobra.ExactArgs(2),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientTxContext(cmd)
if err != nil {
return err
}

contract := args[0]
execMsg := []byte(args[1])
amountStr, err := cmd.Flags().GetString(flagAmount)
if err != nil {
return fmt.Errorf("amount: %s", err)
}
funds, err := sdk.ParseCoinsNormalized(amountStr)
if err != nil {
return fmt.Errorf("amount: %s", err)
}
runAs, err := cmd.Flags().GetString(flagRunAs)
if err != nil {
return fmt.Errorf("run-as: %s", err)
}

if len(runAs) == 0 {
return errors.New("run-as address is required")
}
Expand All @@ -205,13 +274,13 @@ func ProposalMigrateContractCmd() *cobra.Command {
return err
}

content := types.MigrateContractProposal{
content := types.ExecuteContractProposal{
Title: proposalTitle,
Description: proposalDescr,
Contract: src.Contract,
CodeID: src.CodeID,
Msg: src.Msg,
Contract: contract,
Msg: execMsg,
RunAs: runAs,
Funds: funds,
}

msg, err := govtypes.NewMsgSubmitProposal(&content, deposit, clientCtx.GetFromAddress())
Expand All @@ -226,6 +295,7 @@ func ProposalMigrateContractCmd() *cobra.Command {
},
}
cmd.Flags().String(flagRunAs, "", "The address that is passed as sender to the contract on proposal execution")
cmd.Flags().String(flagAmount, "", "Coins to send to the contract during instantiation")

// proposal flags
cmd.Flags().String(cli.FlagTitle, "", "Title of proposal")
Expand All @@ -237,6 +307,66 @@ func ProposalMigrateContractCmd() *cobra.Command {
return cmd
}

func ProposalSudoContractCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "sudo-contract [contract_addr_bech32] [json_encoded_migration_args]",
Short: "Submit a sudo wasm contract proposal (to call privileged commands)",
Args: cobra.ExactArgs(2),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientTxContext(cmd)
if err != nil {
return err
}

contract := args[0]
sudoMsg := []byte(args[1])

proposalTitle, err := cmd.Flags().GetString(cli.FlagTitle)
if err != nil {
return fmt.Errorf("proposal title: %s", err)
}
proposalDescr, err := cmd.Flags().GetString(cli.FlagDescription)
if err != nil {
return fmt.Errorf("proposal description: %s", err)
}
depositArg, err := cmd.Flags().GetString(cli.FlagDeposit)
if err != nil {
return err
}
deposit, err := sdk.ParseCoinsNormalized(depositArg)
if err != nil {
return err
}

content := types.SudoContractProposal{
Title: proposalTitle,
Description: proposalDescr,
Contract: contract,
Msg: sudoMsg,
}

msg, err := govtypes.NewMsgSubmitProposal(&content, deposit, clientCtx.GetFromAddress())
if err != nil {
return err
}
if err = msg.ValidateBasic(); err != nil {
return err
}

return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
},
}

// proposal flagsExecute
cmd.Flags().String(cli.FlagTitle, "", "Title of proposal")
cmd.Flags().String(cli.FlagDescription, "", "Description of proposal")
cmd.Flags().String(cli.FlagDeposit, "", "Deposit of proposal")
cmd.Flags().String(cli.FlagProposal, "", "Proposal file path (if this path is given, other proposal flags are ignored)")
// type values must match the "ProposalHandler" "routes" in cli
cmd.Flags().String(flagProposalType, "", "Permission of proposal, types: store-code/instantiate/migrate/update-admin/clear-admin/text/parameter_change/software_upgrade")
return cmd
}

func ProposalUpdateContractAdminCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "set-contract-admin [contract_addr_bech32] [new_admin_addr_bech32]",
Expand Down
2 changes: 2 additions & 0 deletions x/wasm/client/proposal_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ var ProposalHandlers = []govclient.ProposalHandler{
govclient.NewProposalHandler(cli.ProposalStoreCodeCmd, rest.StoreCodeProposalHandler),
govclient.NewProposalHandler(cli.ProposalInstantiateContractCmd, rest.InstantiateProposalHandler),
govclient.NewProposalHandler(cli.ProposalMigrateContractCmd, rest.MigrateProposalHandler),
govclient.NewProposalHandler(cli.ProposalExecuteContractCmd, rest.ExecuteProposalHandler),
govclient.NewProposalHandler(cli.ProposalSudoContractCmd, rest.SudoProposalHandler),
govclient.NewProposalHandler(cli.ProposalUpdateContractAdminCmd, rest.UpdateContractAdminProposalHandler),
govclient.NewProposalHandler(cli.ProposalClearContractAdminCmd, rest.ClearContractAdminProposalHandler),
govclient.NewProposalHandler(cli.ProposalPinCodesCmd, rest.PinCodeProposalHandler),
Expand Down
Loading