Skip to content

Commit

Permalink
Refactor event traits to better support Starknet events (#531)
Browse files Browse the repository at this point in the history
* Define event extractor traits

* Rename ChannelClosedError to ErrChannelClosed

* Implement CanExtractFromEvent<CosmosCreateClientEvent>

* Use CanExtractFromMessageResponse for create client events

* Use extractor for connection and channel events

* Refactor send packet event

* Refactor write ack event

* Remove unused trait bounds

* Add provider trait for HasEventSubscription

* Return Option in event subscription getter

* Remove HasEventType bound from HasSendPacketEvent

* Relax API for build_packet_from_write_ack_event

* Introduce CanBuildPacketFromSendPacket

* Move around PacketFromWriteAckEventBuilder

* Remove extract packet method from HasSendPacketEvent

* Add build_ack_from_write_ack_event

* Fix clippy
  • Loading branch information
soareschen authored Jan 24, 2025
1 parent 3ff219f commit 8e62668
Show file tree
Hide file tree
Showing 48 changed files with 582 additions and 330 deletions.
1 change: 1 addition & 0 deletions crates/chain/chain-components/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#![no_std]
#![allow(clippy::type_complexity)]

extern crate alloc;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
use cgp::prelude::*;
use hermes_runtime_components::traits::runtime::HasRuntime;
use hermes_runtime_components::traits::subscription::HasSubscription;

use crate::traits::types::event::HasEventType;
use crate::traits::types::height::HasHeightType;

#[cgp_component {
provider: EventSubscriptionGetter,
context: Chain,
}]
pub trait HasEventSubscription: HasHeightType + HasEventType + HasRuntime
where
Self::Runtime: HasSubscription,
{
fn event_subscription(
&self,
) -> &<Self::Runtime as HasSubscription>::Subscription<(Self::Height, Self::Event)>;
) -> Option<&<Self::Runtime as HasSubscription>::Subscription<(Self::Height, Self::Event)>>;
}
74 changes: 74 additions & 0 deletions crates/chain/chain-components/src/traits/extract_data.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
use core::marker::PhantomData;

use cgp::core::component::UseDelegate;
use cgp::prelude::*;
use hermes_chain_type_components::traits::fields::message_response_events::HasMessageResponseEvents;
use hermes_chain_type_components::traits::types::event::HasEventType;
use hermes_chain_type_components::traits::types::message_response::HasMessageResponseType;

#[cgp_component {
provider: MessageResponseExtractor,
context: Chain,
}]
pub trait CanExtractFromMessageResponse<Data>: HasMessageResponseType {
fn try_extract_from_message_response(
&self,
_tag: PhantomData<Data>,
message_response: &Self::MessageResponse,
) -> Option<Data>;
}

#[cgp_component {
provider: EventExtractor,
context: Chain,
}]
pub trait CanExtractFromEvent<Data>: HasEventType {
fn try_extract_from_event(&self, _tag: PhantomData<Data>, event: &Self::Event) -> Option<Data>;
}

pub struct ExtractFromMessageResponseViaEvents;

impl<Chain, Data> MessageResponseExtractor<Chain, Data> for ExtractFromMessageResponseViaEvents
where
Chain: HasMessageResponseEvents + CanExtractFromEvent<Data>,
{
fn try_extract_from_message_response(
chain: &Chain,
tag: PhantomData<Data>,
message_response: &Chain::MessageResponse,
) -> Option<Data> {
Chain::message_response_events(message_response)
.iter()
.find_map(|event| chain.try_extract_from_event(tag, event))
}
}

impl<Chain, Data, Components> MessageResponseExtractor<Chain, Data> for UseDelegate<Components>
where
Chain: HasMessageResponseType,
Components: DelegateComponent<Data>,
Components::Delegate: MessageResponseExtractor<Chain, Data>,
{
fn try_extract_from_message_response(
chain: &Chain,
tag: PhantomData<Data>,
message_response: &Chain::MessageResponse,
) -> Option<Data> {
Components::Delegate::try_extract_from_message_response(chain, tag, message_response)
}
}

impl<Chain, Data, Components> EventExtractor<Chain, Data> for UseDelegate<Components>
where
Chain: HasEventType,
Components: DelegateComponent<Data>,
Components::Delegate: EventExtractor<Chain, Data>,
{
fn try_extract_from_event(
chain: &Chain,
tag: PhantomData<Data>,
event: &Chain::Event,
) -> Option<Data> {
Components::Delegate::try_extract_from_event(chain, tag, event)
}
}
1 change: 1 addition & 0 deletions crates/chain/chain-components/src/traits/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
pub mod commitment_prefix;
pub mod event_subscription;
pub mod extract_data;
pub mod message_builders;
pub mod packet;
pub mod payload_builders;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
use cgp::prelude::*;
use hermes_chain_type_components::traits::types::ibc::packet::HasOutgoingPacketType;

