1use 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#[cw_serde]
19pub struct InstantiateMsg {
20 pub client_state: Binary,
21 pub consensus_state: Binary,
22 pub checksum: Binary,
23}
24
25#[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#[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}