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#[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";
118const 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";
123const 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";
128const 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";
135const 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";
144const 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";
152const CROSS_CHAIN_QUERY_PACKET_EVENT: &str = "cross_chain_query";
154const DISTRIBUTION_FEE_PACKET_EVENT: &str = "distribute_fee";
156
157#[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 _ => Err(Error::incorrect_event_type(s.to_string())),
280 }
281 }
282}
283
284#[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), }
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:?}"), }
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}