use crate::traits::types::ibc_events::send_packet::HasSendPacketEvent;

#[cgp_component {
provider: PacketFromSendPacketEventBuilder,
context: Chain,
}]
#[async_trait]
pub trait CanBuildPacketFromSendPacket<Counterparty>:
Sized + HasSendPacketEvent<Counterparty> + HasOutgoingPacketType<Counterparty> + HasAsyncErrorType
{
async fn build_packet_from_send_packet_event(
&self,
event: &Self::SendPacketEvent,
) -> Result<Self::OutgoingPacket, Self::Error>;
}
17 changes: 13 additions & 4 deletions crates/chain/chain-components/src/traits/packet/from_write_ack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@ use cgp::prelude::*;
use hermes_chain_type_components::traits::types::ibc::packet::HasOutgoingPacketType;

use crate::traits::types::ibc_events::write_ack::HasWriteAckEvent;
use crate::traits::types::packets::ack::HasAcknowledgementType;

#[cgp_component {
provider: PacketFromWriteAckBuilder,
provider: PacketFromWriteAckEventBuilder,
context: Chain,
}]
pub trait CanBuildPacketFromWriteAck<Counterparty>: HasWriteAckEvent<Counterparty>
#[async_trait]
pub trait CanBuildPacketFromWriteAck<Counterparty>:
Sized + HasWriteAckEvent<Counterparty> + HasAcknowledgementType<Counterparty> + HasAsyncErrorType
where
Counterparty: HasOutgoingPacketType<Self>,
{
Expand All @@ -25,7 +28,13 @@ where
refactored into a method like
`query_packet_from_write_ack_event`.
*/
fn build_packet_from_write_ack_event(
async fn build_packet_from_write_ack_event(
&self,
ack: &Self::WriteAckEvent,
) -> &Counterparty::OutgoingPacket;
) -> Result<Counterparty::OutgoingPacket, Self::Error>;

async fn build_ack_from_write_ack_event(
&self,
ack: &Self::WriteAckEvent,
) -> Result<Self::Acknowledgement, Self::Error>;
}
1 change: 1 addition & 0 deletions crates/chain/chain-components/src/traits/packet/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pub mod fields;
pub mod filter;
pub mod from_send_packet;
pub mod from_write_ack;
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::traits::types::ibc_events::write_ack::HasWriteAckEvent;
}]
#[async_trait]
pub trait CanQueryWriteAck<Counterparty>:
HasWriteAckEvent<Counterparty> + HasAsyncErrorType
Sized + HasWriteAckEvent<Counterparty> + HasAsyncErrorType
where
Counterparty: HasOutgoingPacketType<Self>,
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ use cgp::core::component::{UseDelegate, WithProvider};
use cgp::core::types::ProvideType;
use cgp::prelude::*;
use hermes_chain_type_components::traits::types::ibc::client_id::HasClientIdType;
use hermes_chain_type_components::traits::types::message_response::HasMessageResponseType;

