ibc_client_cw/types/
msgs.rs

1//! Defines the messages sent to the CosmWasm contract by the 08-wasm proxy
2//! light client.
3use cosmwasm_schema::{cw_serde, QueryResponses};
4use cosmwasm_std::Binary;
5use ibc_core::client::types::proto::v1::Height as RawHeight;
6use ibc_core::client::types::Height;
7use ibc_core::commitment_types::commitment::{CommitmentPrefix, CommitmentProofBytes};
8use ibc_core::host::types::path::PathBytes;
9use ibc_core::primitives::proto::Any;
10use prost::Message;
11
12use super::error::ContractError;
13
14// ------------------------------------------------------------
15// Implementation of the InstantiateMsg struct
16// ------------------------------------------------------------
17
18#[cw_serde]
19pub struct InstantiateMsg {
20    pub client_state: Binary,
21    pub consensus_state: Binary,
22    pub checksum: Binary,
23}
24
25// ------------------------------------------------------------
26// Implementation of the SudoMsg enum and its variants
27// ------------------------------------------------------------
28
29#[derive(derive_more::From)]
30#[cw_serde]
31pub enum SudoMsg {
32    UpdateState(UpdateStateMsgRaw),
33    UpdateStateOnMisbehaviour(UpdateStateOnMisbehaviourMsgRaw),
34    VerifyUpgradeAndUpdateState(VerifyUpgradeAndUpdateStateMsgRaw),
35    VerifyMembership(VerifyMembershipMsgRaw),
36    VerifyNonMembership(VerifyNonMembershipMsgRaw),
37    MigrateClientStore(MigrateClientStoreMsg),
38}
39
40#[cw_serde]
41pub struct UpdateStateOnMisbehaviourMsgRaw {
42    pub client_message: Binary,
43}
44
45pub struct UpdateStateOnMisbehaviourMsg {
46    pub client_message: Any,
47}
48
49impl TryFrom<UpdateStateOnMisbehaviourMsgRaw> for UpdateStateOnMisbehaviourMsg {
50    type Error = ContractError;
51
52    fn try_from(raw: UpdateStateOnMisbehaviourMsgRaw) -> Result<Self, Self::Error> {
53        let client_message = Any::decode(&mut raw.client_message.as_slice())?;
54
55        Ok(Self { client_message })
56    }
57}
58
59#[cw_serde]
60pub struct UpdateStateMsgRaw {
61    pub client_message: Binary,
62}
63
64pub struct UpdateStateMsg {
65    pub client_message: Any,
66}
67
68impl TryFrom<UpdateStateMsgRaw> for UpdateStateMsg {
69    type Error = ContractError;
70
71    fn try_from(raw: UpdateStateMsgRaw) -> Result<Self, Self::Error> {
72        let client_message = Any::decode(&mut raw.client_message.as_slice())?;
73
74        Ok(Self { client_message })
75    }
76}
77
78#[cw_serde]
79pub struct CheckSubstituteAndUpdateStateMsg {}
80
81#[cw_serde]
82pub struct VerifyUpgradeAndUpdateStateMsgRaw {
83    pub upgrade_client_state: Binary,
84    pub upgrade_consensus_state: Binary,
85    pub proof_upgrade_client: Binary,
86    pub proof_upgrade_consensus_state: Binary,
87}
88
89pub struct VerifyUpgradeAndUpdateStateMsg {
90    pub upgrade_client_state: Any,
91    pub upgrade_consensus_state: Any,
92    pub proof_upgrade_client: CommitmentProofBytes,
93    pub proof_upgrade_consensus_state: CommitmentProofBytes,
94}
95
96impl TryFrom<VerifyUpgradeAndUpdateStateMsgRaw> for VerifyUpgradeAndUpdateStateMsg {
97    type Error = ContractError;
98
99    fn try_from(raw: VerifyUpgradeAndUpdateStateMsgRaw) -> Result<Self, Self::Error> {
100        let upgrade_client_state = Any::decode(&mut raw.upgrade_client_state.as_slice())?;
101
102        let upgrade_consensus_state = Any::decode(&mut raw.upgrade_consensus_state.as_slice())?;
103
104        Ok(Self {
105            upgrade_client_state,
106            upgrade_consensus_state,
107            proof_upgrade_client: CommitmentProofBytes::try_from(
108                raw.proof_upgrade_client.to_vec(),
109            )?,
110            proof_upgrade_consensus_state: CommitmentProofBytes::try_from(
111                raw.proof_upgrade_consensus_state.to_vec(),
112            )?,
113        })
114    }
115}
116
117#[cw_serde]
118pub struct MerklePath {
119    pub key_path: Vec<Binary>,
120}
121
122#[cw_serde]
123pub struct VerifyMembershipMsgRaw {
124    pub proof: Binary,
125    pub merkle_path: MerklePath,
126    pub value: Binary,
127    pub height: RawHeight,
128    pub delay_block_period: u64,
129    pub delay_time_period: u64,
130}
131
132pub struct VerifyMembershipMsg {
133    pub prefix: CommitmentPrefix,
134    pub proof: CommitmentProofBytes,
135    pub path: PathBytes,
136    pub value: Vec<u8>,
137    pub height: Height,
138    pub delay_block_period: u64,
139    pub delay_time_period: u64,
140}
141
142impl TryFrom<VerifyMembershipMsgRaw> for VerifyMembershipMsg {
143    type Error = ContractError;
144
145    fn try_from(mut raw: VerifyMembershipMsgRaw) -> Result<Self, Self::Error> {
146        let proof = CommitmentProofBytes::try_from(raw.proof.to_vec())?;
147        let prefix = CommitmentPrefix::from_bytes(raw.merkle_path.key_path.remove(0));
148        let path = PathBytes::flatten(raw.merkle_path.key_path);
149        let height = Height::try_from(raw.height)?;
150
151        Ok(Self {
152            proof,
153            path,
154            value: raw.value.into(),
155            height,
156            prefix,
157            delay_block_period: raw.delay_block_period,
158            delay_time_period: raw.delay_time_period,
159        })
160    }
161}
162
163#[cw_serde]
164pub struct VerifyNonMembershipMsgRaw {
165    pub proof: Binary,
166    pub merkle_path: MerklePath,
167    pub height: RawHeight,
168    pub delay_block_period: u64,
169    pub delay_time_period: u64,
170}
171
172pub struct VerifyNonMembershipMsg {
173    pub prefix: CommitmentPrefix,
174    pub proof: CommitmentProofBytes,
175    pub path: PathBytes,
176    pub height: Height,
177    pub delay_block_period: u64,
178    pub delay_time_period: u64,
179}
180
181impl TryFrom<VerifyNonMembershipMsgRaw> for VerifyNonMembershipMsg {
182    type Error = ContractError;
183
184    fn try_from(mut raw: VerifyNonMembershipMsgRaw) -> Result<Self, Self::Error> {
185        let proof = CommitmentProofBytes::try_from(raw.proof.to_vec())?;
186        let prefix = CommitmentPrefix::from_bytes(raw.merkle_path.key_path.remove(0));
187        let path = PathBytes::flatten(raw.merkle_path.key_path);
188        let height = raw.height.try_into()?;
189
190        Ok(Self {
191            proof,
192            path,
193            height,
194            prefix,
195            delay_block_period: raw.delay_block_period,
196            delay_time_period: raw.delay_time_period,
197        })
198    }
199}
200
201#[cw_serde]
202pub struct MigrateClientStoreMsg {}
203
204// ------------------------------------------------------------
205// Implementation of the QueryMsg enum and its variants
206// ------------------------------------------------------------
207
208#[derive(QueryResponses, derive_more::From)]
209#[cw_serde]
210pub enum QueryMsg {
211    #[returns(crate::types::response::StatusResponse)]
212    Status(StatusMsg),
213    #[returns(crate::types::response::TimestampAtHeightResponse)]
214    TimestampAtHeight(TimestampAtHeightMsg),
215    #[returns(crate::types::response::VerifyClientMessageResponse)]
216    VerifyClientMessage(VerifyClientMessageRaw),
217    #[returns(crate::types::response::CheckForMisbehaviourResponse)]
218    CheckForMisbehaviour(CheckForMisbehaviourMsgRaw),
219}
220
221#[cw_serde]
222pub struct StatusMsg {}
223
224#[cw_serde]
225pub struct TimestampAtHeightMsg {
226    pub height: Height,
227}
228
229#[cw_serde]
230pub struct VerifyClientMessageRaw {
231    pub client_message: Binary,
232}
233
234pub struct VerifyClientMessageMsg {
235    pub client_message: Any,
236}
237
238impl TryFrom<VerifyClientMessageRaw> for VerifyClientMessageMsg {
239    type Error = ContractError;
240
241    fn try_from(raw: VerifyClientMessageRaw) -> Result<Self, Self::Error> {
242        let client_message = Any::decode(&mut raw.client_message.as_slice())?;
243
244        Ok(Self { client_message })
245    }
246}
247
248#[cw_serde]
249pub struct CheckForMisbehaviourMsgRaw {
250    pub client_message: Binary,
251}
252
253pub struct CheckForMisbehaviourMsg {
254    pub client_message: Any,
255}
256
257impl TryFrom<CheckForMisbehaviourMsgRaw> for CheckForMisbehaviourMsg {
258    type Error = ContractError;
259
260    fn try_from(raw: CheckForMisbehaviourMsgRaw) -> Result<Self, Self::Error> {
261        let client_message = Any::decode(&mut raw.client_message.as_slice())?;
262
263        Ok(Self { client_message })
264    }
265}
266
267#[cfg(test)]
268mod test {
269    use super::{InstantiateMsg, SudoMsg};
270
271    #[test]
272    fn verify_membership_from_json() {
273        let sudo_msg = r#"{
274            "verify_membership":{
275                "height":
276                    {"revision_height":57},
277                "delay_time_period":0,
278                "delay_block_period":0,
279                "proof":"CuECCt4CChhjb25uZWN0aW9ucy9jb25uZWN0aW9uLTASWgoPMDctdGVuZGVybWludC0wEiMKATESDU9SREVSX09SREVSRUQSD09SREVSX1VOT1JERVJFRBgCIiAKCTA4LXdhc20tMBIMY29ubmVjdGlvbi0wGgUKA2liYxoLCAEYASABKgMAAkgiKQgBEiUCBHAg3HTYmBAMxlr6u0mv6wCpm3ur2WQc7A3Af6aV7Ye0Fe0gIisIARIEBAZwIBohIHXEkQ9RIH08ZZYBIP6THxOOJiRmjXWGn1G4RCWT3V6rIisIARIEBgxwIBohIEUjGWV7YLPEzdFVLAb0lv4VvP7A+l1TqFkjpx1kDKAPIikIARIlCBhwILWsAKEot+2MknVyn5zcS0qsqVhRj4AHpgDx7fNPbfhtICIpCAESJQxAcCCzyYMGE+CdCltudr1ddHvCJrqv3kl/i7YnMLx3XWJt/yAK/AEK+QEKA2liYxIg2nvqL76rejXXGlX6ng/UKrbw+72C8uKKgM2vP0JKj1QaCQgBGAEgASoBACIlCAESIQEGuZwNgRn/HtvL4WXQ8ZM327wIDmd8iOV6oq52fr8PDyInCAESAQEaIKplBAbqDXbjndQ9LqapHj/aockI/CGnymjl5izIEVY5IiUIARIhAdt4G8DCLINAaaJnhUMIzv74AV3zZiugAyyZ/lWYRv+cIiUIARIhAf+sohoEV+uWeKThAPEbqCUivWT4H8KNT7Giw9//LsyvIicIARIBARogNHO4HC5KxPCwBdQGgBCscVtEKw+YSn2pnf654Y3Oxik=",
280                "merkle_path":{"key_path":["aWJj","Y29ubmVjdGlvbnMvY29ubmVjdGlvbi0w"]},
281                "value":"Cg8wNy10ZW5kZXJtaW50LTASIwoBMRINT1JERVJfT1JERVJFRBIPT1JERVJfVU5PUkRFUkVEGAIiIAoJMDgtd2FzbS0wEgxjb25uZWN0aW9uLTAaBQoDaWJj"
282            }
283        }"#;
284        assert!(matches!(
285            serde_json::from_str::<SudoMsg>(sudo_msg).unwrap(),
286            SudoMsg::VerifyMembership(_)
287        ));
288    }
289
290    #[test]
291    fn instantiate_msg_from_json() {
292        let instantiate_msg = r#"{
293            "client_state":"Y2xpZW50X3N0YXRlCg==",
294            "consensus_state":"Y29uc2Vuc3VzX3N0YXRlCg==",
295            "checksum":"Y2hlY2tzdW0K"
296        }"#;
297        serde_json::from_str::<InstantiateMsg>(instantiate_msg).unwrap();
298    }
299}