ibc_core_channel_types/msgs/
timeout.rs

1use ibc_core_client_types::Height;
2use ibc_core_commitment_types::commitment::CommitmentProofBytes;
3use ibc_core_host_types::error::DecodingError;
4use ibc_core_host_types::identifiers::Sequence;
5use ibc_primitives::prelude::*;
6use ibc_primitives::Signer;
7use ibc_proto::ibc::core::channel::v1::MsgTimeout as RawMsgTimeout;
8use ibc_proto::Protobuf;
9
10use crate::packet::Packet;
11
12pub const TIMEOUT_TYPE_URL: &str = "/ibc.core.channel.v1.MsgTimeout";
13
14///
15/// Message definition for packet timeout domain type,
16/// which is sent on chain A and needs to prove that a previously sent packet was not received on chain B
17///
18#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
19#[cfg_attr(
20    feature = "borsh",
21    derive(borsh::BorshSerialize, borsh::BorshDeserialize)
22)]
23#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
24#[derive(Clone, Debug, PartialEq, Eq)]
25pub struct MsgTimeout {
26    pub packet: Packet,
27    pub next_seq_recv_on_b: Sequence,
28    pub proof_unreceived_on_b: CommitmentProofBytes,
29    pub proof_height_on_b: Height,
30    pub signer: Signer,
31}
32
33impl Protobuf<RawMsgTimeout> for MsgTimeout {}
34
35impl TryFrom<RawMsgTimeout> for MsgTimeout {
36    type Error = DecodingError;
37
38    fn try_from(raw_msg: RawMsgTimeout) -> Result<Self, Self::Error> {
39        if raw_msg.next_sequence_recv == 0 {
40            return Err(DecodingError::invalid_raw_data(
41                "msg timeout packet sequence cannot be 0",
42            ));
43        }
44        Ok(MsgTimeout {
45            packet: raw_msg
46                .packet
47                .ok_or(DecodingError::missing_raw_data("msg timeout packet data"))?
48                .try_into()?,
49            next_seq_recv_on_b: Sequence::from(raw_msg.next_sequence_recv),
50            proof_unreceived_on_b: raw_msg.proof_unreceived.try_into()?,
51            proof_height_on_b: raw_msg
52                .proof_height
53                .and_then(|raw_height| raw_height.try_into().ok())
54                .ok_or(DecodingError::missing_raw_data("msg timeout proof height"))?,
55            signer: raw_msg.signer.into(),
56        })
57    }
58}
59
60impl From<MsgTimeout> for RawMsgTimeout {
61    fn from(domain_msg: MsgTimeout) -> Self {
62        RawMsgTimeout {
63            packet: Some(domain_msg.packet.into()),
64            proof_unreceived: domain_msg.proof_unreceived_on_b.into(),
65            proof_height: Some(domain_msg.proof_height_on_b.into()),
66            next_sequence_recv: domain_msg.next_seq_recv_on_b.into(),
67            signer: domain_msg.signer.to_string(),
68        }
69    }
70}