Skip to content

Commit

Permalink
Merge pull request #2130 from CosmWasm/chipshort/async-ack
Browse files Browse the repository at this point in the history
Async Acknowledgement
  • Loading branch information
chipshort committed Jun 13, 2024
2 parents 6416b95 + e1be535 commit 81c6ab8
Show file tree
Hide file tree
Showing 12 changed files with 288 additions and 17 deletions.
4 changes: 3 additions & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -695,8 +695,10 @@ jobs:
- restore_cache:
keys:
- cargocache-v2-contract_ibc_reflect-rust:1.74-{{ checksum "Cargo.lock" }}
# TODO: Enable this once 2.1 has been released to crates.io
- check_contract:
min_version: "2.0"
min_version: "2.1"
skip_cosmwasm_check: true
- save_cache:
paths:
- /usr/local/cargo/registry
Expand Down
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ and this project adheres to
- cosmwasm-std: Add `TransferMsgBuilder` to more easily create an
`IbcMsg::Transfer` with different kinds of memo values, including IBC
Callbacks memo values. ([#2167])
- cosmwasm-std: Add `IbcMsg::WriteAcknowledgement` for async IBC
acknowledgements ([#2130])

[#1983]: https://github.com/CosmWasm/cosmwasm/pull/1983
[#2025]: https://github.com/CosmWasm/cosmwasm/pull/2025
Expand All @@ -69,6 +71,7 @@ and this project adheres to
[#2120]: https://github.com/CosmWasm/cosmwasm/pull/2120
[#2124]: https://github.com/CosmWasm/cosmwasm/pull/2124
[#2129]: https://github.com/CosmWasm/cosmwasm/pull/2129
[#2130]: https://github.com/CosmWasm/cosmwasm/pull/2130
[#2166]: https://github.com/CosmWasm/cosmwasm/pull/2166
[#2167]: https://github.com/CosmWasm/cosmwasm/pull/2167

Expand Down
2 changes: 1 addition & 1 deletion contracts/ibc-reflect/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ cranelift = ["cosmwasm-vm/cranelift"]

[dependencies]
cosmwasm-schema = { path = "../../packages/schema" }
cosmwasm-std = { path = "../../packages/std", features = ["iterator", "stargate", "cosmwasm_2_0"] }
cosmwasm-std = { path = "../../packages/std", features = ["iterator", "stargate", "cosmwasm_2_1"] }
schemars = "0.8.12"
serde = { version = "1.0.103", default-features = false, features = ["derive"] }

Expand Down
69 changes: 68 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,74 @@
},
"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/IbcAcknowledgement"
}
]
},
"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"
},
"IbcAcknowledgement": {
"type": "object",
"required": [
"data"
],
"properties": {
"data": {
"$ref": "#/definitions/Binary"
}
},
"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
64 changes: 64 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 Expand Up @@ -390,6 +403,18 @@
}
]
},
"IbcAcknowledgement": {
"type": "object",
"required": [
"data"
],
"properties": {
"data": {
"$ref": "#/definitions/Binary"
}
},
"additionalProperties": false
},
"IbcMsg": {
"description": "These are messages in the IBC lifecycle. Only usable by IBC-enabled contracts (contracts that directly speak the IBC protocol via 6 entry points)",
"oneOf": [
Expand Down Expand Up @@ -481,6 +506,45 @@
},
"additionalProperties": false
},
{
"description": "Acknowledges a packet that this contract received over IBC. This allows acknowledging a packet that was not acknowledged yet in the `ibc_packet_receive` call.",
"type": "object",
"required": [
"write_acknowledgement"
],
"properties": {
"write_acknowledgement": {
"type": "object",
"required": [
"ack",
"channel_id",
"packet_sequence"
],
"properties": {
"ack": {
"description": "The acknowledgement to send back",
"allOf": [
{
"$ref": "#/definitions/IbcAcknowledgement"
}
]
},
"channel_id": {
"description": "Existing channel where the packet was received",
"type": "string"
},
"packet_sequence": {
"description": "Sequence number of the packet that was received",
"type": "integer",
"format": "uint64",
"minimum": 0.0
}
},
"additionalProperties": false
}
},
"additionalProperties": false
},
{
"description": "This will close an existing channel that is owned by this contract. Port is auto-assigned to the contract's IBC port",
"type": "object",
Expand Down
68 changes: 68 additions & 0 deletions contracts/ibc-reflect/schema/raw/execute.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
{
"$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/IbcAcknowledgement"
}
]
},
"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"
},
"IbcAcknowledgement": {
"type": "object",
"required": [
"data"
],
"properties": {
"data": {
"$ref": "#/definitions/Binary"
}
},
"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
43 changes: 36 additions & 7 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,
DepsMut, Empty, Env, Event, Ibc3ChannelOpenResponse, IbcAcknowledgement, IbcBasicResponse,
IbcChannelCloseMsg, IbcChannelConnectMsg, IbcChannelOpenMsg, IbcChannelOpenResponse, 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: IbcAcknowledgement,
) -> 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 Expand Up @@ -607,7 +636,7 @@ mod tests {
// acknowledgement is an error
let ack: AcknowledgementMsg<DispatchResponse> =
from_json(res.acknowledgement.unwrap()).unwrap();
assert_eq!(ack.unwrap_err(), "invalid packet: Error parsing into type ibc_reflect::msg::PacketMsg: unknown variant `reflect_code_id`, expected one of `dispatch`, `who_am_i`, `balances`, `panic`, `return_err`, `return_msgs`");
assert_eq!(ack.unwrap_err(), "invalid packet: Error parsing into type ibc_reflect::msg::PacketMsg: unknown variant `reflect_code_id`, expected one of `dispatch`, `who_am_i`, `balances`, `panic`, `return_err`, `return_msgs`, `no_ack`");
}

#[test]
Expand Down
15 changes: 14 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, IbcAcknowledgement, 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: IbcAcknowledgement,
},
}

#[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
Loading

0 comments on commit 81c6ab8

Please sign in to comment.