Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Get events from RPC event's data instead of events #1172

Merged
merged 15 commits into from
Aug 23, 2021
Merged
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

73 changes: 0 additions & 73 deletions modules/src/events.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use std::collections::HashMap;

use serde_derive::{Deserialize, Serialize};

use crate::ics02_client::error as client_error;
Expand Down Expand Up @@ -259,74 +257,3 @@ impl IbcEvent {
}
}
}

#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct RawObject {
pub height: Height,
pub action: String,
pub idx: usize,
pub events: HashMap<String, Vec<String>>,
}

impl RawObject {
pub fn new(
height: Height,
action: String,
idx: usize,
events: HashMap<String, Vec<String>>,
) -> RawObject {
RawObject {
height,
action,
idx,
events,
}
}
}

pub fn extract_events<S: ::std::hash::BuildHasher>(
events: &HashMap<String, Vec<String>, S>,
action_string: &str,
) -> Result<(), Error> {
if let Some(message_action) = events.get("message.action") {
if message_action.contains(&action_string.to_owned()) {
return Ok(());
}
return Err(Error::missing_action_string());
}
Err(Error::incorrect_event_type(action_string.to_string()))
}

pub fn extract_attribute(object: &RawObject, key: &str) -> Result<String, Error> {
let value = object
.events
.get(key)
.ok_or_else(|| Error::missing_key(key.to_string()))?[object.idx]
.clone();

Ok(value)
}

pub fn maybe_extract_attribute(object: &RawObject, key: &str) -> Option<String> {
object.events.get(key).map(|tags| tags[object.idx].clone())
}

#[macro_export]
macro_rules! make_event {
($a:ident, $b:literal) => {
#[derive(Debug, Deserialize, Serialize, Clone)]
pub struct $a {
pub data: ::std::collections::HashMap<String, Vec<String>>,
}
impl ::std::convert::TryFrom<$crate::events::RawObject> for $a {
type Error = $crate::event::Error;

fn try_from(result: $crate::events::RawObject) -> Result<Self, Self::Error> {
$crate::events::extract_events(&result.events, $b)?;
Ok($a {
data: result.events.clone(),
})
}
}
};
}
70 changes: 1 addition & 69 deletions modules/src/ics02_client/events.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
//! Types for the IBC events emitted from Tendermint Websocket by the client module.
use std::convert::{TryFrom, TryInto};

use prost::Message;
use serde_derive::{Deserialize, Serialize};
use subtle_encoding::hex;
use tendermint_proto::Protobuf;

use crate::events::{extract_attribute, Error, IbcEvent, RawObject};
use crate::events::IbcEvent;
use crate::ics02_client::client_type::ClientType;
use crate::ics02_client::header::AnyHeader;
use crate::ics02_client::height::Height;
Expand Down Expand Up @@ -134,25 +132,6 @@ impl std::fmt::Display for Attributes {
}
}

fn extract_attributes(object: &RawObject, namespace: &str) -> Result<Attributes, Error> {
Ok(Attributes {
height: object.height,

client_id: extract_attribute(object, &format!("{}.client_id", namespace))?
.parse()
.map_err(Error::parse)?,

client_type: extract_attribute(object, &format!("{}.client_type", namespace))?
.parse()
.map_err(Error::client)?,

consensus_height: extract_attribute(object, &format!("{}.consensus_height", namespace))?
.as_str()
.try_into()
.map_err(Error::height)?,
})
}

/// CreateClient event signals the creation of a new on-chain client (IBC client).
#[derive(Debug, Deserialize, Serialize, Clone)]
pub struct CreateClient(pub Attributes);
Expand All @@ -175,13 +154,6 @@ impl From<Attributes> for CreateClient {
}
}

impl TryFrom<RawObject> for CreateClient {
type Error = Error;
fn try_from(obj: RawObject) -> Result<Self, Self::Error> {
Ok(CreateClient(extract_attributes(&obj, "create_client")?))
}
}

