Skip to content

Commit

Permalink
Re-use existing append_events infrastructure
Browse files Browse the repository at this point in the history
  • Loading branch information
romac committed Apr 18, 2024
1 parent a0abb90 commit 6ed048b
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 102 deletions.
100 changes: 7 additions & 93 deletions crates/relayer-types/src/applications/ics31_icq/events.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use std::collections::BTreeMap;
use std::str::FromStr;

use serde::{Deserialize, Serialize};
Expand All @@ -9,7 +8,7 @@ use crate::events::IbcEvent;

use super::error::Error;

const EVENT_TYPE_PREFIX: &str = "query_request";
pub const EVENT_TYPE_PREFIX: &str = "query_request";

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
pub struct CrossChainQueryPacket {
Expand All @@ -23,6 +22,12 @@ pub struct CrossChainQueryPacket {
pub request: String,
}

impl From<CrossChainQueryPacket> for IbcEvent {
fn from(packet: CrossChainQueryPacket) -> Self {
IbcEvent::CrossChainQueryPacket(packet)
}
}

fn find_value<'a>(key: &str, entries: &'a [abci::EventAttribute]) -> Result<&'a str, Error> {
entries
.iter()
Expand Down Expand Up @@ -94,94 +99,3 @@ impl<'a> TryFrom<&'a [abci::EventAttribute]> for CrossChainQueryPacket {
}
}

fn fetch_nth_element_from_events<'a>(
block_events: &'a BTreeMap<String, Vec<String>>,
key: &str,
index: usize,
) -> Result<&'a String, Error> {
let res = block_events
.get(key)
.ok_or_else(|| Error::event(format!("attribute not found for key: {key}")))?
.get(index)
.ok_or_else(|| {
Error::event(format!(
"element at position {index}, of attribute with key `{key}`, not found"
))
})?;

Ok(res)
}

impl CrossChainQueryPacket {
pub fn extract_query_events(
block_events: &BTreeMap<String, Vec<String>>,
) -> Result<Vec<IbcEvent>, Error> {
let events_count = block_events
.get(&format!("{}.{}", EVENT_TYPE_PREFIX, "query_id"))
.ok_or_else(|| Error::event("attribute not found for key: query_id".to_string()))?
.len();

let cross_chain_queries = (0..events_count)
.filter_map(|index| Self::extract_nth_query_event(block_events, index).ok())
.collect::<Vec<_>>();

Ok(cross_chain_queries)
}

fn extract_nth_query_event(
block_events: &BTreeMap<String, Vec<String>>,
index: usize,
) -> Result<IbcEvent, Error> {
let chain_id_str = fetch_nth_element_from_events(
block_events,
&format!("{}.{}", EVENT_TYPE_PREFIX, "chain_id"),
index,
)?;
let connection_id_str = fetch_nth_element_from_events(
block_events,
&format!("{}.{}", EVENT_TYPE_PREFIX, "connection_id"),
index,
)?;
let height_str = fetch_nth_element_from_events(
block_events,
&format!("{}.{}", EVENT_TYPE_PREFIX, "height"),
index,
)?;
let query_type = fetch_nth_element_from_events(
block_events,
&format!("{}.{}", EVENT_TYPE_PREFIX, "type"),
index,
)?;
let query_id = fetch_nth_element_from_events(
block_events,
&format!("{}.{}", EVENT_TYPE_PREFIX, "query_id"),
index,
)?;
let module = fetch_nth_element_from_events(
block_events,
&format!("{}.{}", EVENT_TYPE_PREFIX, "module"),
index,
)?;
let action = fetch_nth_element_from_events(
block_events,
&format!("{}.{}", EVENT_TYPE_PREFIX, "action"),
index,
)?;
let request = fetch_nth_element_from_events(
block_events,
&format!("{}.{}", EVENT_TYPE_PREFIX, "request"),
index,
)?;

Ok(IbcEvent::CrossChainQueryPacket(CrossChainQueryPacket {
module: module.clone(),
action: action.clone(),
query_id: query_id.clone(),
chain_id: ChainId::from_string(chain_id_str),
connection_id: ConnectionId::from_str(connection_id_str)?,
query_type: query_type.clone(),
height: Height::from_str(height_str)?,
request: request.clone(),
}))
}
}
27 changes: 27 additions & 0 deletions crates/relayer/src/chain/cosmos/types/events/channel.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use alloc::collections::btree_map::BTreeMap as HashMap;

