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 WasmMsg::Migrate variant #768

Merged
merged 5 commits into from
Feb 5, 2021
Merged
Show file tree
Hide file tree
Changes from all 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
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,16 @@ and this project adheres to
- contracts: added new `ibc-reflect` contract that receives channels and assigns
each an account to redispatch. Similar idea to ICS27/Interchain Accounts (but
different implementation) ([#692], [#711], [#714])
- cosmwasm-std: Added new `WasmMsg::Migrate` variant that allows one contract
(eg. multisig) be the admin and migrate another contract ([#768])

[#692]: https://github.com/CosmWasm/cosmwasm/issues/692
[#706]: https://github.com/CosmWasm/cosmwasm/pull/706
[#710]: https://github.com/CosmWasm/cosmwasm/pull/710
[#711]: https://github.com/CosmWasm/cosmwasm/pull/711
[#714]: https://github.com/CosmWasm/cosmwasm/pull/714
[#716]: https://github.com/CosmWasm/cosmwasm/pull/716
[#768]: https://github.com/CosmWasm/cosmwasm/pull/768

### Changed

Expand Down
36 changes: 36 additions & 0 deletions contracts/ibc-reflect-send/schema/handle_msg.json
Original file line number Diff line number Diff line change
Expand Up @@ -584,6 +584,42 @@
}
}
}
},
{
"description": "Migrates a given contracts to use new wasm code. Passes a MigrateMsg to allow us to customize behavior.\n\nOnly the contract admin (as defined in wasmd), if any, is able to make this call.\n\nThis is translated to a [MsgMigrateContract](https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto#L86-L96). `sender` is automatically filled with the current contract's address.",
"type": "object",
"required": [
"migrate"
],
"properties": {
"migrate": {
"type": "object",
"required": [
"contract_addr",
"msg",
"new_code_id"
],
"properties": {
"contract_addr": {
"$ref": "#/definitions/HumanAddr"
},
"msg": {
"description": "msg is the json-encoded MigrateMsg struct that will be passed to the new code",
"allOf": [
{
"$ref": "#/definitions/Binary"
}
]
},
"new_code_id": {
"description": "the code_id of the new logic to place in the given contract",
"type": "integer",
"format": "uint64",
"minimum": 0.0
}
}
}
}
}
]
}
Expand Down
36 changes: 36 additions & 0 deletions contracts/ibc-reflect-send/schema/packet_msg.json
Original file line number Diff line number Diff line change
Expand Up @@ -538,6 +538,42 @@
}
}
}
},
{
"description": "Migrates a given contracts to use new wasm code. Passes a MigrateMsg to allow us to customize behavior.\n\nOnly the contract admin (as defined in wasmd), if any, is able to make this call.\n\nThis is translated to a [MsgMigrateContract](https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto#L86-L96). `sender` is automatically filled with the current contract's address.",
"type": "object",
"required": [
"migrate"
],
"properties": {
"migrate": {
"type": "object",
"required": [
"contract_addr",
"msg",
"new_code_id"
],
"properties": {
"contract_addr": {
"$ref": "#/definitions/HumanAddr"
},
"msg": {
"description": "msg is the json-encoded MigrateMsg struct that will be passed to the new code",
"allOf": [
{
"$ref": "#/definitions/Binary"
}
]
},
"new_code_id": {
"description": "the code_id of the new logic to place in the given contract",
"type": "integer",
"format": "uint64",
"minimum": 0.0
}
}
}
}
}
]
}
Expand Down
36 changes: 36 additions & 0 deletions contracts/ibc-reflect/schema/packet_msg.json
Original file line number Diff line number Diff line change
Expand Up @@ -537,6 +537,42 @@
}
}
}
},
{
"description": "Migrates a given contracts to use new wasm code. Passes a MigrateMsg to allow us to customize behavior.\n\nOnly the contract admin (as defined in wasmd), if any, is able to make this call.\n\nThis is translated to a [MsgMigrateContract](https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto#L86-L96). `sender` is automatically filled with the current contract's address.",
"type": "object",
"required": [
"migrate"
],
"properties": {
"migrate": {
"type": "object",
"required": [
"contract_addr",
"msg",
"new_code_id"
],
"properties": {
"contract_addr": {
"$ref": "#/definitions/HumanAddr"
},
"msg": {
"description": "msg is the json-encoded MigrateMsg struct that will be passed to the new code",
"allOf": [
{
"$ref": "#/definitions/Binary"
}
]
},
"new_code_id": {
"description": "the code_id of the new logic to place in the given contract",
"type": "integer",
"format": "uint64",
"minimum": 0.0
}
}
}
}
}
]
}
Expand Down
36 changes: 36 additions & 0 deletions contracts/reflect/schema/handle_msg.json
Original file line number Diff line number Diff line change
Expand Up @@ -557,6 +557,42 @@
}
}
}
},
{
"description": "Migrates a given contracts to use new wasm code. Passes a MigrateMsg to allow us to customize behavior.\n\nOnly the contract admin (as defined in wasmd), if any, is able to make this call.\n\nThis is translated to a [MsgMigrateContract](https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto#L86-L96). `sender` is automatically filled with the current contract's address.",
"type": "object",
"required": [
"migrate"
],
"properties": {
"migrate": {
"type": "object",
"required": [
"contract_addr",
"msg",
"new_code_id"
],
"properties": {
"contract_addr": {
"$ref": "#/definitions/HumanAddr"
},
"msg": {
"description": "msg is the json-encoded MigrateMsg struct that will be passed to the new code",
"allOf": [
{
"$ref": "#/definitions/Binary"
}
]
},
"new_code_id": {
"description": "the code_id of the new logic to place in the given contract",
"type": "integer",
"format": "uint64",
"minimum": 0.0
}
}
}
}
}
]
}
Expand Down
36 changes: 36 additions & 0 deletions contracts/reflect/schema/handle_response_for__custom_msg.json
Original file line number Diff line number Diff line change
Expand Up @@ -560,6 +560,42 @@
}
}
}
},
{
"description": "Migrates a given contracts to use new wasm code. Passes a MigrateMsg to allow us to customize behavior.\n\nOnly the contract admin (as defined in wasmd), if any, is able to make this call.\n\nThis is translated to a [MsgMigrateContract](https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto#L86-L96). `sender` is automatically filled with the current contract's address.",
"type": "object",
"required": [
"migrate"
],
"properties": {
"migrate": {
"type": "object",
"required": [
"contract_addr",
"msg",
"new_code_id"
],
"properties": {
"contract_addr": {
"$ref": "#/definitions/HumanAddr"
},
"msg": {
"description": "msg is the json-encoded MigrateMsg struct that will be passed to the new code",
"allOf": [
{
"$ref": "#/definitions/Binary"
}
]
},
"new_code_id": {
"description": "the code_id of the new logic to place in the given contract",
"type": "integer",
"format": "uint64",
"minimum": 0.0
}
}
}
}
}
]
}
Expand Down
36 changes: 36 additions & 0 deletions packages/std/schema/cosmos_msg.json
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,42 @@
}
}
}
},
{
"description": "Migrates a given contracts to use new wasm code. Passes a MigrateMsg to allow us to customize behavior.\n\nOnly the contract admin (as defined in wasmd), if any, is able to make this call.\n\nThis is translated to a [MsgMigrateContract](https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto#L86-L96). `sender` is automatically filled with the current contract's address.",
"type": "object",
"required": [
"migrate"
],
"properties": {
"migrate": {
"type": "object",
"required": [
"contract_addr",
"msg",
"new_code_id"
],
"properties": {
"contract_addr": {
"$ref": "#/definitions/HumanAddr"
},
"msg": {
"description": "msg is the json-encoded MigrateMsg struct that will be passed to the new code",
"allOf": [
{
"$ref": "#/definitions/Binary"
}
]
},
"new_code_id": {
"description": "the code_id of the new logic to place in the given contract",
"type": "integer",
"format": "uint64",
"minimum": 0.0
}
}
}
}
}
]
}
Expand Down
2 changes: 2 additions & 0 deletions packages/std/src/ibc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use crate::types::Empty;