impl From<CreateClient> for IbcEvent {
fn from(v: CreateClient) -> Self {
IbcEvent::CreateClient(v)
Expand Down Expand Up @@ -231,36 +203,6 @@ impl From<Attributes> for UpdateClient {
}
}

impl TryFrom<RawObject> for UpdateClient {
type Error = Error;

fn try_from(obj: RawObject) -> Result<Self, Self::Error> {
let header_str: Option<String> = obj
.events
.get("update_client.header")
.and_then(|tags| tags[obj.idx].parse().ok());

let header: Option<AnyHeader> = match header_str {
Some(str) => {
let header_bytes = hex::decode(str).map_err(Error::subtle_encoding)?;

let decoded = prost_types::Any::decode(header_bytes.as_ref())
.map_err(Error::decode)?
.try_into()
.map_err(Error::client)?;

Some(decoded)
}
None => None,
};

Ok(UpdateClient {
common: extract_attributes(&obj, "update_client")?,
header,
})
}
}

impl From<UpdateClient> for IbcEvent {
fn from(v: UpdateClient) -> Self {
IbcEvent::UpdateClient(v)
Expand Down Expand Up @@ -290,16 +232,6 @@ impl ClientMisbehaviour {
}
}

impl TryFrom<RawObject> for ClientMisbehaviour {
type Error = Error;
fn try_from(obj: RawObject) -> Result<Self, Error> {
Ok(ClientMisbehaviour(extract_attributes(
&obj,
"client_misbehaviour",
)?))
}
}

impl From<ClientMisbehaviour> for IbcEvent {
fn from(v: ClientMisbehaviour) -> Self {
IbcEvent::ClientMisbehaviour(v)
Expand Down
60 changes: 1 addition & 59 deletions modules/src/ics03_connection/events.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
//! Types for the IBC events emitted from Tendermint Websocket by the connection module.
use crate::events::{extract_attribute, maybe_extract_attribute, Error, IbcEvent, RawObject};
use crate::events::IbcEvent;
use crate::ics02_client::height::Height;
use crate::ics24_host::identifier::{ClientId, ConnectionId};
use serde_derive::{Deserialize, Serialize};
use std::convert::TryFrom;

/// The content of the `type` field for the event that a chain produces upon executing a connection handshake transaction.
const INIT_EVENT_TYPE: &str = "connection_open_init";
Expand Down Expand Up @@ -67,32 +66,6 @@ pub struct Attributes {
pub counterparty_client_id: ClientId,
}

fn extract_attributes(object: &RawObject, namespace: &str) -> Result<Attributes, Error> {
Ok(Attributes {
height: object.height,

connection_id: maybe_extract_attribute(object, &format!("{}.connection_id", namespace))
.and_then(|val| val.parse().ok()),

client_id: extract_attribute(object, &format!("{}.client_id", namespace))?
.parse()
.map_err(Error::parse)?,

counterparty_connection_id: maybe_extract_attribute(
object,
&format!("{}.counterparty_connection_id", namespace),
)
.and_then(|val| val.parse().ok()),

counterparty_client_id: extract_attribute(
object,
&format!("{}.counterparty_client_id", namespace),
)?
.parse()
.map_err(Error::parse)?,
})
}

impl Default for Attributes {
fn default() -> Self {
Attributes {
Expand Down Expand Up @@ -129,13 +102,6 @@ impl From<Attributes> for OpenInit {
}
}

impl TryFrom<RawObject> for OpenInit {
type Error = Error;
fn try_from(obj: RawObject) -> Result<Self, Self::Error> {
Ok(OpenInit(extract_attributes(&obj, "connection_open_init")?))
}
}

impl From<OpenInit> for IbcEvent {
fn from(v: OpenInit) -> Self {
IbcEvent::OpenInitConnection(v)
Expand Down Expand Up @@ -166,13 +132,6 @@ impl From<Attributes> for OpenTry {
}
}

impl TryFrom<RawObject> for OpenTry {
type Error = Error;
fn try_from(obj: RawObject) -> Result<Self, Self::Error> {
Ok(OpenTry(extract_attributes(&obj, "connection_open_try")?))
}
}

impl From<OpenTry> for IbcEvent {
fn from(v: OpenTry) -> Self {
IbcEvent::OpenTryConnection(v)
Expand Down Expand Up @@ -203,13 +162,6 @@ impl From<Attributes> for OpenAck {
}
}

impl TryFrom<RawObject> for OpenAck {
type Error = Error;
fn try_from(obj: RawObject) -> Result<Self, Self::Error> {
Ok(OpenAck(extract_attributes(&obj, "connection_open_ack")?))
}
}

impl From<OpenAck> for IbcEvent {
fn from(v: OpenAck) -> Self {
IbcEvent::OpenAckConnection(v)
Expand Down Expand Up @@ -240,16 +192,6 @@ impl From<Attributes> for OpenConfirm {
}
}

impl TryFrom<RawObject> for OpenConfirm {
type Error = Error;
fn try_from(obj: RawObject) -> Result<Self, Self::Error> {
Ok(OpenConfirm(extract_attributes(
&obj,
"connection_open_confirm",
)?))
}
}

impl From<OpenConfirm> for IbcEvent {
fn from(v: OpenConfirm) -> Self {
IbcEvent::OpenConfirmConnection(v)
Expand Down
Loading