Skip to content

Commit 6d635bf

Browse files
authored
feat: Add WriteAcknowledgement to Ibc2Msg (#2425)
1 parent 5a3998d commit 6d635bf

File tree

7 files changed

+80
-10
lines changed

7 files changed

+80
-10
lines changed

contracts/ibc2/schema/ibc2.json

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,23 @@
3737
"title": "State",
3838
"type": "object",
3939
"required": [
40-
"ibc2_packet_receive_counter"
40+
"ibc2_packet_receive_counter",
41+
"last_channel_id",
42+
"last_packet_seq"
4143
],
4244
"properties": {
4345
"ibc2_packet_receive_counter": {
4446
"type": "integer",
4547
"format": "uint32",
4648
"minimum": 0.0
49+
},
50+
"last_channel_id": {
51+
"type": "string"
52+
},
53+
"last_packet_seq": {
54+
"type": "integer",
55+
"format": "uint64",
56+
"minimum": 0.0
4757
}
4858
},
4959
"additionalProperties": false

contracts/ibc2/schema/raw/response_to_query_state.json

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,23 @@
33
"title": "State",
44
"type": "object",
55
"required": [
6-
"ibc2_packet_receive_counter"
6+
"ibc2_packet_receive_counter",
7+
"last_channel_id",
8+
"last_packet_seq"
79
],
810
"properties": {
911
"ibc2_packet_receive_counter": {
1012
"type": "integer",
1113
"format": "uint32",
1214
"minimum": 0.0
15+
},
16+
"last_channel_id": {
17+
"type": "string"
18+
},
19+
"last_packet_seq": {
20+
"type": "integer",
21+
"format": "uint64",
22+
"minimum": 0.0
1323
}
1424
},
1525
"additionalProperties": false

contracts/ibc2/src/contract.rs

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
use cosmwasm_std::{
22
entry_point, from_json, to_json_vec, Binary, Deps, DepsMut, Empty, Env, Ibc2Msg,
3-
Ibc2PacketReceiveMsg, Ibc2Payload, IbcReceiveResponse, MessageInfo, QueryResponse, Response,
4-
StdAck, StdError, StdResult, Timestamp,
3+
Ibc2PacketReceiveMsg, Ibc2Payload, IbcAcknowledgement, IbcReceiveResponse, MessageInfo,
4+
QueryResponse, Response, StdAck, StdError, StdResult, Timestamp,
55
};
66

7-
use crate::msg::QueryMsg;
7+
use crate::msg::{IbcPayload, QueryMsg};
88
use crate::state::{State, STATE_KEY};
99

1010
#[entry_point]
@@ -18,6 +18,8 @@ pub fn instantiate(
1818
STATE_KEY,
1919
&to_json_vec(&State {
2020
ibc2_packet_receive_counter: 0,
21+
last_channel_id: "".to_owned(),
22+
last_packet_seq: 0,
2123
})?,
2224
);
2325

@@ -43,15 +45,21 @@ pub fn ibc2_packet_receive(
4345
_env: Env,
4446
msg: Ibc2PacketReceiveMsg,
4547
) -> StdResult<IbcReceiveResponse> {
48+
let binary_payload = &msg.payload.value;
49+
let json_payload: IbcPayload = from_json(binary_payload)?;
50+
4651
let data = deps
4752
.storage
4853
.get(STATE_KEY)
4954
.ok_or_else(|| StdError::generic_err("State not found."))?;
5055
let state: State = from_json(data)?;
56+
5157
deps.storage.set(
5258
STATE_KEY,
5359
&to_json_vec(&State {
5460
ibc2_packet_receive_counter: state.ibc2_packet_receive_counter + 1,
61+
last_channel_id: msg.source_client.clone(),
62+
last_packet_seq: msg.packet_sequence,
5563
})?,
5664
);
5765
// Workaround for now.
@@ -71,7 +79,23 @@ pub fn ibc2_packet_receive(
7179
// timeout: _env.block.time.plus_seconds(5_u64),
7280
};
7381

74-
Ok(IbcReceiveResponse::new(StdAck::success(b"\x01"))
75-
.add_message(new_msg)
76-
.add_attribute("action", "handle_increment"))
82+
let resp = if json_payload.response_without_ack {
83+
IbcReceiveResponse::without_ack().add_attribute("action", "handle_increment")
84+
} else {
85+
IbcReceiveResponse::new(StdAck::success(b"\x01"))
86+
.add_message(new_msg)
87+
.add_attribute("action", "handle_increment")
88+
};
89+
90+
if json_payload.send_async_ack_for_prev_msg {
91+
Ok(
92+
resp.add_message(cosmwasm_std::Ibc2Msg::WriteAcknowledgement {
93+
channel_id: state.last_channel_id,
94+
packet_sequence: state.last_packet_seq,
95+
ack: IbcAcknowledgement::new([1, 2, 3]),
96+
}),
97+
)
98+
} else {
99+
Ok(resp)
100+
}
77101
}

contracts/ibc2/src/msg.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,9 @@ pub enum QueryMsg {
66
#[returns(crate::state::State)]
77
QueryState {},
88
}
9+
10+
#[cw_serde]
11+
pub struct IbcPayload {
12+
pub response_without_ack: bool,
13+
pub send_async_ack_for_prev_msg: bool,
14+
}

contracts/ibc2/src/state.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ use serde::{Deserialize, Serialize};
44
#[derive(Default, Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)]
55
pub struct State {
66
pub ibc2_packet_receive_counter: u32,
7+
pub last_channel_id: String,
8+
pub last_packet_seq: u64,
79
}
810

911
pub const STATE_KEY: &[u8] = b"state";

packages/std/src/ibc2.rs

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use schemars::JsonSchema;
22
use serde::{Deserialize, Serialize};
33

4-
use crate::{Addr, Binary, Timestamp};
4+
use crate::{Addr, Binary, IbcAcknowledgement, Timestamp};
55

66
/// Payload value should be encoded in a format defined by the channel version,
77
/// and the module on the other side should know how to parse this.
@@ -51,6 +51,16 @@ pub enum Ibc2Msg {
5151
timeout: Timestamp,
5252
payloads: Vec<Ibc2Payload>,
5353
},
54+
/// Acknowledges a packet that this contract received over IBC.
55+
/// This allows acknowledging a packet that was not acknowledged yet in the `ibc2_packet_receive` call.
56+
WriteAcknowledgement {
57+
/// Existing channel where the packet was received
58+
channel_id: String,
59+
/// Sequence number of the packet that was received
60+
packet_sequence: u64,
61+
/// The acknowledgement to send back
62+
ack: IbcAcknowledgement,
63+
},
5464
}
5565

5666
/// The message that is passed into `ibc2_packet_receive`
@@ -60,14 +70,21 @@ pub struct Ibc2PacketReceiveMsg {
6070
pub payload: Ibc2Payload,
6171
pub relayer: Addr,
6272
pub source_client: String,
73+
pub packet_sequence: u64,
6374
}
6475

6576
impl Ibc2PacketReceiveMsg {
66-
pub fn new(payload: Ibc2Payload, relayer: Addr, source_client: String) -> Self {
77+
pub fn new(
78+
payload: Ibc2Payload,
79+
relayer: Addr,
80+
source_client: String,
81+
packet_sequence: u64,
82+
) -> Self {
6783
Self {
6884
payload,
6985
relayer,
7086
source_client,
87+
packet_sequence,
7188
}
7289
}
7390
}

packages/std/src/testing/mock.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -528,6 +528,7 @@ pub fn mock_ibc2_packet_recv(data: &impl Serialize) -> StdResult<Ibc2PacketRecei
528528
},
529529
Addr::unchecked("relayer"),
530530
"channel_id23".to_string(),
531+
42,
531532
))
532533
}
533534

0 commit comments

Comments
 (0)