Skip to content

Commit 42a553e

Browse files
committed
Add async ack functionality to ibc-reflect
1 parent caa6dfe commit 42a553e

File tree

6 files changed

+244
-9
lines changed

6 files changed

+244
-9
lines changed

contracts/ibc-reflect/schema/ibc-reflect.json

Lines changed: 79 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,85 @@
1919
},
2020
"additionalProperties": false
2121
},
22-
"execute": null,
22+
"execute": {
23+
"$schema": "http://json-schema.org/draft-07/schema#",
24+
"title": "ExecuteMsg",
25+
"oneOf": [
26+
{
27+
"type": "object",
28+
"required": [
29+
"async_ack"
30+
],
31+
"properties": {
32+
"async_ack": {
33+
"type": "object",
34+
"required": [
35+
"ack",
36+
"channel_id",
37+
"packet_sequence"
38+
],
39+
"properties": {
40+
"ack": {
41+
"description": "The acknowledgement to send back",
42+
"allOf": [
43+
{
44+
"$ref": "#/definitions/IbcFullAcknowledgement"
45+
}
46+
]
47+
},
48+
"channel_id": {
49+
"description": "Existing channel where the packet was received",
50+
"type": "string"
51+
},
52+
"packet_sequence": {
53+
"description": "Sequence number of the packet that was received",
54+
"allOf": [
55+
{
56+
"$ref": "#/definitions/Uint64"
57+
}
58+
]
59+
}
60+
},
61+
"additionalProperties": false
62+
}
63+
},
64+
"additionalProperties": false
65+
}
66+
],
67+
"definitions": {
68+
"Binary": {
69+
"description": "Binary is a wrapper around Vec<u8> to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec<u8>. See also <https://github.com/CosmWasm/cosmwasm/blob/main/docs/MESSAGE_TYPES.md>.",
70+
"type": "string"
71+
},
72+
"IbcFullAcknowledgement": {
73+
"description": "The acknowledgement written by the module on the destination chain. It is different from the [`crate::IbcAcknowledgement`] as it can be unsuccessful.",
74+
"type": "object",
75+
"required": [
76+
"data",
77+
"success"
78+
],
79+
"properties": {
80+
"data": {
81+
"description": "The acknowledgement data returned by the module.",
82+
"allOf": [
83+
{
84+
"$ref": "#/definitions/Binary"
85+
}
86+
]
87+
},
88+
"success": {
89+
"description": "Whether the acknowledgement was successful or not.",
90+
"type": "boolean"
91+
}
92+
},
93+
"additionalProperties": false
94+
},
95+
"Uint64": {
96+
"description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```",
97+
"type": "string"
98+
}
99+
}
100+
},
23101
"query": {
24102
"$schema": "http://json-schema.org/draft-07/schema#",
25103
"title": "QueryMsg",

contracts/ibc-reflect/schema/ibc/packet_msg.json

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,19 @@
109109
}
110110
},
111111
"additionalProperties": false
112+
},
113+
{
114+
"type": "object",
115+
"required": [
116+
"no_ack"
117+
],
118+
"properties": {
119+
"no_ack": {
120+
"type": "object",
121+
"additionalProperties": false
122+
}
123+
},
124+
"additionalProperties": false
112125
}
113126
],
114127
"definitions": {
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
{
2+
"$schema": "http://json-schema.org/draft-07/schema#",
3+
"title": "ExecuteMsg",
4+
"oneOf": [
5+
{
6+
"type": "object",
7+
"required": [
8+
"async_ack"
9+
],
10+
"properties": {
11+
"async_ack": {
12+
"type": "object",
13+
"required": [
14+
"ack",
15+
"channel_id",
16+
"packet_sequence"
17+
],
18+
"properties": {
19+
"ack": {
20+
"description": "The acknowledgement to send back",
21+
"allOf": [
22+
{
23+
"$ref": "#/definitions/IbcFullAcknowledgement"
24+
}
25+
]
26+
},
27+
"channel_id": {
28+
"description": "Existing channel where the packet was received",
29+
"type": "string"
30+
},
31+
"packet_sequence": {
32+
"description": "Sequence number of the packet that was received",
33+
"allOf": [
34+
{
35+
"$ref": "#/definitions/Uint64"
36+
}
37+
]
38+
}
39+
},
40+
"additionalProperties": false
41+
}
42+
},
43+
"additionalProperties": false
44+
}
45+
],
46+
"definitions": {
47+
"Binary": {
48+
"description": "Binary is a wrapper around Vec<u8> to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec<u8>. See also <https://github.com/CosmWasm/cosmwasm/blob/main/docs/MESSAGE_TYPES.md>.",
49+
"type": "string"
50+
},
51+
"IbcFullAcknowledgement": {
52+
"description": "The acknowledgement written by the module on the destination chain. It is different from the [`crate::IbcAcknowledgement`] as it can be unsuccessful.",
53+
"type": "object",
54+
"required": [
55+
"data",
56+
"success"
57+
],
58+
"properties": {
59+
"data": {
60+
"description": "The acknowledgement data returned by the module.",
61+
"allOf": [
62+
{
63+
"$ref": "#/definitions/Binary"
64+
}
65+
]
66+
},
67+
"success": {
68+
"description": "Whether the acknowledgement was successful or not.",
69+
"type": "boolean"
70+
}
71+
},
72+
"additionalProperties": false
73+
},
74+
"Uint64": {
75+
"description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```",
76+
"type": "string"
77+
}
78+
}
79+
}

contracts/ibc-reflect/src/bin/schema.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,15 @@ use cosmwasm_schema::{export_schema, export_schema_with_title, schema_for, write
44
use cosmwasm_std::Empty;
55

66
use ibc_reflect::msg::{
7-
AcknowledgementMsg, BalancesResponse, DispatchResponse, InstantiateMsg, PacketMsg, QueryMsg,
8-
WhoAmIResponse,
7+
AcknowledgementMsg, BalancesResponse, DispatchResponse, ExecuteMsg, InstantiateMsg, PacketMsg,
8+
QueryMsg, WhoAmIResponse,
99
};
1010

1111
fn main() {
1212
// Clear & write standard API
1313
write_api! {
1414
instantiate: InstantiateMsg,
15+
execute: ExecuteMsg,
1516
query: QueryMsg,
1617
migrate: Empty,
1718
}

contracts/ibc-reflect/src/contract.rs

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
use cosmwasm_std::{
22
entry_point, from_json, to_json_binary, wasm_execute, BankMsg, Binary, CosmosMsg, Deps,
33
DepsMut, Empty, Env, Event, Ibc3ChannelOpenResponse, IbcBasicResponse, IbcChannelCloseMsg,
4-
IbcChannelConnectMsg, IbcChannelOpenMsg, IbcChannelOpenResponse, IbcOrder, IbcPacketAckMsg,
5-
IbcPacketReceiveMsg, IbcPacketTimeoutMsg, IbcReceiveResponse, MessageInfo, Never,
6-
QueryResponse, Reply, Response, StdError, StdResult, SubMsg, SubMsgResponse, SubMsgResult,
7-
WasmMsg,
4+
IbcChannelConnectMsg, IbcChannelOpenMsg, IbcChannelOpenResponse, IbcFullAcknowledgement,
5+
IbcMsg, IbcOrder, IbcPacketAckMsg, IbcPacketReceiveMsg, IbcPacketTimeoutMsg,
6+
IbcReceiveResponse, MessageInfo, Never, QueryResponse, Reply, Response, StdError, StdResult,
7+
SubMsg, SubMsgResponse, SubMsgResult, WasmMsg,
88
};
99

1010
use crate::msg::{
1111
AccountInfo, AccountResponse, AcknowledgementMsg, BalancesResponse, DispatchResponse,
12-
InstantiateMsg, ListAccountsResponse, PacketMsg, QueryMsg, ReflectExecuteMsg,
12+
ExecuteMsg, InstantiateMsg, ListAccountsResponse, PacketMsg, QueryMsg, ReflectExecuteMsg,
1313
ReturnMsgsResponse, WhoAmIResponse,
1414
};
1515
use crate::state::{
@@ -37,6 +37,34 @@ pub fn instantiate(
3737
Ok(Response::new().add_attribute("action", "instantiate"))
3838
}
3939

40+
#[entry_point]
41+
pub fn execute(
42+
_deps: DepsMut,
43+
_env: Env,
44+
_info: MessageInfo,
45+
msg: ExecuteMsg,
46+
) -> StdResult<Response> {
47+
match msg {
48+
ExecuteMsg::AsyncAck {
49+
channel_id,
50+
packet_sequence,
51+
ack,
52+
} => execute_async_ack(channel_id, packet_sequence.u64(), ack),
53+
}
54+
}
55+
56+
fn execute_async_ack(
57+
channel_id: String,
58+
packet_sequence: u64,
59+
ack: IbcFullAcknowledgement,
60+
) -> StdResult<Response> {
61+
Ok(Response::new().add_message(IbcMsg::WriteAcknowledgement {
62+
channel_id,
63+
packet_sequence,
64+
ack,
65+
}))
66+
}
67+
4068
#[entry_point]
4169
pub fn reply(deps: DepsMut, _env: Env, reply: Reply) -> StdResult<Response> {
4270
match (reply.id, reply.result) {
@@ -249,6 +277,7 @@ pub fn ibc_packet_receive(
249277
PacketMsg::Panic {} => execute_panic(),
250278
PacketMsg::ReturnErr { text } => execute_error(text),
251279
PacketMsg::ReturnMsgs { msgs } => execute_return_msgs(msgs),
280+
PacketMsg::NoAck {} => Ok(IbcReceiveResponse::without_ack()),
252281
}
253282
})()
254283
.or_else(|e| {

contracts/ibc-reflect/src/msg.rs

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,24 @@
11
use cosmwasm_schema::{cw_serde, QueryResponses};
2-
use cosmwasm_std::{Coin, CosmosMsg};
2+
use cosmwasm_std::{Coin, CosmosMsg, IbcFullAcknowledgement, Uint64};
33

44
/// Just needs to know the code_id of a reflect contract to spawn sub-accounts
55
#[cw_serde]
66
pub struct InstantiateMsg {
77
pub reflect_code_id: u64,
88
}
99

10+
#[cw_serde]
11+
pub enum ExecuteMsg {
12+
AsyncAck {
13+
/// Existing channel where the packet was received
14+
channel_id: String,
15+
/// Sequence number of the packet that was received
16+
packet_sequence: Uint64,
17+
/// The acknowledgement to send back
18+
ack: IbcFullAcknowledgement,
19+
},
20+
}
21+
1022
#[cw_serde]
1123
#[derive(QueryResponses)]
1224
pub enum QueryMsg {
@@ -49,6 +61,7 @@ pub enum PacketMsg {
4961
Panic {},
5062
ReturnErr { text: String },
5163
ReturnMsgs { msgs: Vec<CosmosMsg> },
64+
NoAck {},
5265
}
5366

5467
/// A custom acknowledgement type.
@@ -103,3 +116,25 @@ pub struct BalancesResponse {
103116
/// This is the success response we send on ack for PacketMsg::ReturnMsgs.
104117
/// Just acknowledge success or error
105118
pub type ReturnMsgsResponse = ();
119+
120+
#[cfg(test)]
121+
mod tests {
122+
use cosmwasm_std::from_json;
123+
124+
use super::*;
125+
126+
#[test]
127+
fn test_serde_packet_msg() {
128+
let packet_msg = PacketMsg::AsyncAck {
129+
channel_id: "channel-0".to_string(),
130+
packet_sequence: Uint64(1),
131+
ack: IbcFullAcknowledgement {
132+
data: Some(b"my ack".to_vec()),
133+
..Default::default()
134+
},
135+
};
136+
137+
let json = r#"{"async_ack":{"channel_id":"channel-0","packet_sequence": 1, "ack": {"data":"my ack", "success": true}}}"#;
138+
let packet_msg: PacketMsg = from_json(json).unwrap();
139+
}
140+
}

0 commit comments

Comments
 (0)