Skip to content

Commit 13a04e2

Browse files
authored
Merge pull request CosmWasm#1232 from CosmWasm/SubMsgResult
Create dedicated SubMsgResult
2 parents 84ecdd3 + e6c14b2 commit 13a04e2

16 files changed

+294
-30
lines changed

CHANGELOG.md

+9
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,15 @@ and this project adheres to
66

77
## [Unreleased]
88

9+
### Changed
10+
11+
- cosmwasm-std: Change type of `Reply::result` from `ContractResult` to the new
12+
`SubMsgResult`. Both types are equal when serialized but `ContractResult` is
13+
documented to be the result of a contract execution, which is not the case
14+
here. ([#1232])
15+
16+
[#1232]: https://github.com/CosmWasm/cosmwasm/pull/1232
17+
918
## [1.0.0-beta5] - 2022-02-08
1019

1120
### Changed

MIGRATING.md

+18
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,24 @@ major releases of `cosmwasm`. Note that you can also view the
3333
deps.storage.set(b"foo", b"bar");
3434
```
3535

36+
- Replace `ContractResult` with `SubMsgResult` in `Reply` handling:
37+
38+
```diff
39+
@@ -35,10 +35,10 @@ pub fn instantiate(
40+
#[entry_point]
41+
pub fn reply(deps: DepsMut, _env: Env, reply: Reply) -> StdResult<Response> {
42+
match (reply.id, reply.result) {
43+
- (RECEIVE_DISPATCH_ID, ContractResult::Err(err)) => {
44+
+ (RECEIVE_DISPATCH_ID, SubMsgResult::Err(err)) => {
45+
Ok(Response::new().set_data(encode_ibc_error(err)))
46+
}
47+
- (INIT_CALLBACK_ID, ContractResult::Ok(response)) => handle_init_callback(deps, response),
48+
+ (INIT_CALLBACK_ID, SubMsgResult::Ok(response)) => handle_init_callback(deps, response),
49+
_ => Err(StdError::generic_err("invalid reply id or result")),
50+
}
51+
}
52+
```
53+
3654
## 0.16 -> 1.0.0-beta
3755

3856
- Update CosmWasm dependencies in Cargo.toml (skip the ones you don't use):

contracts/ibc-reflect/schema/acknowledgement_msg_balances.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"$schema": "http://json-schema.org/draft-07/schema#",
33
"title": "AcknowledgementMsgBalances",
4-
"description": "This is the final result type that is created and serialized in a contract for every init/execute/migrate call. The VM then deserializes this type to distinguish between successful and failed executions.\n\nWe use a custom type here instead of Rust's Result because we want to be able to define the serialization, which is a public interface. Every language that compiles to Wasm and runs in the ComsWasm VM needs to create the same JSON representation.\n\n# Examples\n\nSuccess:\n\n``` # use cosmwasm_std::{to_vec, ContractResult, Response}; let response: Response = Response::default(); let result: ContractResult<Response> = ContractResult::Ok(response); assert_eq!(to_vec(&result).unwrap(), br#\"{\"ok\":{\"messages\":[],\"attributes\":[],\"events\":[],\"data\":null}}\"#.to_vec()); ```\n\nFailure:\n\n``` # use cosmwasm_std::{to_vec, ContractResult, Response}; let error_msg = String::from(\"Something went wrong\"); let result: ContractResult<Response> = ContractResult::Err(error_msg); assert_eq!(to_vec(&result).unwrap(), br#\"{\"error\":\"Something went wrong\"}\"#.to_vec()); ```",
4+
"description": "This is the final result type that is created and serialized in a contract for every init/execute/migrate call. The VM then deserializes this type to distinguish between successful and failed executions.\n\nWe use a custom type here instead of Rust's Result because we want to be able to define the serialization, which is a public interface. Every language that compiles to Wasm and runs in the ComsWasm VM needs to create the same JSON representation.\n\n# Examples\n\nSuccess:\n\n``` # use cosmwasm_std::{to_vec, ContractResult, Response}; let response: Response = Response::default(); let result: ContractResult<Response> = ContractResult::Ok(response); assert_eq!(to_vec(&result).unwrap(), br#\"{\"ok\":{\"messages\":[],\"attributes\":[],\"events\":[],\"data\":null}}\"#); ```\n\nFailure:\n\n``` # use cosmwasm_std::{to_vec, ContractResult, Response}; let error_msg = String::from(\"Something went wrong\"); let result: ContractResult<Response> = ContractResult::Err(error_msg); assert_eq!(to_vec(&result).unwrap(), br#\"{\"error\":\"Something went wrong\"}\"#); ```",
55
"oneOf": [
66
{
77
"type": "object",

contracts/ibc-reflect/schema/acknowledgement_msg_dispatch.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"$schema": "http://json-schema.org/draft-07/schema#",
33
"title": "AcknowledgementMsgDispatch",
4-
"description": "This is the final result type that is created and serialized in a contract for every init/execute/migrate call. The VM then deserializes this type to distinguish between successful and failed executions.\n\nWe use a custom type here instead of Rust's Result because we want to be able to define the serialization, which is a public interface. Every language that compiles to Wasm and runs in the ComsWasm VM needs to create the same JSON representation.\n\n# Examples\n\nSuccess:\n\n``` # use cosmwasm_std::{to_vec, ContractResult, Response}; let response: Response = Response::default(); let result: ContractResult<Response> = ContractResult::Ok(response); assert_eq!(to_vec(&result).unwrap(), br#\"{\"ok\":{\"messages\":[],\"attributes\":[],\"events\":[],\"data\":null}}\"#.to_vec()); ```\n\nFailure:\n\n``` # use cosmwasm_std::{to_vec, ContractResult, Response}; let error_msg = String::from(\"Something went wrong\"); let result: ContractResult<Response> = ContractResult::Err(error_msg); assert_eq!(to_vec(&result).unwrap(), br#\"{\"error\":\"Something went wrong\"}\"#.to_vec()); ```",
4+
"description": "This is the final result type that is created and serialized in a contract for every init/execute/migrate call. The VM then deserializes this type to distinguish between successful and failed executions.\n\nWe use a custom type here instead of Rust's Result because we want to be able to define the serialization, which is a public interface. Every language that compiles to Wasm and runs in the ComsWasm VM needs to create the same JSON representation.\n\n# Examples\n\nSuccess:\n\n``` # use cosmwasm_std::{to_vec, ContractResult, Response}; let response: Response = Response::default(); let result: ContractResult<Response> = ContractResult::Ok(response); assert_eq!(to_vec(&result).unwrap(), br#\"{\"ok\":{\"messages\":[],\"attributes\":[],\"events\":[],\"data\":null}}\"#); ```\n\nFailure:\n\n``` # use cosmwasm_std::{to_vec, ContractResult, Response}; let error_msg = String::from(\"Something went wrong\"); let result: ContractResult<Response> = ContractResult::Err(error_msg); assert_eq!(to_vec(&result).unwrap(), br#\"{\"error\":\"Something went wrong\"}\"#); ```",
55
"oneOf": [
66
{
77
"type": "object",

contracts/ibc-reflect/schema/acknowledgement_msg_who_am_i.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"$schema": "http://json-schema.org/draft-07/schema#",
33
"title": "AcknowledgementMsgWhoAmI",
4-
"description": "This is the final result type that is created and serialized in a contract for every init/execute/migrate call. The VM then deserializes this type to distinguish between successful and failed executions.\n\nWe use a custom type here instead of Rust's Result because we want to be able to define the serialization, which is a public interface. Every language that compiles to Wasm and runs in the ComsWasm VM needs to create the same JSON representation.\n\n# Examples\n\nSuccess:\n\n``` # use cosmwasm_std::{to_vec, ContractResult, Response}; let response: Response = Response::default(); let result: ContractResult<Response> = ContractResult::Ok(response); assert_eq!(to_vec(&result).unwrap(), br#\"{\"ok\":{\"messages\":[],\"attributes\":[],\"events\":[],\"data\":null}}\"#.to_vec()); ```\n\nFailure:\n\n``` # use cosmwasm_std::{to_vec, ContractResult, Response}; let error_msg = String::from(\"Something went wrong\"); let result: ContractResult<Response> = ContractResult::Err(error_msg); assert_eq!(to_vec(&result).unwrap(), br#\"{\"error\":\"Something went wrong\"}\"#.to_vec()); ```",
4+
"description": "This is the final result type that is created and serialized in a contract for every init/execute/migrate call. The VM then deserializes this type to distinguish between successful and failed executions.\n\nWe use a custom type here instead of Rust's Result because we want to be able to define the serialization, which is a public interface. Every language that compiles to Wasm and runs in the ComsWasm VM needs to create the same JSON representation.\n\n# Examples\n\nSuccess:\n\n``` # use cosmwasm_std::{to_vec, ContractResult, Response}; let response: Response = Response::default(); let result: ContractResult<Response> = ContractResult::Ok(response); assert_eq!(to_vec(&result).unwrap(), br#\"{\"ok\":{\"messages\":[],\"attributes\":[],\"events\":[],\"data\":null}}\"#); ```\n\nFailure:\n\n``` # use cosmwasm_std::{to_vec, ContractResult, Response}; let error_msg = String::from(\"Something went wrong\"); let result: ContractResult<Response> = ContractResult::Err(error_msg); assert_eq!(to_vec(&result).unwrap(), br#\"{\"error\":\"Something went wrong\"}\"#); ```",
55
"oneOf": [
66
{
77
"type": "object",

contracts/ibc-reflect/src/contract.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
use cosmwasm_std::{
2-
entry_point, from_slice, to_binary, wasm_execute, BankMsg, Binary, ContractResult, CosmosMsg,
3-
Deps, DepsMut, Empty, Env, Event, IbcBasicResponse, IbcChannelCloseMsg, IbcChannelConnectMsg,
2+
entry_point, from_slice, to_binary, wasm_execute, BankMsg, Binary, CosmosMsg, Deps, DepsMut,
3+
Empty, Env, Event, IbcBasicResponse, IbcChannelCloseMsg, IbcChannelConnectMsg,
44
IbcChannelOpenMsg, IbcOrder, IbcPacketAckMsg, IbcPacketReceiveMsg, IbcPacketTimeoutMsg,
55
IbcReceiveResponse, MessageInfo, Order, QueryResponse, Reply, Response, StdError, StdResult,
6-
SubMsg, SubMsgExecutionResponse, WasmMsg,
6+
SubMsg, SubMsgExecutionResponse, SubMsgResult, WasmMsg,
77
};
88

99
use crate::msg::{
@@ -35,10 +35,10 @@ pub fn instantiate(
3535
#[entry_point]
3636
pub fn reply(deps: DepsMut, _env: Env, reply: Reply) -> StdResult<Response> {
3737
match (reply.id, reply.result) {
38-
(RECEIVE_DISPATCH_ID, ContractResult::Err(err)) => {
38+
(RECEIVE_DISPATCH_ID, SubMsgResult::Err(err)) => {
3939
Ok(Response::new().set_data(encode_ibc_error(err)))
4040
}
41-
(INIT_CALLBACK_ID, ContractResult::Ok(response)) => handle_init_callback(deps, response),
41+
(INIT_CALLBACK_ID, SubMsgResult::Ok(response)) => handle_init_callback(deps, response),
4242
_ => Err(StdError::generic_err("invalid reply id or result")),
4343
}
4444
}
@@ -387,7 +387,7 @@ mod tests {
387387
// fake a reply and ensure this works
388388
let response = Reply {
389389
id,
390-
result: ContractResult::Ok(SubMsgExecutionResponse {
390+
result: SubMsgResult::Ok(SubMsgExecutionResponse {
391391
events: fake_events(&account),
392392
data: None,
393393
}),
@@ -462,7 +462,7 @@ mod tests {
462462
// fake a reply and ensure this works
463463
let response = Reply {
464464
id,
465-
result: ContractResult::Ok(SubMsgExecutionResponse {
465+
result: SubMsgResult::Ok(SubMsgExecutionResponse {
466466
events: fake_events(REFLECT_ADDR),
467467
data: None,
468468
}),

contracts/ibc-reflect/tests/integration.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use cosmwasm_std::testing::{
2323
};
2424
use cosmwasm_std::{
2525
attr, coins, BankMsg, ContractResult, CosmosMsg, Event, IbcBasicResponse, IbcOrder,
26-
IbcReceiveResponse, Reply, Response, SubMsgExecutionResponse, WasmMsg,
26+
IbcReceiveResponse, Reply, Response, SubMsgExecutionResponse, SubMsgResult, WasmMsg,
2727
};
2828
use cosmwasm_vm::testing::{
2929
ibc_channel_connect, ibc_channel_open, ibc_packet_receive, instantiate, mock_env, mock_info,
@@ -95,7 +95,7 @@ fn connect(
9595
// fake a reply and ensure this works
9696
let response = Reply {
9797
id,
98-
result: ContractResult::Ok(SubMsgExecutionResponse {
98+
result: SubMsgResult::Ok(SubMsgExecutionResponse {
9999
events: fake_events(&account),
100100
data: None,
101101
}),
@@ -171,7 +171,7 @@ fn proper_handshake_flow() {
171171
// we get the callback from reflect
172172
let response = Reply {
173173
id,
174-
result: ContractResult::Ok(SubMsgExecutionResponse {
174+
result: SubMsgResult::Ok(SubMsgExecutionResponse {
175175
events: fake_events(REFLECT_ADDR),
176176
data: None,
177177
}),

contracts/reflect/src/contract.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -177,8 +177,8 @@ mod tests {
177177
use crate::testing::mock_dependencies_with_custom_querier;
178178
use cosmwasm_std::testing::{mock_env, mock_info, MOCK_CONTRACT_ADDR};
179179
use cosmwasm_std::{
180-
coin, coins, from_binary, AllBalanceResponse, BankMsg, BankQuery, Binary, ContractResult,
181-
Event, StakingMsg, StdError, SubMsgExecutionResponse,
180+
coin, coins, from_binary, AllBalanceResponse, BankMsg, BankQuery, Binary, Event,
181+
StakingMsg, StdError, SubMsgExecutionResponse, SubMsgResult,
182182
};
183183

184184
#[test]
@@ -435,7 +435,7 @@ mod tests {
435435
let id = 123u64;
436436
let data = Binary::from(b"foobar");
437437
let events = vec![Event::new("message").add_attribute("signer", "caller-addr")];
438-
let result = ContractResult::Ok(SubMsgExecutionResponse {
438+
let result = SubMsgResult::Ok(SubMsgExecutionResponse {
439439
events: events.clone(),
440440
data: Some(data.clone()),
441441
});

contracts/reflect/tests/integration.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
2020
use cosmwasm_std::{
2121
coin, coins, from_binary, BankMsg, Binary, Coin, ContractResult, Event, Reply, Response,
22-
StakingMsg, SubMsg, SubMsgExecutionResponse, SystemResult,
22+
StakingMsg, SubMsg, SubMsgExecutionResponse, SubMsgResult, SystemResult,
2323
};
2424
use cosmwasm_vm::{
2525
testing::{
@@ -226,7 +226,7 @@ fn reply_and_query() {
226226
let id = 123u64;
227227
let data = Binary::from(b"foobar");
228228
let events = vec![Event::new("message").add_attribute("signer", "caller-addr")];
229-
let result = ContractResult::Ok(SubMsgExecutionResponse {
229+
let result = SubMsgResult::Ok(SubMsgExecutionResponse {
230230
events: events.clone(),
231231
data: Some(data.clone()),
232232
});

packages/std/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ pub use crate::query::{ChannelResponse, IbcQuery, ListChannelsResponse, PortIdRe
6060
pub use crate::results::{
6161
attr, wasm_execute, wasm_instantiate, Attribute, BankMsg, ContractResult, CosmosMsg, CustomMsg,
6262
Empty, Event, QueryResponse, Reply, ReplyOn, Response, SubMsg, SubMsgExecutionResponse,
63-
SystemResult, WasmMsg,
63+
SubMsgResult, SystemResult, WasmMsg,
6464
};
6565
#[cfg(feature = "staking")]
6666
pub use crate::results::{DistributionMsg, StakingMsg};

packages/std/src/results/contract_result.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use std::fmt;
1818
/// # use cosmwasm_std::{to_vec, ContractResult, Response};
1919
/// let response: Response = Response::default();
2020
/// let result: ContractResult<Response> = ContractResult::Ok(response);
21-
/// assert_eq!(to_vec(&result).unwrap(), br#"{"ok":{"messages":[],"attributes":[],"events":[],"data":null}}"#.to_vec());
21+
/// assert_eq!(to_vec(&result).unwrap(), br#"{"ok":{"messages":[],"attributes":[],"events":[],"data":null}}"#);
2222
/// ```
2323
///
2424
/// Failure:
@@ -27,7 +27,7 @@ use std::fmt;
2727
/// # use cosmwasm_std::{to_vec, ContractResult, Response};
2828
/// let error_msg = String::from("Something went wrong");
2929
/// let result: ContractResult<Response> = ContractResult::Err(error_msg);
30-
/// assert_eq!(to_vec(&result).unwrap(), br#"{"error":"Something went wrong"}"#.to_vec());
30+
/// assert_eq!(to_vec(&result).unwrap(), br#"{"error":"Something went wrong"}"#);
3131
/// ```
3232
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
3333
#[serde(rename_all = "snake_case")]
@@ -101,7 +101,7 @@ mod tests {
101101
let result: ContractResult<Response> = ContractResult::Ok(Response::default());
102102
assert_eq!(
103103
to_vec(&result).unwrap(),
104-
br#"{"ok":{"messages":[],"attributes":[],"events":[],"data":null}}"#.to_vec()
104+
br#"{"ok":{"messages":[],"attributes":[],"events":[],"data":null}}"#
105105
);
106106

107107
let result: ContractResult<Response> = ContractResult::Err("broken".to_string());

packages/std/src/results/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,5 @@ pub use empty::Empty;
1919
pub use events::{attr, Attribute, Event};
2020
pub use query::QueryResponse;
2121
pub use response::Response;
22-
pub use submessages::{Reply, ReplyOn, SubMsg, SubMsgExecutionResponse};
22+
pub use submessages::{Reply, ReplyOn, SubMsg, SubMsgExecutionResponse, SubMsgResult};
2323
pub use system_result::SystemResult;

packages/std/src/results/response.rs

+17-1
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ mod tests {
210210
use super::super::BankMsg;
211211
use super::*;
212212
use crate::results::submessages::{ReplyOn, UNUSED_MSG_ID};
213-
use crate::{coins, from_slice, to_vec};
213+
use crate::{coins, from_slice, to_vec, ContractResult};
214214

215215
#[test]
216216
fn can_serialize_and_deserialize_init_response() {
@@ -248,4 +248,20 @@ mod tests {
248248
let deserialized: Response = from_slice(&serialized).expect("decode contract result");
249249
assert_eq!(deserialized, original);
250250
}
251+
252+
#[test]
253+
fn contract_result_is_ok_works() {
254+
let success = ContractResult::<()>::Ok(());
255+
let failure = ContractResult::<()>::Err("broken".to_string());
256+
assert!(success.is_ok());
257+
assert!(!failure.is_ok());
258+
}
259+
260+
#[test]
261+
fn contract_result_is_err_works() {
262+
let success = ContractResult::<()>::Ok(());
263+
let failure = ContractResult::<()>::Err("broken".to_string());
264+
assert!(failure.is_err());
265+
assert!(!success.is_err());
266+
}
251267
}

0 commit comments

Comments
 (0)