use ibc_relayer_types::applications::ics31_icq;
use ibc_relayer_types::applications::ics31_icq::events::CrossChainQueryPacket;
use ibc_relayer_types::core::ics02_client::height::HeightErrorDetail;
use ibc_relayer_types::core::ics04_channel::error::Error;
use ibc_relayer_types::core::ics04_channel::events::{
Expand All @@ -12,6 +14,7 @@ use ibc_relayer_types::core::ics04_channel::events::{
use ibc_relayer_types::core::ics04_channel::events::{ReceivePacket, TimeoutOnClosePacket};
use ibc_relayer_types::core::ics04_channel::packet::Packet;
use ibc_relayer_types::core::ics04_channel::timeout::TimeoutHeight;
use ibc_relayer_types::core::ics24_host::identifier::ChainId;
use ibc_relayer_types::events::Error as EventError;
use ibc_relayer_types::Height;

Expand Down Expand Up @@ -176,6 +179,30 @@ impl TryFrom<RawObject<'_>> for Packet {
}
}

impl TryFrom<RawObject<'_>> for CrossChainQueryPacket {
type Error = EventError;

fn try_from(obj: RawObject<'_>) -> Result<Self, Self::Error> {
let p = ics31_icq::events::EVENT_TYPE_PREFIX;

Ok(Self {
module: extract_attribute(&obj, &format!("{p}.module"))?,
action: extract_attribute(&obj, &format!("{p}.action"))?,
query_id: extract_attribute(&obj, &format!("{p}.query_id"))?,
chain_id: extract_attribute(&obj, &format!("{p}.chain_id"))
.map(|s| ChainId::from_string(&s))?,
connection_id: extract_attribute(&obj, &format!("{p}.connection_id"))?
.parse()
.map_err(EventError::parse)?,
query_type: extract_attribute(&obj, &format!("{p}.type"))?,
request: extract_attribute(&obj, &format!("{p}.request"))?,
height: extract_attribute(&obj, &format!("{p}.height"))?
.parse()
.map_err(|_| EventError::height())?,
})
}
}

#[derive(Debug, Clone)]
pub struct RawObject<'a> {
pub height: Height,
Expand Down
2 changes: 1 addition & 1 deletion crates/relayer/src/event/source/rpc/extract.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use ibc_relayer_types::applications::ics29_fee::events::DistributionType;
use tendermint::abci;

use ibc_relayer_types::applications::ics29_fee::events::DistributionType;
use ibc_relayer_types::core::ics02_client::height::Height;
use ibc_relayer_types::core::ics24_host::identifier::ChainId;
use ibc_relayer_types::events::IbcEvent;
Expand Down
19 changes: 11 additions & 8 deletions crates/relayer/src/event/source/websocket/extract.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use alloc::collections::BTreeMap as HashMap;
use ibc_relayer_types::applications::ics29_fee::events::DistributionType;

use ibc_relayer_types::applications::ics31_icq;
use tendermint_rpc::{event::Event as RpcEvent, event::EventData as RpcEventData};

use ibc_relayer_types::applications::ics31_icq::events::CrossChainQueryPacket;
Expand Down Expand Up @@ -329,14 +330,16 @@ fn extract_block_events(
height,
);

// Extract cross chain query event from block_events
if let Ok(ccqs) = CrossChainQueryPacket::extract_query_events(block_events) {
let ccqs_with_height = ccqs
.into_iter()
.map(|ccq| IbcEventWithHeight::new(ccq, height));

events.extend(ccqs_with_height);
}
append_events::<CrossChainQueryPacket>(
&mut events,
extract_events(
height,
block_events,
ics31_icq::events::EVENT_TYPE_PREFIX,
"query_id",
),
height,
);

events
}

0 comments on commit 6ed048b

Please sign in to comment.