ibc_relayer_types/
events.rs

1use std::borrow::Cow;
2use std::fmt::{Display, Error as FmtError, Formatter};
3use std::str::FromStr;
4
5use flex_error::{define_error, TraceError};
6use serde_derive::{Deserialize, Serialize};
7use tendermint::abci;
8
9use crate::applications::ics29_fee::error::Error as FeeError;
10use crate::applications::ics29_fee::events::{DistributeFeePacket, IncentivizedPacket};
11use crate::applications::ics31_icq::error::Error as QueryPacketError;
12use crate::applications::ics31_icq::events::CrossChainQueryPacket;
13use crate::core::ics02_client::error as client_error;
14use crate::core::ics02_client::events as ClientEvents;
15use crate::core::ics02_client::events::NewBlock;
16use crate::core::ics03_connection::error as connection_error;
17use crate::core::ics03_connection::events as ConnectionEvents;
18use crate::core::ics03_connection::events::Attributes as ConnectionAttributes;
19use crate::core::ics04_channel::error as channel_error;
20use crate::core::ics04_channel::events::Attributes as ChannelAttributes;
21use crate::core::ics04_channel::events::{self as ChannelEvents, UpgradeAttributes};
22use crate::core::ics04_channel::packet::Packet;
23use crate::core::ics24_host::error::ValidationError;
24use crate::timestamp::ParseTimestampError;
25use crate::utils::pretty::PrettySlice;
26
27define_error! {
28    Error {
29        Height
30            | _ | { "error parsing height" },
31
32        Parse
33            [ ValidationError ]
34            | _ | { "parse error" },
35
36        Client
37            [ client_error::Error ]
38            | _ | { "ICS02 client error" },
39
40        Connection
41            [ connection_error::Error ]
42            | _ | { "connection error" },
43
44        Channel
45            [ channel_error::Error ]
46            | _ | { "channel error" },
47
48        Fee
49            [ FeeError ]
50            | _ | { "fee error" },
51
52        CrossChainQuery
53            [ QueryPacketError ]
54            | _ | { "cross chain query error" },
55
56        Timestamp
57            [ ParseTimestampError ]
58            | _ | { "error parsing timestamp" },
59
60        MissingKey
61            { key: String }
62            | e | { format_args!("missing event key {}", e.key) },
63
64        Decode
65            [ TraceError<prost::DecodeError> ]
66            | _ | { "error decoding protobuf" },
67
68        InvalidPacketData
69            { data: String }
70            | e | { format_args!("error decoding hex-encoded packet data: {}", e.data) },
71
72        InvalidPacketAck
73            { ack: String }
74            | e | { format_args!("error decoding hex-encoded packet ack: {}", e.ack) },
75
76        MissingActionString
77            | _ | { "missing action string" },
78
79        IncorrectEventType
80            { event: String }
81            | e | { format_args!("incorrect event type: {}", e.event) },
82
83        MalformedModuleEvent
84            { event: ModuleEvent }
85            | e | { format_args!("module event cannot use core event types: {:?}", e.event) },
86
87        UnsupportedAbciEvent
88            {event_type: String}
89            |e| { format_args!("Unable to parse abci event type '{}' into IbcEvent", e.event_type)}
90    }
91}
92
93/// Events whose data is not included in the app state and must be extracted using tendermint RPCs
94/// (i.e. /tx_search or /block_search)
95#[derive(Debug, Clone, Deserialize, Serialize)]
96pub enum WithBlockDataType {
97    CreateClient,
98    UpdateClient,
99    SendPacket,
100    WriteAck,
101}
102
103impl WithBlockDataType {
104    pub fn as_str(&self) -> &'static str {
105        match *self {
106            WithBlockDataType::CreateClient => "create_client",
107            WithBlockDataType::UpdateClient => "update_client",
108            WithBlockDataType::SendPacket => "send_packet",
109            WithBlockDataType::WriteAck => "write_acknowledgement",
110        }
111    }
112}
113
114const NEW_BLOCK_EVENT: &str = "new_block";
115const EMPTY_EVENT: &str = "empty";
116const CHAIN_ERROR_EVENT: &str = "chain_error";
117const APP_MODULE_EVENT: &str = "app_module";
118/// Client event types
119const CREATE_CLIENT_EVENT: &str = "create_client";
120const UPDATE_CLIENT_EVENT: &str = "update_client";
121const CLIENT_MISBEHAVIOUR_EVENT: &str = "client_misbehaviour";
122const UPGRADE_CLIENT_EVENT: &str = "upgrade_client";
123/// Connection event types
124const CONNECTION_INIT_EVENT: &str = "connection_open_init";
125const CONNECTION_TRY_EVENT: &str = "connection_open_try";
126const CONNECTION_ACK_EVENT: &str = "connection_open_ack";
127const CONNECTION_CONFIRM_EVENT: &str = "connection_open_confirm";
128/// Channel event types
129const CHANNEL_OPEN_INIT_EVENT: &str = "channel_open_init";
130const CHANNEL_OPEN_TRY_EVENT: &str = "channel_open_try";
131const CHANNEL_OPEN_ACK_EVENT: &str = "channel_open_ack";
132const CHANNEL_OPEN_CONFIRM_EVENT: &str = "channel_open_confirm";
133const CHANNEL_CLOSE_INIT_EVENT: &str = "channel_close_init";
134const CHANNEL_CLOSE_CONFIRM_EVENT: &str = "channel_close_confirm";
135/// Channel upgrade event types
136const CHANNEL_UPGRADE_INIT_EVENT: &str = "channel_upgrade_init";
137const CHANNEL_UPGRADE_TRY_EVENT: &str = "channel_upgrade_try";
138const CHANNEL_UPGRADE_ACK_EVENT: &str = "channel_upgrade_ack";
139const CHANNEL_UPGRADE_CONFIRM_EVENT: &str = "channel_upgrade_confirm";
140const CHANNEL_UPGRADE_OPEN_EVENT: &str = "channel_upgrade_open";
141const CHANNEL_UPGRADE_CANCEL_EVENT: &str = "channel_upgrade_cancelled";
142const CHANNEL_UPGRADE_TIMEOUT_EVENT: &str = "channel_upgrade_timeout";
143const CHANNEL_UPGRADE_ERROR_EVENT: &str = "channel_upgrade_error";
144/// Packet event types
145const SEND_PACKET_EVENT: &str = "send_packet";
146const RECEIVE_PACKET_EVENT: &str = "receive_packet";
147const WRITE_ACK_EVENT: &str = "write_acknowledgement";
148const ACK_PACKET_EVENT: &str = "acknowledge_packet";
149const TIMEOUT_EVENT: &str = "timeout_packet";
150const TIMEOUT_ON_CLOSE_EVENT: &str = "timeout_packet_on_close";
151const INCENTIVIZED_PACKET_EVENT: &str = "incentivized_ibc_packet";
152/// CrossChainQuery event type
153const CROSS_CHAIN_QUERY_PACKET_EVENT: &str = "cross_chain_query";
154/// Distribution fee event type
155const DISTRIBUTION_FEE_PACKET_EVENT: &str = "distribute_fee";
156
157/// Events types
158#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
159pub enum IbcEventType {
160    NewBlock,
161    CreateClient,
162    UpdateClient,
163    UpgradeClient,
164    ClientMisbehaviour,
165    OpenInitConnection,
166    OpenTryConnection,
167    OpenAckConnection,
168    OpenConfirmConnection,
169    OpenInitChannel,
170    OpenTryChannel,
171    OpenAckChannel,
172    OpenConfirmChannel,
173    CloseInitChannel,
174    CloseConfirmChannel,
175    UpgradeInitChannel,
176    UpgradeTryChannel,
177    UpgradeAckChannel,
178    UpgradeConfirmChannel,
179    UpgradeOpenChannel,
180    UpgradeCancelChannel,
181    UpgradeTimeoutChannel,
182    UpgradeErrorChannel,
183    SendPacket,
184    ReceivePacket,
185    WriteAck,
186    AckPacket,
187    Timeout,
188    TimeoutOnClose,
189    IncentivizedPacket,
190    CrossChainQuery,
191    AppModule,
192    Empty,
193    ChainError,
194    DistributionFee,
195}
196
197impl IbcEventType {
198    pub fn as_str(&self) -> &'static str {
199        match *self {
200            IbcEventType::NewBlock => NEW_BLOCK_EVENT,
201            IbcEventType::CreateClient => CREATE_CLIENT_EVENT,
202            IbcEventType::UpdateClient => UPDATE_CLIENT_EVENT,
203            IbcEventType::UpgradeClient => UPGRADE_CLIENT_EVENT,
204            IbcEventType::ClientMisbehaviour => CLIENT_MISBEHAVIOUR_EVENT,
205            IbcEventType::OpenInitConnection => CONNECTION_INIT_EVENT,
206            IbcEventType::OpenTryConnection => CONNECTION_TRY_EVENT,
207            IbcEventType::OpenAckConnection => CONNECTION_ACK_EVENT,
208            IbcEventType::OpenConfirmConnection => CONNECTION_CONFIRM_EVENT,
209            IbcEventType::OpenInitChannel => CHANNEL_OPEN_INIT_EVENT,
210            IbcEventType::OpenTryChannel => CHANNEL_OPEN_TRY_EVENT,
211            IbcEventType::OpenAckChannel => CHANNEL_OPEN_ACK_EVENT,
212            IbcEventType::OpenConfirmChannel => CHANNEL_OPEN_CONFIRM_EVENT,
213            IbcEventType::CloseInitChannel => CHANNEL_CLOSE_INIT_EVENT,
214            IbcEventType::CloseConfirmChannel => CHANNEL_CLOSE_CONFIRM_EVENT,
215            IbcEventType::UpgradeInitChannel => CHANNEL_UPGRADE_INIT_EVENT,
216            IbcEventType::UpgradeTryChannel => CHANNEL_UPGRADE_TRY_EVENT,
217            IbcEventType::UpgradeAckChannel => CHANNEL_UPGRADE_ACK_EVENT,
218            IbcEventType::UpgradeConfirmChannel => CHANNEL_UPGRADE_CONFIRM_EVENT,
219            IbcEventType::UpgradeOpenChannel => CHANNEL_UPGRADE_OPEN_EVENT,
220            IbcEventType::UpgradeCancelChannel => CHANNEL_UPGRADE_CANCEL_EVENT,
221            IbcEventType::UpgradeTimeoutChannel => CHANNEL_UPGRADE_TIMEOUT_EVENT,
222            IbcEventType::UpgradeErrorChannel => CHANNEL_UPGRADE_ERROR_EVENT,
223            IbcEventType::SendPacket => SEND_PACKET_EVENT,
224            IbcEventType::ReceivePacket => RECEIVE_PACKET_EVENT,
225            IbcEventType::WriteAck => WRITE_ACK_EVENT,
226            IbcEventType::AckPacket => ACK_PACKET_EVENT,
227            IbcEventType::Timeout => TIMEOUT_EVENT,
228            IbcEventType::TimeoutOnClose => TIMEOUT_ON_CLOSE_EVENT,
229            IbcEventType::IncentivizedPacket => INCENTIVIZED_PACKET_EVENT,
230            IbcEventType::CrossChainQuery => CROSS_CHAIN_QUERY_PACKET_EVENT,
231            IbcEventType::AppModule => APP_MODULE_EVENT,
232            IbcEventType::Empty => EMPTY_EVENT,
233            IbcEventType::ChainError => CHAIN_ERROR_EVENT,
234            IbcEventType::DistributionFee => DISTRIBUTION_FEE_PACKET_EVENT,
235        }
236    }
237}
238
239impl FromStr for IbcEventType {
240    type Err = Error;
241
242    fn from_str(s: &str) -> Result<Self, Self::Err> {
243        match s {
244            NEW_BLOCK_EVENT => Ok(IbcEventType::NewBlock),
245            CREATE_CLIENT_EVENT => Ok(IbcEventType::CreateClient),
246            UPDATE_CLIENT_EVENT => Ok(IbcEventType::UpdateClient),
247            UPGRADE_CLIENT_EVENT => Ok(IbcEventType::UpgradeClient),
248            CLIENT_MISBEHAVIOUR_EVENT => Ok(IbcEventType::ClientMisbehaviour),
249            CONNECTION_INIT_EVENT => Ok(IbcEventType::OpenInitConnection),
250            CONNECTION_TRY_EVENT => Ok(IbcEventType::OpenTryConnection),
251            CONNECTION_ACK_EVENT => Ok(IbcEventType::OpenAckConnection),
252            CONNECTION_CONFIRM_EVENT => Ok(IbcEventType::OpenConfirmConnection),
253            CHANNEL_OPEN_INIT_EVENT => Ok(IbcEventType::OpenInitChannel),
254            CHANNEL_OPEN_TRY_EVENT => Ok(IbcEventType::OpenTryChannel),
255            CHANNEL_OPEN_ACK_EVENT => Ok(IbcEventType::OpenAckChannel),
256            CHANNEL_OPEN_CONFIRM_EVENT => Ok(IbcEventType::OpenConfirmChannel),
257            CHANNEL_CLOSE_INIT_EVENT => Ok(IbcEventType::CloseInitChannel),
258            CHANNEL_CLOSE_CONFIRM_EVENT => Ok(IbcEventType::CloseConfirmChannel),
259            CHANNEL_UPGRADE_INIT_EVENT => Ok(IbcEventType::UpgradeInitChannel),
260            CHANNEL_UPGRADE_TRY_EVENT => Ok(IbcEventType::UpgradeTryChannel),
261            CHANNEL_UPGRADE_ACK_EVENT => Ok(IbcEventType::UpgradeAckChannel),
262            CHANNEL_UPGRADE_CONFIRM_EVENT => Ok(IbcEventType::UpgradeConfirmChannel),
263            CHANNEL_UPGRADE_OPEN_EVENT => Ok(IbcEventType::UpgradeOpenChannel),
264            CHANNEL_UPGRADE_CANCEL_EVENT => Ok(IbcEventType::UpgradeCancelChannel),
265            CHANNEL_UPGRADE_TIMEOUT_EVENT => Ok(IbcEventType::UpgradeTimeoutChannel),
266            CHANNEL_UPGRADE_ERROR_EVENT => Ok(IbcEventType::UpgradeErrorChannel),
267            SEND_PACKET_EVENT => Ok(IbcEventType::SendPacket),
268            RECEIVE_PACKET_EVENT => Ok(IbcEventType::ReceivePacket),
269            WRITE_ACK_EVENT => Ok(IbcEventType::WriteAck),
270            ACK_PACKET_EVENT => Ok(IbcEventType::AckPacket),
271            TIMEOUT_EVENT => Ok(IbcEventType::Timeout),
272            TIMEOUT_ON_CLOSE_EVENT => Ok(IbcEventType::TimeoutOnClose),
273            INCENTIVIZED_PACKET_EVENT => Ok(IbcEventType::IncentivizedPacket),
274            CROSS_CHAIN_QUERY_PACKET_EVENT => Ok(IbcEventType::CrossChainQuery),
275            EMPTY_EVENT => Ok(IbcEventType::Empty),
276            CHAIN_ERROR_EVENT => Ok(IbcEventType::ChainError),
277            DISTRIBUTION_FEE_PACKET_EVENT => Ok(IbcEventType::DistributionFee),
278            // from_str() for `APP_MODULE_EVENT` MUST fail because a `ModuleEvent`'s type isn't constant
279            _ => Err(Error::incorrect_event_type(s.to_string())),
280        }
281    }
282}
283
284/// Events created by the IBC component of a chain, destined for a relayer.
285#[derive(Debug, Clone, Serialize, PartialEq)]
286pub enum IbcEvent {
287    NewBlock(NewBlock),
288
289    CreateClient(ClientEvents::CreateClient),
290    UpdateClient(ClientEvents::UpdateClient),
291    UpgradeClient(ClientEvents::UpgradeClient),
292    ClientMisbehaviour(ClientEvents::ClientMisbehaviour),
293
294    OpenInitConnection(ConnectionEvents::OpenInit),
295    OpenTryConnection(ConnectionEvents::OpenTry),
296    OpenAckConnection(ConnectionEvents::OpenAck),
297    OpenConfirmConnection(ConnectionEvents::OpenConfirm),
298
299    OpenInitChannel(ChannelEvents::OpenInit),
300    OpenTryChannel(ChannelEvents::OpenTry),
301    OpenAckChannel(ChannelEvents::OpenAck),
302    OpenConfirmChannel(ChannelEvents::OpenConfirm),
303    CloseInitChannel(ChannelEvents::CloseInit),
304    CloseConfirmChannel(ChannelEvents::CloseConfirm),
305    UpgradeInitChannel(ChannelEvents::UpgradeInit),
306    UpgradeTryChannel(ChannelEvents::UpgradeTry),
307    UpgradeAckChannel(ChannelEvents::UpgradeAck),
308    UpgradeConfirmChannel(ChannelEvents::UpgradeConfirm),
309    UpgradeOpenChannel(ChannelEvents::UpgradeOpen),
310    UpgradeCancelChannel(ChannelEvents::UpgradeCancel),
311    UpgradeTimeoutChannel(ChannelEvents::UpgradeTimeout),
312    UpgradeErrorChannel(ChannelEvents::UpgradeError),
313
314    SendPacket(ChannelEvents::SendPacket),
315    ReceivePacket(ChannelEvents::ReceivePacket),
316    WriteAcknowledgement(ChannelEvents::WriteAcknowledgement),
317    AcknowledgePacket(ChannelEvents::AcknowledgePacket),
318    TimeoutPacket(ChannelEvents::TimeoutPacket),
319    TimeoutOnClosePacket(ChannelEvents::TimeoutOnClosePacket),
320
321    IncentivizedPacket(IncentivizedPacket),
322    CrossChainQueryPacket(CrossChainQueryPacket),
323
324    DistributeFeePacket(DistributeFeePacket),
325
326    AppModule(ModuleEvent),
327
328    ChainError(String), // Special event, signifying an error on CheckTx or DeliverTx
329}
330
331impl Display for IbcEvent {
332    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
333        match self {
334            IbcEvent::NewBlock(ev) => write!(f, "NewBlock({})", ev.height),
335
336            IbcEvent::CreateClient(ev) => write!(f, "CreateClient({ev})"),
337            IbcEvent::UpdateClient(ev) => write!(f, "UpdateClient({ev})"),
338            IbcEvent::UpgradeClient(ev) => write!(f, "UpgradeClient({ev})"),
339            IbcEvent::ClientMisbehaviour(ev) => write!(f, "ClientMisbehaviour({ev})"),
340
341            IbcEvent::OpenInitConnection(ev) => write!(f, "OpenInitConnection({ev})"),
342            IbcEvent::OpenTryConnection(ev) => write!(f, "OpenTryConnection({ev})"),
343            IbcEvent::OpenAckConnection(ev) => write!(f, "OpenAckConnection({ev})"),
344            IbcEvent::OpenConfirmConnection(ev) => write!(f, "OpenConfirmConnection({ev})"),
345
346            IbcEvent::OpenInitChannel(ev) => write!(f, "OpenInitChannel({ev})"),
347            IbcEvent::OpenTryChannel(ev) => write!(f, "OpenTryChannel({ev})"),
348            IbcEvent::OpenAckChannel(ev) => write!(f, "OpenAckChannel({ev})"),
349            IbcEvent::OpenConfirmChannel(ev) => write!(f, "OpenConfirmChannel({ev})"),
350            IbcEvent::CloseInitChannel(ev) => write!(f, "CloseInitChannel({ev})"),
351            IbcEvent::CloseConfirmChannel(ev) => write!(f, "CloseConfirmChannel({ev})"),
352            IbcEvent::UpgradeInitChannel(ev) => write!(f, "UpgradeInitChannel({ev})"),
353            IbcEvent::UpgradeTryChannel(ev) => write!(f, "UpgradeTryChannel({ev})"),
354            IbcEvent::UpgradeAckChannel(ev) => write!(f, "UpgradeAckChannel({ev})"),
355            IbcEvent::UpgradeConfirmChannel(ev) => write!(f, "UpgradeConfirmChannel({ev})"),
356            IbcEvent::UpgradeOpenChannel(ev) => write!(f, "UpgradeOpenChannel({ev})"),
357            IbcEvent::UpgradeCancelChannel(ev) => write!(f, "UpgradeCancelChannel({ev})"),
358            IbcEvent::UpgradeTimeoutChannel(ev) => write!(f, "UpgradeTimeoutChannel({ev})"),
359            IbcEvent::UpgradeErrorChannel(ev) => write!(f, "UpgradeErrorChannel({ev})"),
360
361            IbcEvent::SendPacket(ev) => write!(f, "SendPacket({ev})"),
362            IbcEvent::ReceivePacket(ev) => write!(f, "ReceivePacket({ev})"),
363            IbcEvent::WriteAcknowledgement(ev) => write!(f, "WriteAcknowledgement({ev})"),
364            IbcEvent::AcknowledgePacket(ev) => write!(f, "AcknowledgePacket({ev})"),
365            IbcEvent::TimeoutPacket(ev) => write!(f, "TimeoutPacket({ev})"),
366            IbcEvent::TimeoutOnClosePacket(ev) => write!(f, "TimeoutOnClosePacket({ev})"),
367
368            IbcEvent::IncentivizedPacket(ev) => write!(f, "IncenvitizedPacket({ev:?}"),
369            IbcEvent::CrossChainQueryPacket(ev) => write!(f, "CrosschainPacket({ev:?})"),
370
371            IbcEvent::DistributeFeePacket(ev) => write!(f, "DistributionFeePacket({ev:?})"),
372
373            IbcEvent::AppModule(ev) => write!(f, "AppModule({ev})"),
374
375            IbcEvent::ChainError(ev) => write!(f, "ChainError({ev})"),
376        }
377    }
378}
379
380impl IbcEvent {
381    pub fn to_json(&self) -> String {
382        match serde_json::to_string(self) {
383            Ok(value) => value,
384            Err(_) => format!("{self:?}"), // Fallback to debug printing
385        }
386    }
387
388    pub fn event_type(&self) -> IbcEventType {
389        match self {
390            IbcEvent::NewBlock(_) => IbcEventType::NewBlock,
391            IbcEvent::CreateClient(_) => IbcEventType::CreateClient,
392            IbcEvent::UpdateClient(_) => IbcEventType::UpdateClient,
393            IbcEvent::ClientMisbehaviour(_) => IbcEventType::ClientMisbehaviour,
394            IbcEvent::UpgradeClient(_) => IbcEventType::UpgradeClient,
395            IbcEvent::OpenInitConnection(_) => IbcEventType::OpenInitConnection,
396            IbcEvent::OpenTryConnection(_) => IbcEventType::OpenTryConnection,
397            IbcEvent::OpenAckConnection(_) => IbcEventType::OpenAckConnection,
398            IbcEvent::OpenConfirmConnection(_) => IbcEventType::OpenConfirmConnection,
399            IbcEvent::OpenInitChannel(_) => IbcEventType::OpenInitChannel,
400            IbcEvent::OpenTryChannel(_) => IbcEventType::OpenTryChannel,
401            IbcEvent::OpenAckChannel(_) => IbcEventType::OpenAckChannel,
402            IbcEvent::OpenConfirmChannel(_) => IbcEventType::OpenConfirmChannel,
403            IbcEvent::CloseInitChannel(_) => IbcEventType::CloseInitChannel,
404            IbcEvent::CloseConfirmChannel(_) => IbcEventType::CloseConfirmChannel,
405            IbcEvent::UpgradeInitChannel(_) => IbcEventType::UpgradeInitChannel,
406            IbcEvent::UpgradeTryChannel(_) => IbcEventType::UpgradeTryChannel,
407            IbcEvent::UpgradeAckChannel(_) => IbcEventType::UpgradeAckChannel,
408            IbcEvent::UpgradeConfirmChannel(_) => IbcEventType::UpgradeConfirmChannel,
409            IbcEvent::UpgradeOpenChannel(_) => IbcEventType::UpgradeOpenChannel,
410            IbcEvent::UpgradeCancelChannel(_) => IbcEventType::UpgradeCancelChannel,
411            IbcEvent::UpgradeTimeoutChannel(_) => IbcEventType::UpgradeTimeoutChannel,
412            IbcEvent::UpgradeErrorChannel(_) => IbcEventType::UpgradeErrorChannel,
413            IbcEvent::SendPacket(_) => IbcEventType::SendPacket,
414            IbcEvent::ReceivePacket(_) => IbcEventType::ReceivePacket,
415            IbcEvent::WriteAcknowledgement(_) => IbcEventType::WriteAck,
416            IbcEvent::AcknowledgePacket(_) => IbcEventType::AckPacket,
417            IbcEvent::TimeoutPacket(_) => IbcEventType::Timeout,
418            IbcEvent::TimeoutOnClosePacket(_) => IbcEventType::TimeoutOnClose,
419            IbcEvent::IncentivizedPacket(_) => IbcEventType::IncentivizedPacket,
420            IbcEvent::CrossChainQueryPacket(_) => IbcEventType::CrossChainQuery,
421            IbcEvent::DistributeFeePacket(_) => IbcEventType::DistributionFee,
422            IbcEvent::AppModule(_) => IbcEventType::AppModule,
423            IbcEvent::ChainError(_) => IbcEventType::ChainError,
424        }
425    }
426
427    pub fn channel_attributes(self) -> Option<ChannelAttributes> {
428        match self {
429            IbcEvent::OpenInitChannel(ev) => Some(ev.into()),
430            IbcEvent::OpenTryChannel(ev) => Some(ev.into()),
431            IbcEvent::OpenAckChannel(ev) => Some(ev.into()),
432            IbcEvent::OpenConfirmChannel(ev) => Some(ev.into()),
433            _ => None,
434        }
435    }
436
437    pub fn channel_upgrade_attributes(self) -> Option<UpgradeAttributes> {
438        match self {
439            IbcEvent::UpgradeInitChannel(ev) => Some(ev.into()),
440            IbcEvent::UpgradeTryChannel(ev) => Some(ev.into()),
441            IbcEvent::UpgradeAckChannel(ev) => Some(ev.into()),
442            IbcEvent::UpgradeConfirmChannel(ev) => Some(ev.into()),
443            IbcEvent::UpgradeOpenChannel(ev) => Some(ev.into()),
444            IbcEvent::UpgradeCancelChannel(ev) => Some(ev.into()),
445            IbcEvent::UpgradeTimeoutChannel(ev) => Some(ev.into()),
446            IbcEvent::UpgradeErrorChannel(ev) => Some(ev.into()),
447            _ => None,
448        }
449    }
450
451    pub fn connection_attributes(&self) -> Option<&ConnectionAttributes> {
452        match self {
453            IbcEvent::OpenInitConnection(ev) => Some(ev.attributes()),
454            IbcEvent::OpenTryConnection(ev) => Some(ev.attributes()),
455            IbcEvent::OpenAckConnection(ev) => Some(ev.attributes()),
456            IbcEvent::OpenConfirmConnection(ev) => Some(ev.attributes()),
457            _ => None,
458        }
459    }
460
461    pub fn packet(&self) -> Option<&Packet> {
462        match self {
463            IbcEvent::SendPacket(ev) => Some(&ev.packet),
464            IbcEvent::ReceivePacket(ev) => Some(&ev.packet),
465            IbcEvent::WriteAcknowledgement(ev) => Some(&ev.packet),
466            IbcEvent::AcknowledgePacket(ev) => Some(&ev.packet),
467            IbcEvent::TimeoutPacket(ev) => Some(&ev.packet),
468            IbcEvent::TimeoutOnClosePacket(ev) => Some(&ev.packet),
469            _ => None,
470        }
471    }
472
473    pub fn cross_chain_query_packet(&self) -> Option<&CrossChainQueryPacket> {
474        match self {
475            IbcEvent::CrossChainQueryPacket(ev) => Some(ev),
476            _ => None,
477        }
478    }
479
480    pub fn ack(&self) -> Option<&[u8]> {
481        match self {
482            IbcEvent::WriteAcknowledgement(ev) => Some(&ev.ack),
483            _ => None,
484        }
485    }
486}
487
488#[derive(Debug, PartialEq, Eq)]
489pub struct InvalidModuleId;
490
491#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Deserialize, Serialize)]
492pub struct ModuleId(String);
493
494impl ModuleId {
495    pub fn new(s: Cow<'_, str>) -> Result<Self, InvalidModuleId> {
496        if !s.trim().is_empty() && s.chars().all(char::is_alphanumeric) {
497            Ok(Self(s.into_owned()))
498        } else {
499            Err(InvalidModuleId)
500        }
501    }
502}
503
504impl Display for ModuleId {
505    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
506        write!(f, "{}", self.0)
507    }
508}
509
510impl FromStr for ModuleId {
511    type Err = InvalidModuleId;
512
513    fn from_str(s: &str) -> Result<Self, Self::Err> {
514        Self::new(Cow::Borrowed(s))
515    }
516}
517
518#[derive(Debug, Clone, Serialize, PartialEq, Eq)]
519pub struct ModuleEvent {
520    pub kind: String,
521    pub module_name: ModuleId,
522    pub attributes: Vec<ModuleEventAttribute>,
523}
524
525impl Display for ModuleEvent {
526    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
527        write!(
528            f,
529            "ModuleEvent {{ kind: {}, module_name: {}, attributes: {} }}",
530            self.kind,
531            self.module_name,
532            PrettySlice(&self.attributes)
533        )
534    }
535}
536
537impl TryFrom<ModuleEvent> for abci::Event {
538    type Error = Error;
539
540    fn try_from(event: ModuleEvent) -> Result<Self, Self::Error> {
541        if IbcEventType::from_str(event.kind.as_str()).is_ok() {
542            return Err(Error::malformed_module_event(event));
543        }
544
545        let attributes = event.attributes.into_iter().map(Into::into).collect();
546        Ok(Self {
547            kind: event.kind,
548            attributes,
549        })
550    }
551}
552
553impl From<ModuleEvent> for IbcEvent {
554    fn from(e: ModuleEvent) -> Self {
555        IbcEvent::AppModule(e)
556    }
557}
558
559#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
560pub struct ModuleEventAttribute {
561    pub key: String,
562    pub value: String,
563}
564
565impl Display for ModuleEventAttribute {
566    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
567        write!(
568            f,
569            "ModuleEventAttribute {{ key: {}, value: {} }}",
570            self.key, self.value
571        )
572    }
573}
574
575impl<K: ToString, V: ToString> From<(K, V)> for ModuleEventAttribute {
576    fn from((k, v): (K, V)) -> Self {
577        Self {
578            key: k.to_string(),
579            value: v.to_string(),
580        }
581    }
582}
583
584impl From<ModuleEventAttribute> for abci::EventAttribute {
585    fn from(attr: ModuleEventAttribute) -> Self {
586        (attr.key, attr.value).into()
587    }
588}