#[cgp_component {
name: CreateClientPayloadOptionsTypeComponent,
Expand Down Expand Up @@ -45,15 +44,9 @@ pub type CreateClientPayloadOf<Chain, Counterparty> =
provider: ProvideCreateClientEvent,
context: Chain,
}]
pub trait HasCreateClientEvent<Counterparty>:
HasMessageResponseType + HasClientIdType<Counterparty>
{
pub trait HasCreateClientEvent<Counterparty>: HasClientIdType<Counterparty> {
type CreateClientEvent: Async;

fn try_extract_create_client_event(
response: &Self::MessageResponse,
) -> Option<Self::CreateClientEvent>;

fn create_client_event_client_id(event: &Self::CreateClientEvent) -> &Self::ClientId;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,14 @@
use cgp::prelude::*;
use hermes_chain_type_components::traits::types::ibc::channel_id::HasChannelIdType;
use hermes_chain_type_components::traits::types::message_response::HasMessageResponseType;

#[cgp_component {
name: ChannelOpenInitEventComponent,
provider: ProvideChannelOpenInitEvent,
context: Chain,
}]
pub trait HasChannelOpenInitEvent<Counterparty>:
HasMessageResponseType + HasChannelIdType<Counterparty>
{
pub trait HasChannelOpenInitEvent<Counterparty>: HasChannelIdType<Counterparty> {
type ChannelOpenInitEvent: Async;

fn try_extract_channel_open_init_event(
event: &Self::MessageResponse,
) -> Option<Self::ChannelOpenInitEvent>;

fn channel_open_init_event_channel_id(event: &Self::ChannelOpenInitEvent) -> &Self::ChannelId;
}

Expand All @@ -24,14 +17,8 @@ pub trait HasChannelOpenInitEvent<Counterparty>:
provider: ProvideChannelOpenTryEvent,
context: Chain,
}]
pub trait HasChannelOpenTryEvent<Counterparty>:
HasMessageResponseType + HasChannelIdType<Counterparty>
{
pub trait HasChannelOpenTryEvent<Counterparty>: HasChannelIdType<Counterparty> {
type ChannelOpenTryEvent: Async;

fn try_extract_channel_open_try_event(
event: &Self::MessageResponse,
) -> Option<Self::ChannelOpenTryEvent>;

fn channel_open_try_event_channel_id(event: &Self::ChannelOpenTryEvent) -> &Self::ChannelId;
}
Original file line number Diff line number Diff line change
@@ -1,22 +1,14 @@
use cgp::prelude::*;
use hermes_chain_type_components::traits::types::ibc::connection_id::HasConnectionIdType;
use hermes_chain_type_components::traits::types::message_response::HasMessageResponseType;

#[cgp_component {
name: ConnectionOpenTryEventComponent,
provider: ProvideConnectionOpenTryEvent,
context: Chain,
}]
pub trait HasConnectionOpenTryEvent<Counterparty>:
HasMessageResponseType + HasConnectionIdType<Counterparty>
{
pub trait HasConnectionOpenTryEvent<Counterparty>: HasConnectionIdType<Counterparty> {
type ConnectionOpenTryEvent: Async;

fn try_extract_connection_open_try_event(
&self,
response: &Self::MessageResponse,
) -> Option<Self::ConnectionOpenTryEvent>;

fn connection_open_try_event_connection_id(
event: &Self::ConnectionOpenTryEvent,
) -> &Self::ConnectionId;
Expand All @@ -27,15 +19,9 @@ pub trait HasConnectionOpenTryEvent<Counterparty>:
provider: ProvideConnectionOpenInitEvent,
context: Chain,
}]
pub trait HasConnectionOpenInitEvent<Counterparty>:
HasMessageResponseType + HasConnectionIdType<Counterparty>
{
pub trait HasConnectionOpenInitEvent<Counterparty>: HasConnectionIdType<Counterparty> {
type ConnectionOpenInitEvent: Async;

fn try_extract_connection_open_init_event(
response: &Self::MessageResponse,
) -> Option<Self::ConnectionOpenInitEvent>;

fn connection_open_init_event_connection_id(
event: &Self::ConnectionOpenInitEvent,
) -> &Self::ConnectionId;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,6 @@
*/

use cgp::prelude::*;
use hermes_chain_type_components::traits::types::ibc::packet::HasOutgoingPacketType;

use crate::traits::types::event::HasEventType;

/**
Indicates that a chain context's
Expand All @@ -17,13 +14,6 @@ use crate::traits::types::event::HasEventType;
provider: ProvideSendPacketEvent,
context: Chain,
}]
pub trait HasSendPacketEvent<Counterparty>:
HasOutgoingPacketType<Counterparty> + HasEventType
{
pub trait HasSendPacketEvent<Counterparty> {
type SendPacketEvent: Async;

fn try_extract_send_packet_event(event: &Self::Event) -> Option<Self::SendPacketEvent>;

fn extract_packet_from_send_packet_event(event: &Self::SendPacketEvent)
-> Self::OutgoingPacket;
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@

use cgp::prelude::*;

use crate::traits::types::event::HasEventType;
use crate::traits::types::packets::ack::HasAcknowledgementType;

/**
Indicates that a chain context's
[`Event`](crate::traits::types::event::HasEventType::Event)
Expand All @@ -17,9 +14,7 @@ use crate::traits::types::packets::ack::HasAcknowledgementType;
provider: ProvideWriteAckEvent,
context: Chain,
}]
pub trait HasWriteAckEvent<Counterparty>:
HasEventType + HasAcknowledgementType<Counterparty>
{
pub trait HasWriteAckEvent<Counterparty> {
/**
The write acknowledgement event that is emitted when a `RecvPacket`
message is committed to a chain.
Expand All @@ -34,22 +29,4 @@ pub trait HasWriteAckEvent<Counterparty>:
we can add new methods to this trait to do the extraction.
*/
type WriteAckEvent: Async;

/**
Try to extract an abstract
[`Event`](crate::traits::types::event::HasEventType::Event)
type into a
[`WriteAckEvent`](Self::WriteAckEvent).
If the extraction fails, return `None`.
Since an event type may contain many variants, it is not guaranteed
that the event extraction would be successful. If the concrete
`Event` is dynamic-typed, then the extraction may also fail due to
parse errors.
*/
fn try_extract_write_ack_event(event: &Self::Event) -> Option<Self::WriteAckEvent>;

fn write_acknowledgement(
event: &Self::WriteAckEvent,
) -> impl AsRef<Self::Acknowledgement> + Send;
}
Loading

0 comments on commit 8e62668

Please sign in to comment.