Skip to content

Commit

Permalink
Make connection events compatible with ibc-go (#191)
Browse files Browse the repository at this point in the history
* OpenInit event refactored

* conn_open_init emits proper event

* fix all other connection events

* conn_open_try now outputs proper event

* adopt naming convention in event ctor

* conn_open_ack emits proper event

* conn_open_confirm now emits proper event

* remove unneeded function

* clippy fixes

* changelog

* nit improvement

* Update crates/ibc/src/core/ics03_connection/events.rs

Signed-off-by: Philippe Laferrière <plafer@protonmail.com>

Signed-off-by: Philippe Laferrière <plafer@protonmail.com>
  • Loading branch information
plafer authored Oct 26, 2022
1 parent 4b18233 commit f8bc033
Show file tree
Hide file tree
Showing 7 changed files with 183 additions and 147 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- Make connection events compatible with ibc-go
([#145](https://github.com/cosmos/ibc-rs/issues/145))
206 changes: 122 additions & 84 deletions crates/ibc/src/core/ics03_connection/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use tendermint::abci::tag::Tag;
use tendermint::abci::Event as AbciEvent;

use crate::core::ics24_host::identifier::{ClientId, ConnectionId};
use crate::events::{IbcEvent, IbcEventType};
use crate::events::IbcEventType;
use crate::prelude::*;

/// The content of the `key` field for the attribute containing the connection identifier.
Expand All @@ -15,8 +15,8 @@ pub const COUNTERPARTY_CONN_ID_ATTRIBUTE_KEY: &str = "counterparty_connection_id
pub const COUNTERPARTY_CLIENT_ID_ATTRIBUTE_KEY: &str = "counterparty_client_id";

#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Deserialize, Serialize)]
pub struct Attributes {
pub connection_id: Option<ConnectionId>,
struct Attributes {
pub connection_id: ConnectionId,
pub client_id: ClientId,
pub counterparty_connection_id: Option<ConnectionId>,
pub counterparty_client_id: ClientId,
Expand All @@ -32,56 +32,67 @@ pub struct Attributes {
/// we will be able to remove the `.parse().unwrap()` calls.
impl From<Attributes> for Vec<Tag> {
fn from(a: Attributes) -> Self {
let mut attributes = vec![];
if let Some(conn_id) = a.connection_id {
let conn_id = Tag {
key: CONN_ID_ATTRIBUTE_KEY.parse().unwrap(),
value: conn_id.to_string().parse().unwrap(),
};
attributes.push(conn_id);
}
let conn_id = Tag {
key: CONN_ID_ATTRIBUTE_KEY.parse().unwrap(),
value: a.connection_id.to_string().parse().unwrap(),
};

let client_id = Tag {
key: CLIENT_ID_ATTRIBUTE_KEY.parse().unwrap(),
value: a.client_id.to_string().parse().unwrap(),
};
attributes.push(client_id);
if let Some(conn_id) = a.counterparty_connection_id {
let conn_id = Tag {
key: COUNTERPARTY_CONN_ID_ATTRIBUTE_KEY.parse().unwrap(),
value: conn_id.to_string().parse().unwrap(),
};
attributes.push(conn_id);
}

let counterparty_conn_id = Tag {
key: COUNTERPARTY_CONN_ID_ATTRIBUTE_KEY.parse().unwrap(),
value: match a.counterparty_connection_id {
Some(counterparty_conn_id) => counterparty_conn_id.to_string().parse().unwrap(),
None => "".parse().unwrap(),
},
};

let counterparty_client_id = Tag {
key: COUNTERPARTY_CLIENT_ID_ATTRIBUTE_KEY.parse().unwrap(),
value: a.counterparty_client_id.to_string().parse().unwrap(),
};
attributes.push(counterparty_client_id);
attributes

vec![
conn_id,
client_id,
counterparty_client_id,
counterparty_conn_id,
]
}
}

#[derive(Clone, Debug, PartialEq, Eq, Serialize)]
pub struct OpenInit(pub Attributes);
pub struct OpenInit(Attributes);

impl OpenInit {
pub fn attributes(&self) -> &Attributes {
&self.0
/// Per our convention, this event is generated on chain A.
pub fn new(
conn_id_on_a: ConnectionId,
client_id_on_a: ClientId,
client_id_on_b: ClientId,
) -> Self {
Self(Attributes {
connection_id: conn_id_on_a,
client_id: client_id_on_a,
counterparty_connection_id: None,
counterparty_client_id: client_id_on_b,
})
}
pub fn connection_id(&self) -> Option<&ConnectionId> {
self.0.connection_id.as_ref()
}
}

impl From<Attributes> for OpenInit {
fn from(attrs: Attributes) -> Self {
OpenInit(attrs)
pub fn connection_id(&self) -> &ConnectionId {
&self.0.connection_id
}
}

impl From<OpenInit> for IbcEvent {
fn from(v: OpenInit) -> Self {
IbcEvent::OpenInitConnection(v)
pub fn client_id(&self) -> &ClientId {
&self.0.client_id
}
pub fn counterparty_connection_id(&self) -> Option<&ConnectionId> {
self.0.counterparty_connection_id.as_ref()
}
pub fn counterparty_client_id(&self) -> &ClientId {
&self.0.counterparty_client_id
}
}

Expand All @@ -96,26 +107,35 @@ impl From<OpenInit> for AbciEvent {
}

#[derive(Clone, Debug, PartialEq, Eq, Serialize)]
pub struct OpenTry(pub Attributes);
pub struct OpenTry(Attributes);

impl OpenTry {
pub fn attributes(&self) -> &Attributes {
&self.0
/// Per our convention, this event is generated on chain B.
pub fn new(
conn_id_on_b: ConnectionId,
client_id_on_b: ClientId,
conn_id_on_a: ConnectionId,
client_id_on_a: ClientId,
) -> Self {
Self(Attributes {
connection_id: conn_id_on_b,
client_id: client_id_on_b,
counterparty_connection_id: Some(conn_id_on_a),
counterparty_client_id: client_id_on_a,
})
}
pub fn connection_id(&self) -> Option<&ConnectionId> {
self.0.connection_id.as_ref()
}
}

impl From<Attributes> for OpenTry {
fn from(attrs: Attributes) -> Self {
OpenTry(attrs)
pub fn connection_id(&self) -> &ConnectionId {
&self.0.connection_id
}
}

impl From<OpenTry> for IbcEvent {
fn from(v: OpenTry) -> Self {
IbcEvent::OpenTryConnection(v)
pub fn client_id(&self) -> &ClientId {
&self.0.client_id
}
pub fn counterparty_connection_id(&self) -> Option<&ConnectionId> {
self.0.counterparty_connection_id.as_ref()
}
pub fn counterparty_client_id(&self) -> &ClientId {
&self.0.counterparty_client_id
}
}

Expand All @@ -130,26 +150,35 @@ impl From<OpenTry> for AbciEvent {
}

#[derive(Clone, Debug, PartialEq, Eq, Serialize)]
pub struct OpenAck(pub Attributes);
pub struct OpenAck(Attributes);

impl OpenAck {
pub fn attributes(&self) -> &Attributes {
&self.0
/// Per our convention, this event is generated on chain A.
pub fn new(
conn_id_on_a: ConnectionId,
client_id_on_a: ClientId,
conn_id_on_b: ConnectionId,
client_id_on_b: ClientId,
) -> Self {
Self(Attributes {
connection_id: conn_id_on_a,
client_id: client_id_on_a,
counterparty_connection_id: Some(conn_id_on_b),
counterparty_client_id: client_id_on_b,
})
}
pub fn connection_id(&self) -> Option<&ConnectionId> {
self.0.connection_id.as_ref()
}
}

impl From<Attributes> for OpenAck {
fn from(attrs: Attributes) -> Self {
OpenAck(attrs)
pub fn connection_id(&self) -> &ConnectionId {
&self.0.connection_id
}
}

impl From<OpenAck> for IbcEvent {
fn from(v: OpenAck) -> Self {
IbcEvent::OpenAckConnection(v)
pub fn client_id(&self) -> &ClientId {
&self.0.client_id
}
pub fn counterparty_connection_id(&self) -> Option<&ConnectionId> {
self.0.counterparty_connection_id.as_ref()
}
pub fn counterparty_client_id(&self) -> &ClientId {
&self.0.counterparty_client_id
}
}

Expand All @@ -164,26 +193,35 @@ impl From<OpenAck> for AbciEvent {
}

#[derive(Clone, Debug, PartialEq, Eq, Serialize)]
pub struct OpenConfirm(pub Attributes);
pub struct OpenConfirm(Attributes);

impl OpenConfirm {
pub fn attributes(&self) -> &Attributes {
&self.0
}
pub fn connection_id(&self) -> Option<&ConnectionId> {
self.0.connection_id.as_ref()
}
}

impl From<Attributes> for OpenConfirm {
fn from(attrs: Attributes) -> Self {
OpenConfirm(attrs)
}
}

impl From<OpenConfirm> for IbcEvent {
fn from(v: OpenConfirm) -> Self {
IbcEvent::OpenConfirmConnection(v)
/// Per our convention, this event is generated on chain B.
pub fn new(
conn_id_on_b: ConnectionId,
client_id_on_b: ClientId,
conn_id_on_a: ConnectionId,
client_id_on_a: ClientId,
) -> Self {
Self(Attributes {
connection_id: conn_id_on_b,
client_id: client_id_on_b,
counterparty_connection_id: Some(conn_id_on_a),
counterparty_client_id: client_id_on_a,
})
}

pub fn connection_id(&self) -> &ConnectionId {
&self.0.connection_id
}
pub fn client_id(&self) -> &ClientId {
&self.0.client_id
}
pub fn counterparty_connection_id(&self) -> Option<&ConnectionId> {
self.0.counterparty_connection_id.as_ref()
}
pub fn counterparty_client_id(&self) -> &ClientId {
&self.0.counterparty_client_id
}
}

Expand Down
32 changes: 17 additions & 15 deletions crates/ibc/src/core/ics03_connection/handler/conn_open_ack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
use crate::core::ics03_connection::connection::{ConnectionEnd, Counterparty, State};
use crate::core::ics03_connection::context::ConnectionReader;
use crate::core::ics03_connection::error::Error;
use crate::core::ics03_connection::events::Attributes;
use crate::core::ics03_connection::events::OpenAck;
use crate::core::ics03_connection::handler::ConnectionResult;
use crate::core::ics03_connection::msgs::conn_open_ack::MsgConnectionOpenAck;
use crate::events::IbcEvent;
Expand Down Expand Up @@ -38,6 +38,14 @@ pub(crate) fn process(
return Err(Error::connection_mismatch(msg.conn_id_on_a));
}

let client_id_on_a = conn_end_on_a.client_id();
let client_id_on_b = conn_end_on_a.counterparty().client_id();

let conn_id_on_b = conn_end_on_a
.counterparty()
.connection_id()
.ok_or_else(Error::invalid_counterparty)?;

// Proof verification.
{
let client_state_of_b_on_a = ctx_a.client_state(conn_end_on_a.client_id())?;
Expand All @@ -46,14 +54,8 @@ pub(crate) fn process(

let prefix_on_a = ctx_a.commitment_prefix();
let prefix_on_b = conn_end_on_a.counterparty().prefix();
let client_id_on_a = conn_end_on_a.client_id();
let client_id_on_b = conn_end_on_a.counterparty().client_id();

{
let conn_id_on_b = conn_end_on_a
.counterparty()
.connection_id()
.ok_or_else(Error::invalid_counterparty)?;
let expected_conn_end_on_b = ConnectionEnd::new(
State::TryOpen,
client_id_on_b.clone(),
Expand Down Expand Up @@ -107,6 +109,14 @@ pub(crate) fn process(
}

// Success
output.emit(IbcEvent::OpenAckConnection(OpenAck::new(
msg.conn_id_on_a.clone(),
client_id_on_a.clone(),
conn_id_on_b.clone(),
client_id_on_b.clone(),
)));
output.log("success: conn_open_ack verification passed");

let result = {
let new_conn_end_on_a = {
let mut counterparty = conn_end_on_a.counterparty().clone();
Expand All @@ -126,14 +136,6 @@ pub(crate) fn process(
}
};

let event_attributes = Attributes {
connection_id: Some(result.connection_id.clone()),
..Default::default()
};

output.emit(IbcEvent::OpenAckConnection(event_attributes.into()));
output.log("success: conn_open_ack verification passed");

Ok(output.with_result(result))
}

Expand Down
Loading

0 comments on commit f8bc033

Please sign in to comment.