Skip to content

Commit

Permalink
Get events from RPC event's data instead of events (informalsystems#1172
Browse files Browse the repository at this point in the history
)

* temp fix

* Debugability, add check for chan try for counterparty ch

* Get events from RPC event's data insead of events

* Fix error message

* Debug for proof bytes and getter of other_proof

* fmt fix

* Remove event conversion, redundant with current tendermint-rs refpoint

* Review comments

* Add .changelog entry for informalsystems#1191

* Fix clippy warning

Co-authored-by: Romain Ruetschi <romain@informal.systems>
  • Loading branch information
ancazamfir and romac committed Aug 23, 2021
1 parent 4aa7009 commit 8cf98ea
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 218 deletions.
4 changes: 4 additions & 0 deletions .changelog/unreleased/improvements/1191-ica-compat.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
- Improve support for Interchain Accounts (ICS 027) ([#1191])

[#1191]: https://github.com/informalsystems/ibc-rs/issues/1191

9 changes: 5 additions & 4 deletions relayer/src/channel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -826,7 +826,7 @@ impl<ChainA: ChainHandle, ChainB: ChainHandle> Channel<ChainA, ChainB> {
*src_channel.ordering(),
counterparty,
vec![self.dst_connection_id().clone()],
self.dst_version()?,
src_channel.version(),
);

// Get signer
Expand All @@ -845,7 +845,7 @@ impl<ChainA: ChainHandle, ChainB: ChainHandle> Channel<ChainA, ChainB> {
let new_msg = MsgChannelOpenTry {
port_id: self.dst_port_id().clone(),
previous_channel_id,
counterparty_version: self.src_version()?,
counterparty_version: src_channel.version(),
channel,
proofs,
signer,
Expand Down Expand Up @@ -894,7 +894,8 @@ impl<ChainA: ChainHandle, ChainB: ChainHandle> Channel<ChainA, ChainB> {
self.validated_expected_channel(ChannelMsgType::OpenAck)?;

// Channel must exist on source
self.src_chain()
let src_channel = self
.src_chain()
.query_channel(self.src_port_id(), src_channel_id, Height::zero())
.map_err(|e| ChannelError::query(self.src_chain().id(), e))?;

Expand Down Expand Up @@ -927,7 +928,7 @@ impl<ChainA: ChainHandle, ChainB: ChainHandle> Channel<ChainA, ChainB> {
port_id: self.dst_port_id().clone(),
channel_id: dst_channel_id.clone(),
counterparty_channel_id: src_channel_id.clone(),
counterparty_version: self.src_version()?,
counterparty_version: src_channel.version(),
proofs,
signer,
};
Expand Down
222 changes: 8 additions & 214 deletions relayer/src/event/rpc.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,9 @@
use std::{collections::HashMap, convert::TryFrom};

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

use ibc::events::{from_tx_response_event, IbcEvent};
use ibc::ics02_client::events::NewBlock;
use ibc::ics02_client::height::Height;
use ibc::ics24_host::identifier::ChainId;
use ibc::{
events::{Error as EventError, IbcEvent, RawObject},
ics02_client::events as ClientEvents,
ics03_connection::events as ConnectionEvents,
ics04_channel::events as ChannelEvents,
};

pub fn get_all_events(
chain_id: &ChainId,
Expand All @@ -27,26 +20,16 @@ pub fn get_all_events(

vals.push((height, NewBlock::new(height).into()));
}

RpcEventData::Tx { .. } => {
let events = &result.events.ok_or("missing events")?;
let height_raw = events.get("tx.height").ok_or("tx.height")?[0]
.parse::<u64>()
.map_err(|e| e.to_string())?;
EventData::Tx { tx_result } => {
let height = Height::new(
ChainId::chain_version(chain_id.to_string().as_str()),
height_raw,
tx_result.height as u64,
);

let actions_and_indices = extract_helper(events)?;
for action in actions_and_indices {
if let Ok(event) = build_event(RawObject::new(
height,
action.0,
action.1 as usize,
events.clone(),
)) {
vals.push((height, event));
for abci_event in &tx_result.result.events {
if let Some(ibc_event) = from_tx_response_event(height, abci_event) {
tracing::trace!("Extracted ibc_event {:?}", ibc_event);
vals.push((height, ibc_event));
}
}
}
Expand All @@ -55,192 +38,3 @@ pub fn get_all_events(

Ok(vals)
}

pub fn build_event(mut object: RawObject) -> Result<IbcEvent, EventError> {
match object.action.as_str() {
// Client events
"create_client" | ibc::ics02_client::msgs::create_client::TYPE_URL => Ok(IbcEvent::from(
ClientEvents::CreateClient::try_from(object)?,
)),
"update_client" | ibc::ics02_client::msgs::update_client::TYPE_URL => Ok(IbcEvent::from(
ClientEvents::UpdateClient::try_from(object)?,
)),
"submit_misbehaviour" | ibc::ics02_client::msgs::misbehavior::TYPE_URL => Ok(
IbcEvent::from(ClientEvents::ClientMisbehaviour::try_from(object)?),
),

// Connection events
"connection_open_init" | ibc::ics03_connection::msgs::conn_open_init::TYPE_URL => Ok(
IbcEvent::from(ConnectionEvents::OpenInit::try_from(object)?),
),
"connection_open_try" | ibc::ics03_connection::msgs::conn_open_try::TYPE_URL => {
Ok(IbcEvent::from(ConnectionEvents::OpenTry::try_from(object)?))
}
"connection_open_ack" | ibc::ics03_connection::msgs::conn_open_ack::TYPE_URL => {
Ok(IbcEvent::from(ConnectionEvents::OpenAck::try_from(object)?))
}
"connection_open_confirm" | ibc::ics03_connection::msgs::conn_open_confirm::TYPE_URL => Ok(
IbcEvent::from(ConnectionEvents::OpenConfirm::try_from(object)?),
),

// Channel events
"channel_open_init" | ibc::ics04_channel::msgs::chan_open_init::TYPE_URL => {
Ok(IbcEvent::from(ChannelEvents::OpenInit::try_from(object)?))
}
"channel_open_try" | ibc::ics04_channel::msgs::chan_open_try::TYPE_URL => {
Ok(IbcEvent::from(ChannelEvents::OpenTry::try_from(object)?))
}
"channel_open_ack" | ibc::ics04_channel::msgs::chan_open_ack::TYPE_URL => {
Ok(IbcEvent::from(ChannelEvents::OpenAck::try_from(object)?))
}
"channel_open_confirm" | ibc::ics04_channel::msgs::chan_open_confirm::TYPE_URL => Ok(
IbcEvent::from(ChannelEvents::OpenConfirm::try_from(object)?),
),
"channel_close_init" | ibc::ics04_channel::msgs::chan_close_init::TYPE_URL => {
Ok(IbcEvent::from(ChannelEvents::CloseInit::try_from(object)?))
}
"channel_close_confirm" | ibc::ics04_channel::msgs::chan_close_confirm::TYPE_URL => Ok(
IbcEvent::from(ChannelEvents::CloseConfirm::try_from(object)?),
),

// Packet events
// Note: There is no message.action "send_packet", the only one we can hook into is the
// module's action:
// - "transfer" for ICS20
// - "MsgSend" and "MsgRegister" for ICS27
// However the attributes are all prefixed with "send_packet" therefore the overwrite here
// TODO: This need to be sorted out
"transfer"
| ibc::application::ics20_fungible_token_transfer::msgs::transfer::TYPE_URL
| ibc::application::ICS27_BANK_SEND_TYPE_URL
| ibc::application::ICS27_SEND_TYPE_URL
| ibc::application::ICS27_REGISTER_TYPE_URL => {
object.action = "send_packet".to_string();
Ok(IbcEvent::from(ChannelEvents::SendPacket::try_from(object)?))
}
// Same here
// TODO: sort this out
"recv_packet" | ibc::ics04_channel::msgs::recv_packet::TYPE_URL => {
object.action = "write_acknowledgement".to_string();
Ok(IbcEvent::from(
ChannelEvents::WriteAcknowledgement::try_from(object)?,
))
}
"write_acknowledgement" => Ok(IbcEvent::from(
ChannelEvents::WriteAcknowledgement::try_from(object)?,
)),
"acknowledge_packet" | ibc::ics04_channel::msgs::acknowledgement::TYPE_URL => {
object.action = "acknowledge_packet".to_string();
Ok(IbcEvent::from(ChannelEvents::AcknowledgePacket::try_from(
object,
)?))
}
"timeout_packet" | ibc::ics04_channel::msgs::timeout::TYPE_URL => {
object.action = "timeout_packet".to_string();
Ok(IbcEvent::from(ChannelEvents::TimeoutPacket::try_from(
object,
)?))
}
"timeout_on_close_packet" | ibc::ics04_channel::msgs::timeout_on_close::TYPE_URL => {
object.action = "timeout_packet".to_string();
Ok(IbcEvent::from(
ChannelEvents::TimeoutOnClosePacket::try_from(object)?,
))
}

event_type => Err(EventError::incorrect_event_type(event_type.to_string())),
}
}

/// Takes events in the form
///
/// ```json
/// {
/// "events": {
/// "connection_open_init.client_id": [
/// "testclient",
/// "testclientsec"
/// ],
/// "connection_open_init.connection_id": [
/// "ancaconnonetest",
/// "ancaconnonetestsec"
/// ],
/// "connection_open_init.counterparty_client_id": [
/// "testclientsec",
/// "testclientsecsec"
/// ],
/// "create_client.client_id": [
/// "testclientthird"
/// ],
/// "create_client.client_type": [
/// "tendermint"
/// ],
/// "message.action": [
/// "connection_open_init",
/// "create_client",
/// "connection_open_init"
/// ],
/// "message.module": [
/// "ibc_connection",
/// "ibc_client",
/// "ibc_connection"
/// ],
/// "message.sender": [
/// "cosmos187xxg4yfkypl05cqylucezpjvycj24nurvm8p9",
/// "cosmos187xxg4yfkypl05cqylucezpjvycj24nurvm8p9",
/// "cosmos187xxg4yfkypl05cqylucezpjvycj24nurvm8p9",
/// "cosmos187xxg4yfkypl05cqylucezpjvycj24nurvm8p9"
/// ],
/// "tm.event": [
/// "Tx"
/// ],
/// "transfer.amount": [
/// "5000stake"
/// ],
/// "transfer.recipient": [
/// "cosmos17xpfvakm2amg962yls6f84z3kell8c5lserqta"
/// ],
/// "tx.hash": [
/// "A9E18AE3909F22232F8DBDB1C48F2FECB260A308A2D157E8832E901D45950605"
/// ],
/// "tx.height": [
/// "35"
/// ]
/// }
/// }
/// ```
///
/// and returns:
///
/// ```rust
/// vec![
/// ("connection_open_init", 0),
/// ("create_client", 0),
/// ("connection_open_init", 1),
/// ];
/// ```
///
/// where the number in each entry is the index in the matching events that should be used to build the event.
///
/// e.g. for the last "connection_open_init" in the result
///
/// ```text
/// "connection_open_init.client_id" -> "testclientsec"
/// "connection_open_init.connection_id" -> "ancaconnonetestsec",
/// "connection_open_init.counterparty_client_id" -> "testclientsec", "testclientsecsec",
/// ```
fn extract_helper(events: &HashMap<String, Vec<String>>) -> Result<Vec<(String, u32)>, String> {
let actions = events.get("message.action").ok_or("Incorrect Event Type")?;

let mut val_indices = HashMap::new();
let mut result = Vec::with_capacity(actions.len());

for action in actions {
let idx = val_indices.entry(action.clone()).or_insert_with(|| 0);
result.push((action.clone(), *idx));

*val_indices.get_mut(action.as_str()).unwrap() += 1;
}

Ok(result)
}

0 comments on commit 8cf98ea

Please sign in to comment.