/// These are messages in the IBC lifecycle. Only usable by IBC-enabled contracts
/// (contracts that directly speak the IBC protocol via 6 entry points)
#[non_exhaustive]
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum IbcMsg {
Expand Down Expand Up @@ -60,6 +61,7 @@ pub enum IbcMsg {

/// These are queries to the various IBC modules to see the state of the contract's
/// IBC connection. These will return errors if the contract is not "ibc enabled"
#[non_exhaustive]
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum IbcQuery {
Expand Down
4 changes: 4 additions & 0 deletions packages/std/src/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use crate::ibc::IbcQuery;
use crate::math::Decimal;
use crate::types::Empty;

#[non_exhaustive]
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum QueryRequest<C: CustomQuery> {
Expand All @@ -31,6 +32,7 @@ pub enum QueryRequest<C: CustomQuery> {
Wasm(WasmQuery),
}

#[non_exhaustive]
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum BankQuery {
Expand Down Expand Up @@ -66,6 +68,7 @@ pub trait CustomQuery: Serialize {}

impl CustomQuery for Empty {}

#[non_exhaustive]
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum WasmQuery {
Expand Down Expand Up @@ -140,6 +143,7 @@ pub struct StargateResponse {
pub response: Binary,
}

#[non_exhaustive]
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum StakingQuery {
Expand Down
18 changes: 18 additions & 0 deletions packages/std/src/results/cosmos_msg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use crate::ibc::IbcMsg;
use crate::serde::to_binary;
use crate::types::Empty;

#[non_exhaustive]
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
#[serde(rename_all = "snake_case")]
// See https://github.com/serde-rs/serde/issues/1296 why we cannot add De-Serialize trait bounds to T
Expand Down Expand Up @@ -38,6 +39,7 @@ where
/// The message types of the bank module.
///
/// See https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/bank/v1beta1/tx.proto
#[non_exhaustive]
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum BankMsg {
Expand All @@ -54,6 +56,7 @@ pub enum BankMsg {
/// The message types of the staking module.
///
/// See https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto
#[non_exhaustive]
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum StakingMsg {
Expand Down Expand Up @@ -84,6 +87,7 @@ pub enum StakingMsg {
/// The message types of the wasm module.
///
/// See https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto
#[non_exhaustive]
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum WasmMsg {
Expand All @@ -109,6 +113,20 @@ pub enum WasmMsg {
/// optional human-readbale label for the contract
label: Option<String>,
},
/// Migrates a given contracts to use new wasm code. Passes a MigrateMsg to allow us to
/// customize behavior.
///
/// Only the contract admin (as defined in wasmd), if any, is able to make this call.
///
/// This is translated to a [MsgMigrateContract](https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto#L86-L96).
/// `sender` is automatically filled with the current contract's address.
Migrate {
contract_addr: HumanAddr,
/// the code_id of the new logic to place in the given contract
new_code_id: u64,
/// msg is the json-encoded MigrateMsg struct that will be passed to the new code
msg: Binary,
},
Copy link
Member

Choose a reason for hiding this comment

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

This is by the way a breaking change as the enum is not #[non_exhaustive]. If we ever want to add new cases in 1.x, we should make it #[non_exhaustive].

Copy link
Member Author

Choose a reason for hiding this comment

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

You mean WasmMsg? (Which I think is pretty final, we are just finally supporting a feature we added in 0.9).

Or CosmosMsg in general, which definitely will expand sometime. I guess I could just add this to all the types here

Copy link
Member

Choose a reason for hiding this comment

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

This WasmMsg just brought up the topic. I mean CosmosMsg and all its sub-messages. It is just too easy to forget one type, or require a v2 of an existing type later on. If we need to make a CosmWasm 2.0, just because we did not write #[non_exhaustive] and use fallback cases in the match, it would be pretty annoying. I guess we do not even match those as they are decoded in Go directly from JSON.

Copy link
Member Author

Choose a reason for hiding this comment

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

Huh, I made them non_exhaustive in two commits, and assumed some code would break, at such as places like

match &request {
QueryRequest::Bank(bank_query) => self.bank.query(bank_query),
QueryRequest::Custom(custom_query) => (*self.custom_handler)(custom_query),
QueryRequest::Staking(staking_query) => self.staking.query(staking_query),
QueryRequest::Wasm(msg) => self.wasm.query(msg),
#[cfg(feature = "stargate")]
QueryRequest::Stargate { .. } => SystemResult::Err(SystemError::UnsupportedRequest {
kind: "Stargate".to_string(),
}),
#[cfg(feature = "stargate")]
QueryRequest::Ibc(_) => SystemResult::Err(SystemError::UnsupportedRequest {
kind: "Ibc".to_string(),
}),
}
but tests keep working. Not sure what this does in the end

Copy link
Member

@webmaster128 webmaster128 Feb 5, 2021

Choose a reason for hiding this comment

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

This is a surprise I also hit recently. Rust is too clever: crate-internal you always must mach all cases. Clippy also marks fallback as dead code when all cases are matched. Crate-external, you always need a fallback case.

}

/// Shortcut helper as the construction of WasmMsg::Instantiate can be quite verbose in contract code
Expand Down