diff --git a/crates/core/component/ibc/src/component/client.rs b/crates/core/component/ibc/src/component/client.rs index 7f9af90567..19111d15e2 100644 --- a/crates/core/component/ibc/src/component/client.rs +++ b/crates/core/component/ibc/src/component/client.rs @@ -1,7 +1,6 @@ use anyhow::{Context, Result}; use async_trait::async_trait; -use ibc_types::core::client::msgs::MsgUpdateClient; use ibc_types::core::client::ClientId; use ibc_types::core::client::ClientType; use ibc_types::core::client::Height; @@ -15,10 +14,7 @@ use penumbra_chain::component::StateReadExt as _; use penumbra_proto::{StateReadProto, StateWriteProto}; use penumbra_storage::{StateRead, StateWrite}; -use crate::{ - component::client_counter::{ics02_validation, ClientCounter, VerifiedHeights}, - event, -}; +use crate::component::client_counter::{ClientCounter, VerifiedHeights}; use super::state_key; @@ -32,44 +28,6 @@ use super::state_key; #[async_trait] pub(crate) trait Ics2ClientExt: StateWrite { - // execute a UpdateClient IBC action. this assumes that the UpdateClient has already been - // validated, including header verification. - async fn execute_update_client(&mut self, msg_update_client: &MsgUpdateClient) -> Result<()> { - // TODO(erwan): deferred client state deserialization means `execute_update_client` is faillible - // see ibc-rs ADR004: https://github.com/cosmos/ibc-rs/blob/main/docs/architecture/adr-004-light-client-crates-extraction.md#light-client-specific-code - let tm_header = ics02_validation::get_tendermint_header(msg_update_client.header.clone())?; - - // get the latest client state - let client_state = self - .get_client_state(&msg_update_client.client_id) - .await - .unwrap(); - - let (next_tm_client_state, next_tm_consensus_state) = self - .next_tendermint_state( - msg_update_client.client_id.clone(), - client_state.clone(), - tm_header.clone(), - ) - .await; - - // store the updated client and consensus states - self.put_client(&msg_update_client.client_id, next_tm_client_state); - self.put_verified_consensus_state( - tm_header.height(), - msg_update_client.client_id.clone(), - next_tm_consensus_state, - ) - .await - .unwrap(); - - self.record(event::update_client( - msg_update_client.client_id.clone(), - tm_header, - )); - Ok(()) - } - // given an already verified tendermint header, and a trusted tendermint client state, compute // the next client and consensus states. async fn next_tendermint_state( @@ -395,6 +353,7 @@ mod tests { use std::sync::Arc; use super::*; + use ibc_types::core::client::msgs::MsgUpdateClient; use ibc_types::{core::client::msgs::MsgCreateClient, DomainType}; use penumbra_chain::component::StateWriteExt; use penumbra_component::ActionHandler; diff --git a/crates/core/component/ibc/src/component/msg_handler/acknowledgement.rs b/crates/core/component/ibc/src/component/msg_handler/acknowledgement.rs index 56423b2829..6cbe75c77c 100644 --- a/crates/core/component/ibc/src/component/msg_handler/acknowledgement.rs +++ b/crates/core/component/ibc/src/component/msg_handler/acknowledgement.rs @@ -2,7 +2,8 @@ use anyhow::Result; use async_trait::async_trait; use ibc_types::core::{ channel::channel::Order as ChannelOrder, channel::channel::State as ChannelState, - channel::msgs::MsgAcknowledgement, channel::PortId, connection::State as ConnectionState, + channel::events, channel::msgs::MsgAcknowledgement, channel::PortId, + connection::State as ConnectionState, }; use penumbra_storage::StateWrite; @@ -15,8 +16,6 @@ use crate::component::{ MsgHandler, }; -use crate::event; - #[async_trait] impl MsgHandler for MsgAcknowledgement { async fn check_stateless(&self) -> Result<()> { @@ -96,7 +95,20 @@ impl MsgHandler for MsgAcknowledgement { self.packet.sequence.into(), ); - state.record(event::acknowledge_packet(&self.packet, &channel)); + state.record( + events::packet::AcknowledgePacket { + timeout_height: self.packet.timeout_height_on_b, + timeout_timestamp: self.packet.timeout_timestamp_on_b, + sequence: self.packet.sequence, + src_port_id: self.packet.port_on_a.clone(), + src_channel_id: self.packet.chan_on_a.clone(), + dst_port_id: self.packet.port_on_b.clone(), + dst_channel_id: self.packet.chan_on_b.clone(), + channel_ordering: channel.ordering, + src_connection_id: channel.connection_hops[0].clone(), + } + .into(), + ); let transfer = PortId::transfer(); if self.packet.port_on_b == transfer { diff --git a/crates/core/component/ibc/src/component/msg_handler/channel_close_confirm.rs b/crates/core/component/ibc/src/component/msg_handler/channel_close_confirm.rs index f43a263923..0700a94ba7 100644 --- a/crates/core/component/ibc/src/component/msg_handler/channel_close_confirm.rs +++ b/crates/core/component/ibc/src/component/msg_handler/channel_close_confirm.rs @@ -2,23 +2,20 @@ use anyhow::Result; use async_trait::async_trait; use ibc_types::core::{ channel::{ - channel::State as ChannelState, msgs::MsgChannelCloseConfirm, ChannelEnd, Counterparty, - PortId, + channel::State as ChannelState, events, msgs::MsgChannelCloseConfirm, ChannelEnd, + Counterparty, PortId, }, connection::State as ConnectionState, }; use penumbra_storage::StateWrite; -use crate::{ - component::{ - app_handler::{AppHandlerCheck, AppHandlerExecute}, - channel::{StateReadExt as _, StateWriteExt as _}, - connection::StateReadExt as _, - proof_verification::ChannelProofVerifier, - transfer::Ics20Transfer, - MsgHandler, - }, - event, +use crate::component::{ + app_handler::{AppHandlerCheck, AppHandlerExecute}, + channel::{StateReadExt as _, StateWriteExt as _}, + connection::StateReadExt as _, + proof_verification::ChannelProofVerifier, + transfer::Ics20Transfer, + MsgHandler, }; #[async_trait] @@ -93,11 +90,20 @@ impl MsgHandler for MsgChannelCloseConfirm { channel.set_state(ChannelState::Closed); state.put_channel(&self.chan_id_on_b, &self.port_id_on_b, channel.clone()); - state.record(event::channel_close_confirm( - &self.port_id_on_b, - &self.chan_id_on_b, - &channel, - )); + state.record( + events::channel::CloseConfirm { + port_id: self.port_id_on_b.clone(), + channel_id: self.chan_id_on_b.clone(), + counterparty_port_id: channel.counterparty().port_id.clone(), + counterparty_channel_id: channel + .counterparty() + .channel_id + .clone() + .unwrap_or_default(), + connection_id: channel.connection_hops[0].clone(), + } + .into(), + ); let transfer = PortId::transfer(); if self.port_id_on_b == transfer { diff --git a/crates/core/component/ibc/src/component/msg_handler/channel_close_init.rs b/crates/core/component/ibc/src/component/msg_handler/channel_close_init.rs index 3dfc94d4e7..602334e63b 100644 --- a/crates/core/component/ibc/src/component/msg_handler/channel_close_init.rs +++ b/crates/core/component/ibc/src/component/msg_handler/channel_close_init.rs @@ -1,20 +1,17 @@ use anyhow::Result; use async_trait::async_trait; use ibc_types::core::{ - channel::channel::State as ChannelState, channel::msgs::MsgChannelCloseInit, channel::PortId, - connection::State as ConnectionState, + channel::channel::State as ChannelState, channel::events, channel::msgs::MsgChannelCloseInit, + channel::PortId, connection::State as ConnectionState, }; use penumbra_storage::StateWrite; -use crate::{ - component::{ - app_handler::{AppHandlerCheck, AppHandlerExecute}, - channel::{StateReadExt as _, StateWriteExt as _}, - connection::StateReadExt as _, - transfer::Ics20Transfer, - MsgHandler, - }, - event, +use crate::component::{ + app_handler::{AppHandlerCheck, AppHandlerExecute}, + channel::{StateReadExt as _, StateWriteExt as _}, + connection::StateReadExt as _, + transfer::Ics20Transfer, + MsgHandler, }; #[async_trait] @@ -57,11 +54,20 @@ impl MsgHandler for MsgChannelCloseInit { channel.set_state(ChannelState::Closed); state.put_channel(&self.chan_id_on_a, &self.port_id_on_a, channel.clone()); - state.record(event::channel_close_init( - &self.port_id_on_a, - &self.chan_id_on_a, - &channel, - )); + state.record( + events::channel::CloseInit { + port_id: self.port_id_on_a.clone(), + channel_id: self.chan_id_on_a.clone(), + counterparty_port_id: channel.counterparty().port_id.clone(), + counterparty_channel_id: channel + .counterparty() + .channel_id + .clone() + .unwrap_or_default(), + connection_id: channel.connection_hops[0].clone(), + } + .into(), + ); let transfer = PortId::transfer(); if self.port_id_on_a == transfer { diff --git a/crates/core/component/ibc/src/component/msg_handler/channel_open_ack.rs b/crates/core/component/ibc/src/component/msg_handler/channel_open_ack.rs index d5e64e6590..b60260e533 100644 --- a/crates/core/component/ibc/src/component/msg_handler/channel_open_ack.rs +++ b/crates/core/component/ibc/src/component/msg_handler/channel_open_ack.rs @@ -1,22 +1,19 @@ use anyhow::Result; use async_trait::async_trait; use ibc_types::core::{ - channel::channel::State as ChannelState, channel::msgs::MsgChannelOpenAck, channel::ChannelEnd, - channel::Counterparty, channel::PortId, connection::ConnectionEnd, + channel::channel::State as ChannelState, channel::events, channel::msgs::MsgChannelOpenAck, + channel::ChannelEnd, channel::Counterparty, channel::PortId, connection::ConnectionEnd, connection::State as ConnectionState, }; use penumbra_storage::{StateRead, StateWrite}; -use crate::{ - component::{ - app_handler::{AppHandlerCheck, AppHandlerExecute}, - channel::{StateReadExt as _, StateWriteExt as _}, - connection::StateReadExt as _, - proof_verification::ChannelProofVerifier, - transfer::Ics20Transfer, - MsgHandler, - }, - event, +use crate::component::{ + app_handler::{AppHandlerCheck, AppHandlerExecute}, + channel::{StateReadExt as _, StateWriteExt as _}, + connection::StateReadExt as _, + proof_verification::ChannelProofVerifier, + transfer::Ics20Transfer, + MsgHandler, }; #[async_trait] @@ -80,11 +77,20 @@ impl MsgHandler for MsgChannelOpenAck { channel.set_counterparty_channel_id(self.chan_id_on_b.clone()); state.put_channel(&self.chan_id_on_a, &self.port_id_on_a, channel.clone()); - state.record(event::channel_open_ack( - &self.port_id_on_a, - &self.chan_id_on_a, - &channel, - )); + state.record( + events::channel::OpenAck { + port_id: self.port_id_on_a.clone(), + channel_id: self.chan_id_on_a.clone(), + counterparty_channel_id: channel + .counterparty() + .channel_id + .clone() + .unwrap_or_default(), + counterparty_port_id: channel.counterparty().port_id.clone(), + connection_id: channel.connection_hops[0].clone(), + } + .into(), + ); let transfer = PortId::transfer(); if self.port_id_on_a == transfer { diff --git a/crates/core/component/ibc/src/component/msg_handler/channel_open_confirm.rs b/crates/core/component/ibc/src/component/msg_handler/channel_open_confirm.rs index 6374c6579b..e1c199ae62 100644 --- a/crates/core/component/ibc/src/component/msg_handler/channel_open_confirm.rs +++ b/crates/core/component/ibc/src/component/msg_handler/channel_open_confirm.rs @@ -1,22 +1,19 @@ use anyhow::Result; use async_trait::async_trait; use ibc_types::core::{ - channel::channel::State as ChannelState, channel::msgs::MsgChannelOpenConfirm, + channel::channel::State as ChannelState, channel::events, channel::msgs::MsgChannelOpenConfirm, channel::ChannelEnd, channel::Counterparty, channel::PortId, connection::State as ConnectionState, }; use penumbra_storage::StateWrite; -use crate::{ - component::{ - app_handler::{AppHandlerCheck, AppHandlerExecute}, - channel::{StateReadExt as _, StateWriteExt as _}, - connection::StateReadExt as _, - proof_verification::ChannelProofVerifier, - transfer::Ics20Transfer, - MsgHandler, - }, - event, +use crate::component::{ + app_handler::{AppHandlerCheck, AppHandlerExecute}, + channel::{StateReadExt as _, StateWriteExt as _}, + connection::StateReadExt as _, + proof_verification::ChannelProofVerifier, + transfer::Ics20Transfer, + MsgHandler, }; #[async_trait] @@ -89,11 +86,20 @@ impl MsgHandler for MsgChannelOpenConfirm { channel.set_state(ChannelState::Open); state.put_channel(&self.chan_id_on_b, &self.port_id_on_b, channel.clone()); - state.record(event::channel_open_confirm( - &self.port_id_on_b, - &self.chan_id_on_b, - &channel, - )); + state.record( + events::channel::OpenConfirm { + port_id: self.port_id_on_b.clone(), + channel_id: self.chan_id_on_b.clone(), + counterparty_port_id: channel.counterparty().port_id.clone(), + counterparty_channel_id: channel + .counterparty() + .channel_id + .clone() + .unwrap_or_default(), + connection_id: channel.connection_hops[0].clone(), + } + .into(), + ); let transfer = PortId::transfer(); if self.port_id_on_b == transfer { diff --git a/crates/core/component/ibc/src/component/msg_handler/channel_open_init.rs b/crates/core/component/ibc/src/component/msg_handler/channel_open_init.rs index 1b8e91705a..3879a20150 100644 --- a/crates/core/component/ibc/src/component/msg_handler/channel_open_init.rs +++ b/crates/core/component/ibc/src/component/msg_handler/channel_open_init.rs @@ -1,18 +1,17 @@ use anyhow::Result; use async_trait::async_trait; use ibc_types::core::channel::msgs::MsgChannelOpenInit; -use ibc_types::core::channel::{channel::State, ChannelEnd, ChannelId, Counterparty, PortId}; +use ibc_types::core::channel::{ + channel::State, events, ChannelEnd, ChannelId, Counterparty, PortId, +}; use penumbra_storage::{StateRead, StateWrite}; -use crate::{ - component::{ - app_handler::{AppHandlerCheck, AppHandlerExecute}, - channel::{StateReadExt as _, StateWriteExt as _}, - connection::StateReadExt as _, - transfer::Ics20Transfer, - MsgHandler, - }, - event, +use crate::component::{ + app_handler::{AppHandlerCheck, AppHandlerExecute}, + channel::{StateReadExt as _, StateWriteExt as _}, + connection::StateReadExt as _, + transfer::Ics20Transfer, + MsgHandler, }; #[async_trait] @@ -55,11 +54,16 @@ impl MsgHandler for MsgChannelOpenInit { state.put_recv_sequence(&channel_id, &self.port_id_on_a, 1); state.put_ack_sequence(&channel_id, &self.port_id_on_a, 1); - state.record(event::channel_open_init( - &self.port_id_on_a, - &channel_id, - &new_channel, - )); + state.record( + events::channel::OpenInit { + port_id: self.port_id_on_a.clone(), + channel_id: channel_id.clone(), + counterparty_port_id: new_channel.counterparty().port_id().clone(), + connection_id: new_channel.connection_hops[0].clone(), + version: new_channel.version.clone(), + } + .into(), + ); let transfer = PortId::transfer(); if self.port_id_on_a == transfer { diff --git a/crates/core/component/ibc/src/component/msg_handler/channel_open_try.rs b/crates/core/component/ibc/src/component/msg_handler/channel_open_try.rs index 88c4341393..8b3fedca94 100644 --- a/crates/core/component/ibc/src/component/msg_handler/channel_open_try.rs +++ b/crates/core/component/ibc/src/component/msg_handler/channel_open_try.rs @@ -2,22 +2,20 @@ use anyhow::Result; use async_trait::async_trait; use ibc_types::core::{ channel::{ - channel::State as ChannelState, msgs::MsgChannelOpenTry, ChannelEnd, Counterparty, PortId, + channel::State as ChannelState, events, msgs::MsgChannelOpenTry, ChannelEnd, Counterparty, + PortId, }, connection::{ConnectionEnd, State as ConnectionState}, }; use penumbra_storage::{StateRead, StateWrite}; -use crate::{ - component::{ - app_handler::{AppHandlerCheck, AppHandlerExecute}, - channel::StateWriteExt, - connection::StateReadExt, - proof_verification::ChannelProofVerifier, - transfer::Ics20Transfer, - MsgHandler, - }, - event, +use crate::component::{ + app_handler::{AppHandlerCheck, AppHandlerExecute}, + channel::StateWriteExt, + connection::StateReadExt, + proof_verification::ChannelProofVerifier, + transfer::Ics20Transfer, + MsgHandler, }; #[async_trait] @@ -81,11 +79,21 @@ impl MsgHandler for MsgChannelOpenTry { state.put_recv_sequence(&channel_id, &self.port_id_on_b, 1); state.put_ack_sequence(&channel_id, &self.port_id_on_b, 1); - state.record(event::channel_open_try( - &self.port_id_on_b, - &channel_id, - &new_channel, - )); + state.record( + events::channel::OpenTry { + port_id: self.port_id_on_b.clone(), + channel_id: channel_id.clone(), + counterparty_port_id: new_channel.counterparty().port_id().clone(), + counterparty_channel_id: new_channel + .counterparty() + .channel_id + .clone() + .unwrap_or_default(), + connection_id: new_channel.connection_hops[0].clone(), + version: new_channel.version.clone(), + } + .into(), + ); let transfer = PortId::transfer(); if self.port_id_on_b == transfer { diff --git a/crates/core/component/ibc/src/component/msg_handler/connection_open_ack.rs b/crates/core/component/ibc/src/component/msg_handler/connection_open_ack.rs index d7f7638484..76731ed2f8 100644 --- a/crates/core/component/ibc/src/component/msg_handler/connection_open_ack.rs +++ b/crates/core/component/ibc/src/component/msg_handler/connection_open_ack.rs @@ -3,21 +3,18 @@ use async_trait::async_trait; use ibc_types::core::{ client::Height, commitment::MerkleProof, - connection::{msgs::MsgConnectionOpenAck, ConnectionEnd, Counterparty, State}, + connection::{events, msgs::MsgConnectionOpenAck, ConnectionEnd, Counterparty, State}, }; use ibc_types::lightclients::tendermint::client_state::ClientState as TendermintClientState; use ibc_types::path::{ClientConsensusStatePath, ClientStatePath, ConnectionPath}; use penumbra_chain::component::{StateReadExt as _, PENUMBRA_COMMITMENT_PREFIX}; use penumbra_storage::{StateRead, StateWrite}; -use crate::{ - component::{ - client::StateReadExt as _, - client_counter::validate_penumbra_client_state, - connection::{StateReadExt as _, StateWriteExt as _}, - proof_verification, MsgHandler, - }, - event, +use crate::component::{ + client::StateReadExt as _, + client_counter::validate_penumbra_client_state, + connection::{StateReadExt as _, StateWriteExt as _}, + proof_verification, MsgHandler, }; #[async_trait] @@ -168,7 +165,7 @@ impl MsgHandler for MsgConnectionOpenAck { let counterparty = Counterparty { client_id: prev_counterparty.client_id.clone(), connection_id: Some(self.conn_id_on_b.clone()), - prefix: prev_counterparty.prefix.clone(), + prefix: prev_counterparty.prefix, }; connection.state = State::Open; connection.versions = vec![self.version.clone()]; @@ -176,7 +173,19 @@ impl MsgHandler for MsgConnectionOpenAck { state.update_connection(&self.conn_id_on_a, connection.clone()); - state.record(event::connection_open_ack(&self.conn_id_on_a, &connection)); + state.record( + events::ConnectionOpenAck { + conn_id_on_a: self.conn_id_on_a.clone(), + client_id_on_a: connection.client_id.clone(), + conn_id_on_b: connection + .counterparty + .connection_id + .clone() + .unwrap_or_default(), + client_id_on_b: connection.counterparty.client_id, + } + .into(), + ); Ok(()) } diff --git a/crates/core/component/ibc/src/component/msg_handler/connection_open_confirm.rs b/crates/core/component/ibc/src/component/msg_handler/connection_open_confirm.rs index 764789e036..219f939d96 100644 --- a/crates/core/component/ibc/src/component/msg_handler/connection_open_confirm.rs +++ b/crates/core/component/ibc/src/component/msg_handler/connection_open_confirm.rs @@ -3,20 +3,17 @@ use async_trait::async_trait; use ibc_types::{ core::{ commitment::MerkleProof, - connection::{msgs::MsgConnectionOpenConfirm, ConnectionEnd, Counterparty, State}, + connection::{events, msgs::MsgConnectionOpenConfirm, ConnectionEnd, Counterparty, State}, }, path::ConnectionPath, }; use penumbra_chain::component::PENUMBRA_COMMITMENT_PREFIX; use penumbra_storage::{StateRead, StateWrite}; -use crate::{ - component::{ - client::StateReadExt as _, - connection::{StateReadExt as _, StateWriteExt as _}, - proof_verification, MsgHandler, - }, - event, +use crate::component::{ + client::StateReadExt as _, + connection::{StateReadExt as _, StateWriteExt as _}, + proof_verification, MsgHandler, }; #[async_trait] @@ -99,10 +96,19 @@ impl MsgHandler for MsgConnectionOpenConfirm { state.update_connection(&self.conn_id_on_b, connection.clone()); - state.record(event::connection_open_confirm( - &self.conn_id_on_b, - &connection, - )); + state.record( + events::ConnectionOpenConfirm { + conn_id_on_b: self.conn_id_on_b.clone(), + client_id_on_b: connection.client_id.clone(), + conn_id_on_a: connection + .counterparty + .connection_id + .clone() + .unwrap_or_default(), + client_id_on_a: connection.counterparty.client_id, + } + .into(), + ); Ok(()) } @@ -118,7 +124,7 @@ async fn verify_previous_connection( .ok_or_else(|| anyhow::anyhow!("connection not found"))?; if !connection.state_matches(&State::TryOpen) { - return Err(anyhow::anyhow!("connection not in correct state")); + Err(anyhow::anyhow!("connection not in correct state")) } else { Ok(connection) } diff --git a/crates/core/component/ibc/src/component/msg_handler/connection_open_init.rs b/crates/core/component/ibc/src/component/msg_handler/connection_open_init.rs index 968eca4cc9..68c41c8b27 100644 --- a/crates/core/component/ibc/src/component/msg_handler/connection_open_init.rs +++ b/crates/core/component/ibc/src/component/msg_handler/connection_open_init.rs @@ -1,17 +1,14 @@ use anyhow::Result; use async_trait::async_trait; use ibc_types::core::connection::{ - msgs::MsgConnectionOpenInit, ConnectionEnd, ConnectionId, Version, + events, msgs::MsgConnectionOpenInit, ConnectionEnd, ConnectionId, Version, }; -use crate::{ - component::{ - client::StateReadExt as _, - connection::{StateReadExt as _, StateWriteExt as _}, - connection_counter::SUPPORTED_VERSIONS, - MsgHandler, - }, - event, +use crate::component::{ + client::StateReadExt as _, + connection::{StateReadExt as _, StateWriteExt as _}, + connection_counter::SUPPORTED_VERSIONS, + MsgHandler, }; use ibc_types::core::connection::State as ConnectionState; @@ -50,11 +47,14 @@ impl MsgHandler for MsgConnectionOpenInit { .await .unwrap(); - state.record(event::connection_open_init( - &connection_id, - &self.client_id_on_a, - &self.counterparty, - )); + state.record( + events::ConnectionOpenInit { + connection_id: connection_id.clone(), + client_id_on_a: self.client_id_on_a.clone(), + client_id_on_b: self.counterparty.client_id.clone(), + } + .into(), + ); Ok(()) } diff --git a/crates/core/component/ibc/src/component/msg_handler/connection_open_try.rs b/crates/core/component/ibc/src/component/msg_handler/connection_open_try.rs index 8b3b160891..b720770481 100644 --- a/crates/core/component/ibc/src/component/msg_handler/connection_open_try.rs +++ b/crates/core/component/ibc/src/component/msg_handler/connection_open_try.rs @@ -8,22 +8,19 @@ use ibc_types::path::{ClientConsensusStatePath, ClientStatePath, ConnectionPath} use ibc_types::{ core::client::Height as IBCHeight, core::connection::{ - msgs::MsgConnectionOpenTry, ConnectionEnd, ConnectionId, Counterparty, + events, msgs::MsgConnectionOpenTry, ConnectionEnd, ConnectionId, Counterparty, State as ConnectionState, }, }; use penumbra_chain::component::{StateReadExt as _, PENUMBRA_COMMITMENT_PREFIX}; use penumbra_storage::{StateRead, StateWrite}; -use crate::{ - component::{ - client::StateReadExt as _, - client_counter::validate_penumbra_client_state, - connection::{StateReadExt as _, StateWriteExt as _}, - connection_counter::SUPPORTED_VERSIONS, - MsgHandler, - }, - event, +use crate::component::{ + client::StateReadExt as _, + client_counter::validate_penumbra_client_state, + connection::{StateReadExt as _, StateWriteExt as _}, + connection_counter::SUPPORTED_VERSIONS, + MsgHandler, }; #[async_trait] @@ -183,11 +180,15 @@ impl MsgHandler for MsgConnectionOpenTry { .await .unwrap(); - state.record(event::connection_open_try( - &new_connection_id, - &self.client_id_on_b, - &self.counterparty, - )); + state.record( + events::ConnectionOpenTry { + conn_id_on_b: new_connection_id.clone(), + client_id_on_b: self.client_id_on_b.clone(), + conn_id_on_a: self.counterparty.connection_id.clone().unwrap_or_default(), + client_id_on_a: self.counterparty.client_id.clone(), + } + .into(), + ); Ok(()) } diff --git a/crates/core/component/ibc/src/component/msg_handler/create_client.rs b/crates/core/component/ibc/src/component/msg_handler/create_client.rs index ab011313f4..3481bb0ed0 100644 --- a/crates/core/component/ibc/src/component/msg_handler/create_client.rs +++ b/crates/core/component/ibc/src/component/msg_handler/create_client.rs @@ -1,18 +1,15 @@ use anyhow::Result; use async_trait::async_trait; use ibc_types::{ - core::client::{msgs::MsgCreateClient, ClientId}, + core::client::{events::CreateClient, msgs::MsgCreateClient, ClientId}, lightclients::tendermint::client_type, }; use penumbra_storage::StateWrite; -use crate::{ - component::{ - client::{StateReadExt as _, StateWriteExt as _}, - client_counter::{ics02_validation, ClientCounter}, - MsgHandler, - }, - event, +use crate::component::{ + client::{StateReadExt as _, StateWriteExt as _}, + client_counter::{ics02_validation, ClientCounter}, + MsgHandler, }; #[async_trait] @@ -62,7 +59,14 @@ impl MsgHandler for MsgCreateClient { let counter = state.client_counter().await.unwrap_or(ClientCounter(0)); state.put_client_counter(ClientCounter(counter.0 + 1)); - state.record(event::create_client(client_id, client_state)); + state.record( + CreateClient { + client_id: client_id.clone(), + client_type: client_type(), + consensus_height: client_state.latest_height(), + } + .into(), + ); Ok(()) } } diff --git a/crates/core/component/ibc/src/component/msg_handler/recv_packet.rs b/crates/core/component/ibc/src/component/msg_handler/recv_packet.rs index 127bc818ee..9489d02ba2 100644 --- a/crates/core/component/ibc/src/component/msg_handler/recv_packet.rs +++ b/crates/core/component/ibc/src/component/msg_handler/recv_packet.rs @@ -3,6 +3,7 @@ use async_trait::async_trait; use ibc_types::core::{ channel::{ channel::{Order as ChannelOrder, State as ChannelState}, + events, msgs::MsgRecvPacket, PortId, }, @@ -12,16 +13,13 @@ use ibc_types::core::{ use penumbra_chain::component::StateReadExt; use penumbra_storage::StateWrite; -use crate::{ - component::{ - app_handler::{AppHandlerCheck, AppHandlerExecute}, - channel::{StateReadExt as _, StateWriteExt}, - connection::StateReadExt as _, - proof_verification::PacketProofVerifier, - transfer::Ics20Transfer, - MsgHandler, - }, - event, +use crate::component::{ + app_handler::{AppHandlerCheck, AppHandlerExecute}, + channel::{StateReadExt as _, StateWriteExt}, + connection::StateReadExt as _, + proof_verification::PacketProofVerifier, + transfer::Ics20Transfer, + MsgHandler, }; #[async_trait] @@ -123,7 +121,21 @@ impl MsgHandler for MsgRecvPacket { state.put_packet_receipt(&self.packet); } - state.record(event::receive_packet(&self.packet, &channel)); + state.record( + events::packet::ReceivePacket { + packet_data: self.packet.data.clone(), + timeout_height: self.packet.timeout_height_on_b.clone(), + timeout_timestamp: self.packet.timeout_timestamp_on_b.clone(), + sequence: self.packet.sequence.clone(), + src_port_id: self.packet.port_on_a.clone(), + src_channel_id: self.packet.chan_on_a.clone(), + dst_port_id: self.packet.port_on_b.clone(), + dst_channel_id: self.packet.chan_on_b.clone(), + channel_ordering: channel.ordering.clone(), + dst_connection_id: channel.connection_hops[0].clone(), + } + .into(), + ); let transfer = PortId::transfer(); if self.packet.port_on_b == transfer { diff --git a/crates/core/component/ibc/src/component/msg_handler/timeout.rs b/crates/core/component/ibc/src/component/msg_handler/timeout.rs index b6fafd6dd0..1bd356764f 100644 --- a/crates/core/component/ibc/src/component/msg_handler/timeout.rs +++ b/crates/core/component/ibc/src/component/msg_handler/timeout.rs @@ -2,22 +2,20 @@ use anyhow::Result; use async_trait::async_trait; use ibc_types::core::channel::{ channel::{Order as ChannelOrder, State as ChannelState}, + events, msgs::MsgTimeout, PortId, }; use penumbra_storage::StateWrite; -use crate::{ - component::{ - app_handler::{AppHandlerCheck, AppHandlerExecute}, - channel::{StateReadExt as _, StateWriteExt}, - client::StateReadExt, - connection::StateReadExt as _, - proof_verification::{commit_packet, PacketProofVerifier}, - transfer::Ics20Transfer, - MsgHandler, - }, - event, +use crate::component::{ + app_handler::{AppHandlerCheck, AppHandlerExecute}, + channel::{StateReadExt as _, StateWriteExt}, + client::StateReadExt, + connection::StateReadExt as _, + proof_verification::{commit_packet, PacketProofVerifier}, + transfer::Ics20Transfer, + MsgHandler, }; #[async_trait] @@ -120,7 +118,19 @@ impl MsgHandler for MsgTimeout { ); } - state.record(event::timeout_packet(&self.packet, &channel)); + state.record( + events::packet::TimeoutPacket { + timeout_height: self.packet.timeout_height_on_b, + timeout_timestamp: self.packet.timeout_timestamp_on_b, + sequence: self.packet.sequence, + src_port_id: self.packet.port_on_a.clone(), + src_channel_id: self.packet.chan_on_a.clone(), + dst_port_id: self.packet.port_on_b.clone(), + dst_channel_id: self.packet.chan_on_b.clone(), + channel_ordering: channel.ordering, + } + .into(), + ); let transfer = PortId::transfer(); if self.packet.port_on_b == transfer { diff --git a/crates/core/component/ibc/src/component/msg_handler/update_client.rs b/crates/core/component/ibc/src/component/msg_handler/update_client.rs index d14e6003df..01cc413d17 100644 --- a/crates/core/component/ibc/src/component/msg_handler/update_client.rs +++ b/crates/core/component/ibc/src/component/msg_handler/update_client.rs @@ -1,10 +1,12 @@ use anyhow::{Context, Result}; use async_trait::async_trait; use ibc_types::{ - core::{client::msgs::MsgUpdateClient, client::ClientId}, + core::{client::events::UpdateClient, client::msgs::MsgUpdateClient, client::ClientId}, lightclients::tendermint::client_state::ClientState as TendermintClientState, - lightclients::tendermint::consensus_state::ConsensusState as TendermintConsensusState, lightclients::tendermint::header::Header as TendermintHeader, + lightclients::tendermint::{ + consensus_state::ConsensusState as TendermintConsensusState, TENDERMINT_CLIENT_TYPE, + }, }; use penumbra_chain::component::StateReadExt as _; use penumbra_storage::{StateRead, StateWrite}; @@ -14,13 +16,10 @@ use tendermint_light_client_verifier::{ ProdVerifier, Verdict, Verifier, }; -use crate::{ - component::{ - client::{Ics2ClientExt as _, StateReadExt as _, StateWriteExt as _}, - client_counter::ics02_validation, - MsgHandler, - }, - event, +use crate::component::{ + client::{Ics2ClientExt as _, StateReadExt as _, StateWriteExt as _}, + client_counter::ics02_validation, + MsgHandler, }; #[async_trait] @@ -135,8 +134,17 @@ impl MsgHandler for MsgUpdateClient { ) .await?; - state.record(event::update_client(self.client_id.clone(), trusted_header)); - + state.record( + UpdateClient { + client_id: self.client_id.clone(), + client_type: ibc_types::core::client::ClientType( + TENDERMINT_CLIENT_TYPE.to_string(), + ), // TODO: hardcoded + consensus_height: trusted_header.height(), + header: >::encode_vec(&trusted_header), + } + .into(), + ); return Ok(()); } else { tracing::debug!("skipping duplicate update"); diff --git a/crates/core/component/ibc/src/component/packet.rs b/crates/core/component/ibc/src/component/packet.rs index 5a3c301cc2..fe79a86a41 100644 --- a/crates/core/component/ibc/src/component/packet.rs +++ b/crates/core/component/ibc/src/component/packet.rs @@ -1,7 +1,7 @@ use anyhow::Result; use async_trait::async_trait; use ibc_types::core::{ - channel::{channel::State as ChannelState, ChannelId, Packet, PortId}, + channel::{channel::State as ChannelState, events, ChannelId, Packet, PortId}, client::Height, }; use penumbra_storage::{StateRead, StateWrite}; @@ -12,7 +12,7 @@ use crate::{ client::StateReadExt as _, connection::StateReadExt as _, }, - event, Ics20Withdrawal, + Ics20Withdrawal, }; pub trait CheckStatus: private::Sealed {} @@ -150,16 +150,31 @@ pub trait SendPacketWrite: StateWrite { .unwrap(); self.put_send_sequence(&packet.source_channel, &packet.source_port, sequence + 1); + let channel = self + .get_channel(&packet.source_channel, &packet.source_port) + .await + .expect("should be able to get channel") + .ok_or_else(|| { + anyhow::anyhow!( + "channel {} on port {} does not exist", + packet.source_channel, + packet.source_port + ) + }) + .expect("should be able to get channel"); + // store commitment to the packet data & packet timeout let packet = Packet { chan_on_a: packet.source_channel, port_on_a: packet.source_port.clone(), sequence: sequence.into(), - // NOTE: the packet commitment is solely a function of the source port and channel, so - // these fields do not affect the commitment. Thus, we can set them to empty values. - chan_on_b: ChannelId::default(), - port_on_b: PortId::default(), + chan_on_b: channel + .counterparty() + .channel_id + .clone() + .expect("should have counterparty channel"), + port_on_b: channel.counterparty().port_id.clone(), timeout_height_on_b: packet.timeout_height.into(), timeout_timestamp_on_b: ibc_types::timestamp::Timestamp::from_nanoseconds( @@ -171,6 +186,22 @@ pub trait SendPacketWrite: StateWrite { }; self.put_packet_commitment(&packet); + + self.record( + events::packet::SendPacket { + packet_data: packet.data.clone(), + timeout_height: packet.timeout_height_on_b, + timeout_timestamp: packet.timeout_timestamp_on_b, + sequence: packet.sequence, + src_port_id: packet.port_on_a.clone(), + src_channel_id: packet.chan_on_a.clone(), + dst_port_id: packet.port_on_b.clone(), + dst_channel_id: packet.chan_on_b, + channel_ordering: channel.ordering, + src_connection_id: channel.connection_hops[0].clone(), + } + .into(), + ); } } @@ -196,6 +227,17 @@ pub trait WriteAcknowledgement: StateWrite { return Err(anyhow::anyhow!("acknowledgement already exists")); } + let channel = self + .get_channel(&packet.chan_on_b, &packet.port_on_b) + .await? + .ok_or_else(|| { + anyhow::anyhow!( + "channel {} on port {} does not exist", + packet.chan_on_b, + packet.port_on_b + ) + })?; + self.put_packet_acknowledgement( &packet.port_on_b, &packet.chan_on_b, @@ -203,7 +245,21 @@ pub trait WriteAcknowledgement: StateWrite { ack_bytes, ); - self.record(event::write_acknowledgement(packet, ack_bytes)); + self.record( + events::packet::WriteAcknowledgement { + packet_data: packet.data.clone(), + timeout_height: packet.timeout_height_on_b, + timeout_timestamp: packet.timeout_timestamp_on_b, + sequence: packet.sequence, + src_port_id: packet.port_on_a.clone(), + src_channel_id: packet.chan_on_a.clone(), + dst_port_id: packet.port_on_b.clone(), + dst_channel_id: packet.chan_on_b.clone(), + acknowledgement: ack_bytes.to_vec(), + dst_connection_id: channel.connection_hops[0].clone(), + } + .into(), + ); Ok(()) } diff --git a/crates/core/component/ibc/src/event.rs b/crates/core/component/ibc/src/event.rs deleted file mode 100644 index 5b194dcd4d..0000000000 --- a/crates/core/component/ibc/src/event.rs +++ /dev/null @@ -1,403 +0,0 @@ -use ibc_proto::protobuf::Protobuf; -use ibc_types::lightclients::tendermint::client_state::ClientState as TendermintClientState; -use ibc_types::lightclients::tendermint::header::Header as TendermintHeader; -use ibc_types::{ - core::{ - channel::{ChannelEnd, ChannelId, Packet, PortId}, - client::ClientId, - connection::{ConnectionEnd, ConnectionId, Counterparty}, - }, - lightclients::tendermint::TENDERMINT_CLIENT_TYPE, -}; -use tendermint::abci::{Event, EventAttributeIndexExt}; - -pub fn create_client(client_id: ClientId, client_state: TendermintClientState) -> Event { - Event::new( - "create_client", - vec![ - ("client_id", client_id.to_string()).index(), - // BUG: impl Display for ClientType is wrong and doesn't match as_str - ("client_type", TENDERMINT_CLIENT_TYPE.to_owned()).index(), - ("consensus_height", client_state.latest_height().to_string()).index(), - ], - ) -} - -pub fn update_client(client_id: ClientId, header: TendermintHeader) -> Event { - // AYFK - // lol - let header_hex_proto_bytes = >::encode_to_hex_string(&header); - Event::new( - "update_client", - vec![ - ("client_id", client_id.to_string()).index(), - // BUG: impl Display for ClientType is wrong and doesn't match as_str - ("client_type", TENDERMINT_CLIENT_TYPE.to_owned()).index(), - ("consensus_height", header.height().to_string()).index(), - // We need to encode the header as hex-encoded proto-encoded bytes. - ("header", header_hex_proto_bytes).index(), - ], - ) -} - -pub fn connection_open_init( - connection_id: &ConnectionId, - client_id: &ClientId, - counterparty: &Counterparty, -) -> Event { - Event::new( - "connection_open_init", - vec![ - ("connection_id", connection_id.to_string()).index(), - ("client_id", client_id.to_string()).index(), - ("counterparty_client_id", counterparty.client_id.to_string()).index(), - ( - "counterparty_connection_id", - counterparty - .connection_id - .clone() - .map(|id| id.to_string()) - .unwrap_or_default(), - ) - .index(), - ], - ) -} - -pub fn connection_open_try( - connection_id: &ConnectionId, - client_id: &ClientId, - counterparty: &Counterparty, -) -> Event { - Event::new( - "connection_open_try", - vec![ - ("connection_id", connection_id.to_string()).index(), - ("client_id", client_id.to_string()).index(), - ("counterparty_client_id", counterparty.client_id.to_string()).index(), - ( - "counterparty_connection_id", - counterparty - .connection_id - .clone() - .map(|id| id.to_string()) - .unwrap_or_default(), - ) - .index(), - ], - ) -} - -pub fn connection_open_ack(connection_id: &ConnectionId, connection_end: &ConnectionEnd) -> Event { - Event::new( - "connection_open_ack", - vec![ - ("connection_id", connection_id.to_string()).index(), - ("client_id", connection_end.client_id.to_string()).index(), - ( - "counterparty_client_id", - connection_end.counterparty.client_id.to_string(), - ) - .index(), - ( - "counterparty_connection_id", - connection_end - .counterparty - .connection_id - .clone() - .map(|id| id.to_string()) - .unwrap_or_default(), - ) - .index(), - ], - ) -} - -pub fn connection_open_confirm( - connection_id: &ConnectionId, - connection_end: &ConnectionEnd, -) -> Event { - Event::new( - "connection_open_confirm", - vec![ - ("connection_id", connection_id.to_string()).index(), - ("client_id", connection_end.client_id.to_string()).index(), - ( - "counterparty_client_id", - connection_end.counterparty.client_id.to_string(), - ) - .index(), - ( - "counterparty_connection_id", - connection_end - .counterparty - .connection_id - .clone() - .map(|id| id.to_string()) - .unwrap_or_default(), - ) - .index(), - ], - ) -} - -pub fn channel_open_init(port_id: &PortId, channel_id: &ChannelId, channel: &ChannelEnd) -> Event { - Event::new( - "channel_open_init", - vec![ - ("port_id", port_id.to_string()).index(), - ("channel_id", channel_id.to_string()).index(), - ( - "counterparty_port_id", - channel.counterparty().port_id().to_string(), - ) - .index(), - ( - "counterparty_channel_id", - channel - .counterparty() - .channel_id() - .map(|id| id.to_string()) - .unwrap_or_default(), - ) - .index(), - ("connection_id", channel.connection_hops[0].to_string()).index(), - ], - ) -} - -pub fn channel_open_try(port_id: &PortId, channel_id: &ChannelId, channel: &ChannelEnd) -> Event { - Event::new( - "channel_open_try", - vec![ - ("port_id", port_id.to_string()).index(), - ("channel_id", channel_id.to_string()).index(), - ( - "counterparty_port_id", - channel.counterparty().port_id().to_string(), - ) - .index(), - ( - "counterparty_channel_id", - channel - .counterparty() - .channel_id() - .map(|id| id.to_string()) - .unwrap_or_default(), - ) - .index(), - ("connection_id", channel.connection_hops[0].to_string()).index(), - ], - ) -} - -pub fn channel_open_ack(port_id: &PortId, channel_id: &ChannelId, channel: &ChannelEnd) -> Event { - Event::new( - "channel_open_ack", - vec![ - ("port_id", port_id.to_string()).index(), - ("channel_id", channel_id.to_string()).index(), - ( - "counterparty_port_id", - channel.counterparty().port_id().to_string(), - ) - .index(), - ( - "counterparty_channel_id", - channel - .counterparty() - .channel_id() - .map(|id| id.to_string()) - .unwrap_or_default(), - ) - .index(), - ("connection_id", channel.connection_hops[0].to_string()).index(), - ], - ) -} - -pub fn channel_open_confirm( - port_id: &PortId, - channel_id: &ChannelId, - channel: &ChannelEnd, -) -> Event { - Event::new( - "channel_open_confirm", - vec![ - ("port_id", port_id.to_string()).index(), - ("channel_id", channel_id.to_string()).index(), - ( - "counterparty_port_id", - channel.counterparty().port_id().to_string(), - ) - .index(), - ( - "counterparty_channel_id", - channel - .counterparty() - .channel_id() - .map(|id| id.to_string()) - .unwrap_or_default(), - ) - .index(), - ("connection_id", channel.connection_hops[0].to_string()).index(), - ], - ) -} - -pub fn channel_close_init(port_id: &PortId, channel_id: &ChannelId, channel: &ChannelEnd) -> Event { - Event::new( - "channel_close_init", - vec![ - ("port_id", port_id.to_string()).index(), - ("channel_id", channel_id.to_string()).index(), - ( - "counterparty_port_id", - channel.counterparty().port_id().to_string(), - ) - .index(), - ( - "counterparty_channel_id", - channel - .counterparty() - .channel_id() - .map(|id| id.to_string()) - .unwrap_or_default(), - ) - .index(), - ("connection_id", channel.connection_hops[0].to_string()).index(), - ], - ) -} - -pub fn channel_close_confirm( - port_id: &PortId, - channel_id: &ChannelId, - channel: &ChannelEnd, -) -> Event { - Event::new( - "channel_close_confirm", - vec![ - ("port_id", port_id.to_string()).index(), - ("channel_id", channel_id.to_string()).index(), - ( - "counterparty_port_id", - channel.counterparty().port_id().to_string(), - ) - .index(), - ( - "counterparty_channel_id", - channel - .counterparty() - .channel_id() - .map(|id| id.to_string()) - .unwrap_or_default(), - ) - .index(), - ("connection_id", channel.connection_hops[0].to_string()).index(), - ], - ) -} - -// TODO: add packet send - -pub fn receive_packet(packet: &Packet, channel: &ChannelEnd) -> Event { - Event::new( - "recv_packet", - vec![ - ("packet_data_hex", hex::encode(packet.data.clone())).index(), - ( - "packet_timeout_height", - packet.timeout_height_on_b.to_string(), - ) - .index(), - ( - "packet_timeout_timestamp", - packet.timeout_timestamp_on_b.to_string(), - ) - .index(), - ("packet_sequence", packet.sequence.to_string()).index(), - ("packet_src_port", packet.port_on_a.to_string()).index(), - ("packet_src_channel", packet.chan_on_a.to_string()).index(), - ("packet_dst_port", packet.port_on_b.to_string()).index(), - ("packet_dst_channel", packet.chan_on_b.to_string()).index(), - ("packet_channel_ordering", channel.ordering.to_string()).index(), - ("packet_connection", channel.connection_hops[0].to_string()).index(), - ], - ) -} - -pub fn acknowledge_packet(packet: &Packet, channel: &ChannelEnd) -> Event { - Event::new( - "acknowledge_packet", - vec![ - ("packet_data_hex", hex::encode(packet.data.clone())).index(), - ( - "packet_timeout_height", - packet.timeout_height_on_b.to_string(), - ) - .index(), - ( - "packet_timeout_timestamp", - packet.timeout_timestamp_on_b.to_string(), - ) - .index(), - ("packet_sequence", packet.sequence.to_string()).index(), - ("packet_src_port", packet.port_on_a.to_string()).index(), - ("packet_src_channel", packet.chan_on_a.to_string()).index(), - ("packet_dst_port", packet.port_on_b.to_string()).index(), - ("packet_dst_channel", packet.chan_on_b.to_string()).index(), - ("packet_channel_ordering", channel.ordering.to_string()).index(), - ("packet_connection", channel.connection_hops[0].to_string()).index(), - ], - ) -} - -pub fn write_acknowledgement(packet: &Packet, ack_bytes: &[u8]) -> Event { - Event::new( - "write_acknowledgement", - vec![ - ("packet_data", hex::encode(packet.data.clone())).index(), - ("timeout_height", packet.timeout_height_on_b.to_string()).index(), - ( - "timeout_timestamp", - packet.timeout_timestamp_on_b.to_string(), - ) - .index(), - ("sequence", packet.sequence.to_string()).index(), - ("src_port", packet.port_on_a.to_string()).index(), - ("src_channel", packet.chan_on_a.to_string()).index(), - ("dst_port", packet.port_on_b.to_string()).index(), - ("dst_channel", packet.chan_on_b.to_string()).index(), - ("acknowledgement", hex::encode(ack_bytes)).index(), - ], - ) -} - -pub fn timeout_packet(packet: &Packet, channel: &ChannelEnd) -> Event { - Event::new( - "timeout_packet", - vec![ - ("packet_data_hex", hex::encode(packet.data.clone())).index(), - ( - "packet_timeout_height", - packet.timeout_height_on_b.to_string(), - ) - .index(), - ( - "packet_timeout_timestamp", - packet.timeout_timestamp_on_b.to_string(), - ) - .index(), - ("packet_sequence", packet.sequence.to_string()).index(), - ("packet_src_port", packet.port_on_a.to_string()).index(), - ("packet_src_channel", packet.chan_on_a.to_string()).index(), - ("packet_dst_port", packet.port_on_b.to_string()).index(), - ("packet_dst_channel", packet.chan_on_b.to_string()).index(), - ("packet_channel_ordering", channel.ordering.to_string()).index(), - ("packet_connection", channel.connection_hops[0].to_string()).index(), - ], - ) -} diff --git a/crates/core/component/ibc/src/lib.rs b/crates/core/component/ibc/src/lib.rs index 1ba0f64869..546e859fab 100644 --- a/crates/core/component/ibc/src/lib.rs +++ b/crates/core/component/ibc/src/lib.rs @@ -8,8 +8,6 @@ #[cfg(feature = "component")] pub mod component; -pub mod event; - mod ibc_action; mod ibc_token; mod ics20_withdrawal;