Skip to content

Commit

Permalink
Add async ack functionality to ibc-reflect
Browse files Browse the repository at this point in the history
  • Loading branch information
chipshort committed May 8, 2024
1 parent 9280da8 commit c9b4920
Show file tree
Hide file tree
Showing 6 changed files with 244 additions and 9 deletions.
80 changes: 79 additions & 1 deletion contracts/ibc-reflect/schema/ibc-reflect.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,85 @@
},
"additionalProperties": false
},
"execute": null,
"execute": {
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "ExecuteMsg",
"oneOf": [
{
"type": "object",
"required": [
"async_ack"
],
"properties": {
"async_ack": {
"type": "object",
"required": [
"ack",
"channel_id",
"packet_sequence"
],
"properties": {
"ack": {
"description": "The acknowledgement to send back",
"allOf": [
{
"$ref": "#/definitions/IbcFullAcknowledgement"
}
]
},
"channel_id": {
"description": "Existing channel where the packet was received",
"type": "string"
},
"packet_sequence": {
"description": "Sequence number of the packet that was received",
"allOf": [
{
"$ref": "#/definitions/Uint64"
}
]
}
},
"additionalProperties": false
}
},
"additionalProperties": false
}
],
"definitions": {
"Binary": {
"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>.",
"type": "string"
},
"IbcFullAcknowledgement": {
"description": "The acknowledgement written by the module on the destination chain. It is different from the [`crate::IbcAcknowledgement`] as it can be unsuccessful.",
"type": "object",
"required": [
"data",
"success"
],
"properties": {
"data": {
"description": "The acknowledgement data returned by the module.",
"allOf": [
{
"$ref": "#/definitions/Binary"
}
]
},
"success": {
"description": "Whether the acknowledgement was successful or not.",
"type": "boolean"
}
},
"additionalProperties": false
},
"Uint64": {
"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); ```",
"type": "string"
}
}
},
"query": {
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "QueryMsg",
Expand Down
13 changes: 13 additions & 0 deletions contracts/ibc-reflect/schema/ibc/packet_msg.json
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,19 @@
}
},
"additionalProperties": false
},
{
"type": "object",
"required": [
"no_ack"
],
"properties": {
"no_ack": {
"type": "object",
"additionalProperties": false
}
},
"additionalProperties": false
}
],
"definitions": {
Expand Down
79 changes: 79 additions & 0 deletions contracts/ibc-reflect/schema/raw/execute.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "ExecuteMsg",
"oneOf": [
{
"type": "object",
"required": [
"async_ack"
],
"properties": {
"async_ack": {
"type": "object",
"required": [
"ack",
"channel_id",
"packet_sequence"
],
"properties": {
"ack": {
"description": "The acknowledgement to send back",
"allOf": [
{
"$ref": "#/definitions/IbcFullAcknowledgement"
}
]
},
"channel_id": {
"description": "Existing channel where the packet was received",
"type": "string"
},
"packet_sequence": {
"description": "Sequence number of the packet that was received",
"allOf": [
{
"$ref": "#/definitions/Uint64"
}
]
}
},
"additionalProperties": false
}
},
"additionalProperties": false
}
],
"definitions": {
"Binary": {
"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>.",
"type": "string"
},
"IbcFullAcknowledgement": {
"description": "The acknowledgement written by the module on the destination chain. It is different from the [`crate::IbcAcknowledgement`] as it can be unsuccessful.",
"type": "object",
"required": [
"data",
"success"
],
"properties": {
"data": {
"description": "The acknowledgement data returned by the module.",
"allOf": [
{
"$ref": "#/definitions/Binary"
}
]
},
"success": {
"description": "Whether the acknowledgement was successful or not.",
"type": "boolean"
}
},
"additionalProperties": false
},
"Uint64": {
"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); ```",
"type": "string"
}
}
}
5 changes: 3 additions & 2 deletions contracts/ibc-reflect/src/bin/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@ use cosmwasm_schema::{export_schema, export_schema_with_title, schema_for, write
use cosmwasm_std::Empty;

use ibc_reflect::msg::{
AcknowledgementMsg, BalancesResponse, DispatchResponse, InstantiateMsg, PacketMsg, QueryMsg,
WhoAmIResponse,
AcknowledgementMsg, BalancesResponse, DispatchResponse, ExecuteMsg, InstantiateMsg, PacketMsg,
QueryMsg, WhoAmIResponse,
};

fn main() {
// Clear & write standard API
write_api! {
instantiate: InstantiateMsg,
execute: ExecuteMsg,
query: QueryMsg,
migrate: Empty,
}
Expand Down
39 changes: 34 additions & 5 deletions contracts/ibc-reflect/src/contract.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
use cosmwasm_std::{
entry_point, from_json, to_json_binary, wasm_execute, BankMsg, Binary, CosmosMsg, Deps,
DepsMut, Empty, Env, Event, Ibc3ChannelOpenResponse, IbcBasicResponse, IbcChannelCloseMsg,
IbcChannelConnectMsg, IbcChannelOpenMsg, IbcChannelOpenResponse, IbcOrder, IbcPacketAckMsg,
IbcPacketReceiveMsg, IbcPacketTimeoutMsg, IbcReceiveResponse, MessageInfo, Never,
QueryResponse, Reply, Response, StdError, StdResult, SubMsg, SubMsgResponse, SubMsgResult,
WasmMsg,
IbcChannelConnectMsg, IbcChannelOpenMsg, IbcChannelOpenResponse, IbcFullAcknowledgement,
IbcMsg, IbcOrder, IbcPacketAckMsg, IbcPacketReceiveMsg, IbcPacketTimeoutMsg,
IbcReceiveResponse, MessageInfo, Never, QueryResponse, Reply, Response, StdError, StdResult,
SubMsg, SubMsgResponse, SubMsgResult, WasmMsg,
};

use crate::msg::{
AccountInfo, AccountResponse, AcknowledgementMsg, BalancesResponse, DispatchResponse,
InstantiateMsg, ListAccountsResponse, PacketMsg, QueryMsg, ReflectExecuteMsg,
ExecuteMsg, InstantiateMsg, ListAccountsResponse, PacketMsg, QueryMsg, ReflectExecuteMsg,
ReturnMsgsResponse, WhoAmIResponse,
};
use crate::state::{
Expand Down Expand Up @@ -37,6 +37,34 @@ pub fn instantiate(
Ok(Response::new().add_attribute("action", "instantiate"))
}

#[entry_point]
pub fn execute(
_deps: DepsMut,
_env: Env,
_info: MessageInfo,
msg: ExecuteMsg,
) -> StdResult<Response> {
match msg {
ExecuteMsg::AsyncAck {
channel_id,
packet_sequence,
ack,
} => execute_async_ack(channel_id, packet_sequence.u64(), ack),
}
}

fn execute_async_ack(
channel_id: String,
packet_sequence: u64,
ack: IbcFullAcknowledgement,
) -> StdResult<Response> {
Ok(Response::new().add_message(IbcMsg::WriteAcknowledgement {
channel_id,
packet_sequence,
ack,
}))
}

#[entry_point]
pub fn reply(deps: DepsMut, _env: Env, reply: Reply) -> StdResult<Response> {
match (reply.id, reply.result) {
Expand Down Expand Up @@ -249,6 +277,7 @@ pub fn ibc_packet_receive(
PacketMsg::Panic {} => execute_panic(),
PacketMsg::ReturnErr { text } => execute_error(text),
PacketMsg::ReturnMsgs { msgs } => execute_return_msgs(msgs),
PacketMsg::NoAck {} => Ok(IbcReceiveResponse::without_ack()),
}
})()
.or_else(|e| {
Expand Down
37 changes: 36 additions & 1 deletion contracts/ibc-reflect/src/msg.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,24 @@
use cosmwasm_schema::{cw_serde, QueryResponses};
use cosmwasm_std::{Coin, CosmosMsg};
use cosmwasm_std::{Coin, CosmosMsg, IbcFullAcknowledgement, Uint64};

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

#[cw_serde]
pub enum ExecuteMsg {
AsyncAck {
/// Existing channel where the packet was received
channel_id: String,
/// Sequence number of the packet that was received
packet_sequence: Uint64,
/// The acknowledgement to send back
ack: IbcFullAcknowledgement,
},
}

#[cw_serde]
#[derive(QueryResponses)]
pub enum QueryMsg {
Expand Down Expand Up @@ -49,6 +61,7 @@ pub enum PacketMsg {
Panic {},
ReturnErr { text: String },
ReturnMsgs { msgs: Vec<CosmosMsg> },
NoAck {},
}

/// A custom acknowledgement type.
Expand Down Expand Up @@ -103,3 +116,25 @@ pub struct BalancesResponse {
/// This is the success response we send on ack for PacketMsg::ReturnMsgs.
/// Just acknowledge success or error
pub type ReturnMsgsResponse = ();

#[cfg(test)]
mod tests {
use cosmwasm_std::from_json;

use super::*;

#[test]
fn test_serde_packet_msg() {
let packet_msg = PacketMsg::AsyncAck {
channel_id: "channel-0".to_string(),
packet_sequence: Uint64(1),
ack: IbcFullAcknowledgement {
data: Some(b"my ack".to_vec()),
..Default::default()
},
};

let json = r#"{"async_ack":{"channel_id":"channel-0","packet_sequence": 1, "ack": {"data":"my ack", "success": true}}}"#;
let packet_msg: PacketMsg = from_json(json).unwrap();
}
}

0 comments on commit c9b4920

Please sign in to comment.