diff --git a/Cargo.toml b/Cargo.toml index b01f405f4..59e1b406f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -153,7 +153,7 @@ hermes-cli-components = { version = "0.1.0" } hermes-cli-framework = { version = "0.1.0" } hermes-cosmos-chain-components = { version = "0.1.0" } -hermes-cosmos-encoding-components = { version = "0.1.0" } +hermes-cosmos-encoding-components = { version = "0.1.0" } hermes-cosmos-relayer = { version = "0.1.0" } hermes-cosmos-wasm-relayer = { version = "0.1.0" } hermes-cosmos-test-components = { version = "0.1.0" } diff --git a/crates/chain/chain-components/src/traits/queries/mod.rs b/crates/chain/chain-components/src/traits/queries/mod.rs index ad0069eae..06e6b9e5f 100644 --- a/crates/chain/chain-components/src/traits/queries/mod.rs +++ b/crates/chain/chain-components/src/traits/queries/mod.rs @@ -9,6 +9,7 @@ pub mod consensus_state_height; pub mod counterparty_chain_id; pub mod packet_acknowledgement; pub mod packet_commitment; +pub mod packet_is_cleared; pub mod packet_is_received; pub mod packet_receipt; pub mod write_ack; diff --git a/crates/chain/chain-components/src/traits/queries/packet_is_cleared.rs b/crates/chain/chain-components/src/traits/queries/packet_is_cleared.rs new file mode 100644 index 000000000..f924e3eda --- /dev/null +++ b/crates/chain/chain-components/src/traits/queries/packet_is_cleared.rs @@ -0,0 +1,29 @@ +use cgp::prelude::*; +use hermes_chain_type_components::traits::types::ibc::channel_id::HasChannelIdType; +use hermes_chain_type_components::traits::types::ibc::port_id::HasPortIdType; +use hermes_chain_type_components::traits::types::ibc::sequence::HasSequenceType; + +/** + Checks if a given packet has been cleared on the source chain. Having + the packet cleared means that the source chain has received either + an ack or timeout from the destination chain, thereby completing + the full packet relaying cycle. +*/ +#[cgp_component { + provider: PacketIsClearedQuerier, + context: Chain, +}] +#[async_trait] +pub trait CanQueryPacketIsCleared: + HasChannelIdType + + HasPortIdType + + HasSequenceType + + HasAsyncErrorType +{ + async fn query_packet_is_cleared( + &self, + port_id: &Self::PortId, + channel_id: &Self::ChannelId, + sequence: &Self::Sequence, + ) -> Result; +} diff --git a/crates/chain/chain-components/src/traits/queries/packet_is_received.rs b/crates/chain/chain-components/src/traits/queries/packet_is_received.rs index 2ccbf0855..e54c2aed6 100644 --- a/crates/chain/chain-components/src/traits/queries/packet_is_received.rs +++ b/crates/chain/chain-components/src/traits/queries/packet_is_received.rs @@ -4,7 +4,7 @@ use hermes_chain_type_components::traits::types::ibc::port_id::HasPortIdType; use hermes_chain_type_components::traits::types::ibc::sequence::HasSequenceType; #[cgp_component { - provider: ReceivedPacketQuerier, + provider: PacketIsReceivedQuerier, context: Chain, }] #[async_trait] diff --git a/crates/chain/chain-components/src/traits/queries/write_ack.rs b/crates/chain/chain-components/src/traits/queries/write_ack.rs index 975acd20a..1e336488f 100644 --- a/crates/chain/chain-components/src/traits/queries/write_ack.rs +++ b/crates/chain/chain-components/src/traits/queries/write_ack.rs @@ -8,7 +8,7 @@ use crate::traits::types::ibc_events::write_ack::HasWriteAckEvent; context: Chain, }] #[async_trait] -pub trait CanQueryWriteAck: +pub trait CanQueryWriteAckEvent: Sized + HasWriteAckEvent + HasAsyncErrorType where Counterparty: HasOutgoingPacketType, diff --git a/crates/chain/chain-type-components/src/traits/types/ibc/channel_id.rs b/crates/chain/chain-type-components/src/traits/types/ibc/channel_id.rs index a2f1725d7..e1bd401c2 100644 --- a/crates/chain/chain-type-components/src/traits/types/ibc/channel_id.rs +++ b/crates/chain/chain-type-components/src/traits/types/ibc/channel_id.rs @@ -1,4 +1,4 @@ -use core::fmt::Debug; +use core::fmt::{Debug, Display}; use cgp::core::component::WithProvider; use cgp::core::types::ProvideType; @@ -14,7 +14,7 @@ pub trait HasChannelIdType: Sized + Async { The channel ID of the counterparty chain, that is stored on the self chain. */ - type ChannelId: Debug + Async; + type ChannelId: Display + Debug + Async; } #[cgp_provider(ChannelIdTypeComponent)] @@ -23,7 +23,7 @@ impl ProvideChannelIdType, - ChannelId: Debug + Async, + ChannelId: Debug + Display + Async, { type ChannelId = ChannelId; } diff --git a/crates/cosmos/cosmos-chain-components/src/components/client.rs b/crates/cosmos/cosmos-chain-components/src/components/client.rs index 3ebfa6ade..ef6fc5ebe 100644 --- a/crates/cosmos/cosmos-chain-components/src/components/client.rs +++ b/crates/cosmos/cosmos-chain-components/src/components/client.rs @@ -75,7 +75,8 @@ pub use hermes_relayer_components::chain::traits::queries::consensus_state_heigh pub use hermes_relayer_components::chain::traits::queries::counterparty_chain_id::CounterpartyChainIdQuerierComponent; pub use hermes_relayer_components::chain::traits::queries::packet_acknowledgement::PacketAcknowledgementQuerierComponent; pub use hermes_relayer_components::chain::traits::queries::packet_commitment::PacketCommitmentQuerierComponent; -pub use hermes_relayer_components::chain::traits::queries::packet_is_received::ReceivedPacketQuerierComponent; +pub use hermes_relayer_components::chain::traits::queries::packet_is_cleared::PacketIsClearedQuerierComponent; +pub use hermes_relayer_components::chain::traits::queries::packet_is_received::PacketIsReceivedQuerierComponent; pub use hermes_relayer_components::chain::traits::queries::packet_receipt::PacketReceiptQuerierComponent; pub use hermes_relayer_components::chain::traits::queries::write_ack::WriteAckQuerierComponent; pub use hermes_relayer_components::chain::traits::types::block::{ @@ -158,7 +159,8 @@ use crate::impls::queries::consensus_state::QueryCosmosConsensusStateFromAbci; use crate::impls::queries::packet_acknowledgement::QueryPacketAcknowledgementFromAbci; use crate::impls::queries::packet_commitment::QueryPacketCommitmentFromAbci; use crate::impls::queries::packet_receipt::QueryPacketReceiptFromAbci; -use crate::impls::queries::received_packet::QueryCosmosReceivedPacket; +use crate::impls::queries::received_ack::QueryCosmosPacketIsCleared; +use crate::impls::queries::received_packet::QueryCosmosPacketIsReceived; use crate::impls::queries::write_ack_event::QueryCosmosWriteAckEvent; use crate::impls::relay::packet_filter::FilterPacketWithConfig; use crate::impls::types::chain::ProvideCosmosChainTypes; @@ -281,8 +283,10 @@ cgp_preset! { ]: BuildCosmosPacketMessages, - ReceivedPacketQuerierComponent: - QueryCosmosReceivedPacket, + PacketIsReceivedQuerierComponent: + QueryCosmosPacketIsReceived, + PacketIsClearedQuerierComponent: + QueryCosmosPacketIsCleared, PacketCommitmentQuerierComponent: QueryPacketCommitmentFromAbci, diff --git a/crates/cosmos/cosmos-chain-components/src/impls/queries/mod.rs b/crates/cosmos/cosmos-chain-components/src/impls/queries/mod.rs index 95310e09b..0975343d8 100644 --- a/crates/cosmos/cosmos-chain-components/src/impls/queries/mod.rs +++ b/crates/cosmos/cosmos-chain-components/src/impls/queries/mod.rs @@ -12,5 +12,6 @@ pub mod eip; pub mod packet_acknowledgement; pub mod packet_commitment; pub mod packet_receipt; +pub mod received_ack; pub mod received_packet; pub mod write_ack_event; diff --git a/crates/cosmos/cosmos-chain-components/src/impls/queries/received_ack.rs b/crates/cosmos/cosmos-chain-components/src/impls/queries/received_ack.rs new file mode 100644 index 000000000..b301397b1 --- /dev/null +++ b/crates/cosmos/cosmos-chain-components/src/impls/queries/received_ack.rs @@ -0,0 +1,47 @@ +use core::fmt::Display; + +use cgp::prelude::*; +use hermes_relayer_components::chain::traits::queries::chain_status::CanQueryChainHeight; +use hermes_relayer_components::chain::traits::queries::packet_is_cleared::{ + PacketIsClearedQuerier, PacketIsClearedQuerierComponent, +}; +use hermes_relayer_components::chain::traits::types::ibc::{ + HasChannelIdType, HasPortIdType, HasSequenceType, +}; +use ibc::cosmos_host::IBC_QUERY_PATH; + +use crate::traits::abci_query::CanQueryAbci; + +pub struct QueryCosmosPacketIsCleared; + +#[cgp_provider(PacketIsClearedQuerierComponent)] +impl PacketIsClearedQuerier for QueryCosmosPacketIsCleared +where + Chain: HasChannelIdType + + HasPortIdType + + HasSequenceType + + CanQueryAbci + + CanQueryChainHeight + + HasAsyncErrorType, + Chain::ChannelId: Display, +{ + async fn query_packet_is_cleared( + chain: &Chain, + port_id: &Chain::PortId, + channel_id: &Chain::ChannelId, + sequence: &Chain::Sequence, + ) -> Result { + let height = chain.query_chain_height().await?; + + let commitment_path = + format!("commitments/ports/{port_id}/channels/{channel_id}/sequences/{sequence}"); + + let commitment = chain + .query_abci(IBC_QUERY_PATH, commitment_path.as_bytes(), &height) + .await?; + + // Once a packet has been cleared, the chain would have removed its packet commitment + + Ok(commitment.is_empty()) + } +} diff --git a/crates/cosmos/cosmos-chain-components/src/impls/queries/received_packet.rs b/crates/cosmos/cosmos-chain-components/src/impls/queries/received_packet.rs index cb5cdbb6f..c9efc3281 100644 --- a/crates/cosmos/cosmos-chain-components/src/impls/queries/received_packet.rs +++ b/crates/cosmos/cosmos-chain-components/src/impls/queries/received_packet.rs @@ -1,6 +1,6 @@ use cgp::prelude::*; use hermes_relayer_components::chain::traits::queries::packet_is_received::{ - ReceivedPacketQuerier, ReceivedPacketQuerierComponent, + PacketIsReceivedQuerier, PacketIsReceivedQuerierComponent, }; use hermes_relayer_components::chain::traits::types::ibc::HasIbcChainTypes; use http::uri::InvalidUri; @@ -13,10 +13,11 @@ use tonic::{Request, Status}; use crate::traits::grpc_address::HasGrpcAddress; -pub struct QueryCosmosReceivedPacket; +pub struct QueryCosmosPacketIsReceived; -#[cgp_provider(ReceivedPacketQuerierComponent)] -impl ReceivedPacketQuerier for QueryCosmosReceivedPacket +#[cgp_provider(PacketIsReceivedQuerierComponent)] +impl PacketIsReceivedQuerier + for QueryCosmosPacketIsReceived where Chain: HasIbcChainTypes + HasGrpcAddress diff --git a/crates/cosmos/cosmos-relayer/src/contexts/chain.rs b/crates/cosmos/cosmos-relayer/src/contexts/chain.rs index 3f7cfd6de..cca9cdc6c 100644 --- a/crates/cosmos/cosmos-relayer/src/contexts/chain.rs +++ b/crates/cosmos/cosmos-relayer/src/contexts/chain.rs @@ -12,7 +12,7 @@ use hermes_chain_type_components::traits::fields::message_response_events::HasMe use hermes_chain_type_components::traits::types::event::HasEventType; use hermes_chain_type_components::traits::types::message_response::HasMessageResponseType; use hermes_cosmos_chain_components::components::client::{ - BlockEventsQuerierComponent, ChainStatusQuerierComponent, + BlockEventsQuerierComponent, ChainStatusQuerierComponent, PacketIsClearedQuerierComponent, }; use hermes_cosmos_chain_components::components::cosmos_to_cosmos::CosmosToCosmosComponents; use hermes_cosmos_chain_components::components::delegate::DelegateCosmosChainComponents; @@ -378,6 +378,7 @@ pub trait CanUseCosmosChain: + CanExtractFromMessageResponse + CanUseComponent + CanUseComponent + + CanUseComponent { } diff --git a/crates/ibc/ibc-mock-chain/src/types/channel_id.rs b/crates/ibc/ibc-mock-chain/src/types/channel_id.rs index 46cbf86e5..e4cab706c 100644 --- a/crates/ibc/ibc-mock-chain/src/types/channel_id.rs +++ b/crates/ibc/ibc-mock-chain/src/types/channel_id.rs @@ -1,6 +1,14 @@ +use core::fmt::{Debug, Display}; + #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] pub enum MockChannelId { ChannelIdA, ChannelIdB, ChannelIdC, } + +impl Display for MockChannelId { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + Debug::fmt(self, f) + } +} diff --git a/crates/mock/mock-relayer/src/relayer_mock/base/impls/chain.rs b/crates/mock/mock-relayer/src/relayer_mock/base/impls/chain.rs index 0515fb03f..394643353 100644 --- a/crates/mock/mock-relayer/src/relayer_mock/base/impls/chain.rs +++ b/crates/mock/mock-relayer/src/relayer_mock/base/impls/chain.rs @@ -17,25 +17,27 @@ use cgp::prelude::*; use eyre::eyre; use hermes_chain_type_components::impls::types::message_response::UseEventsMessageResponse; use hermes_chain_type_components::traits::fields::chain_id::ChainIdGetterComponent; +use hermes_chain_type_components::traits::types::commitment_proof::ProvideCommitmentProofType; use hermes_cosmos_chain_components::components::client::{ AckPacketMessageBuilderComponent, AckPacketPayloadBuilderComponent, AckPacketPayloadTypeComponent, ChainIdTypeComponent, ChainStatusQuerierComponent, ChainStatusTypeComponent, ChannelIdTypeComponent, ClientIdTypeComponent, - ClientStateQuerierComponent, ClientStateTypeComponent, ConnectionIdTypeComponent, - ConsensusStateQuerierComponent, ConsensusStateTypeComponent, + ClientStateQuerierComponent, ClientStateTypeComponent, CommitmentProofTypeComponent, + ConnectionIdTypeComponent, ConsensusStateQuerierComponent, ConsensusStateTypeComponent, CounterpartyMessageHeightGetterComponent, EventExtractorComponent, EventTypeComponent, HeightIncrementerComponent, HeightTypeComponent, MessageResponseEventsGetterComponent, MessageResponseTypeComponent, MessageSizeEstimatorComponent, MessageTypeComponent, - OutgoingPacketTypeComponent, PacketDstChannelIdGetterComponent, PacketDstPortIdGetterComponent, + OutgoingPacketTypeComponent, PacketAcknowledgementQuerierComponent, + PacketDstChannelIdGetterComponent, PacketDstPortIdGetterComponent, PacketFromSendPacketEventBuilderComponent, PacketFromWriteAckEventBuilderComponent, - PacketSequenceGetterComponent, PacketSrcChannelIdGetterComponent, - PacketSrcPortIdGetterComponent, PacketTimeoutHeightGetterComponent, - PacketTimeoutTimestampGetterComponent, PortIdTypeComponent, + PacketIsReceivedQuerierComponent, PacketSequenceGetterComponent, + PacketSrcChannelIdGetterComponent, PacketSrcPortIdGetterComponent, + PacketTimeoutHeightGetterComponent, PacketTimeoutTimestampGetterComponent, PortIdTypeComponent, ReceivePacketMessageBuilderComponent, ReceivePacketPayloadBuilderComponent, - ReceivePacketPayloadTypeComponent, ReceivedPacketQuerierComponent, SendPacketEventComponent, - SequenceTypeComponent, TimeTypeComponent, TimeoutTypeComponent, - TimeoutUnorderedPacketMessageBuilderComponent, TimeoutUnorderedPacketPayloadBuilderComponent, - TimeoutUnorderedPacketPayloadTypeComponent, WriteAckEventComponent, WriteAckQuerierComponent, + ReceivePacketPayloadTypeComponent, SendPacketEventComponent, SequenceTypeComponent, + TimeTypeComponent, TimeoutTypeComponent, TimeoutUnorderedPacketMessageBuilderComponent, + TimeoutUnorderedPacketPayloadBuilderComponent, TimeoutUnorderedPacketPayloadTypeComponent, + WriteAckEventComponent, WriteAckQuerierComponent, }; use hermes_cosmos_chain_components::components::transaction::MessageSenderComponent; use hermes_relayer_components::chain::traits::extract_data::EventExtractor; @@ -55,7 +57,9 @@ use hermes_relayer_components::chain::traits::payload_builders::timeout_unordere use hermes_relayer_components::chain::traits::queries::chain_status::ChainStatusQuerier; use hermes_relayer_components::chain::traits::queries::client_state::ClientStateQuerier; use hermes_relayer_components::chain::traits::queries::consensus_state::ConsensusStateQuerier; -use hermes_relayer_components::chain::traits::queries::packet_is_received::ReceivedPacketQuerier; +use hermes_relayer_components::chain::traits::queries::packet_acknowledgement::PacketAcknowledgementQuerier; +use hermes_relayer_components::chain::traits::queries::packet_is_cleared::PacketIsClearedQuerier; +use hermes_relayer_components::chain::traits::queries::packet_is_received::PacketIsReceivedQuerier; use hermes_relayer_components::chain::traits::queries::write_ack::WriteAckQuerier; use hermes_relayer_components::chain::traits::send_message::MessageSender; use hermes_relayer_components::chain::traits::types::chain_id::{ @@ -237,6 +241,11 @@ impl ProvideWriteAckEvent for MockChainCompo type WriteAckEvent = WriteAckEvent; } +#[cgp_provider(CommitmentProofTypeComponent)] +impl ProvideCommitmentProofType for MockChainComponents { + type CommitmentProof = (); +} + #[cgp_provider(PacketFromWriteAckEventBuilderComponent)] impl PacketFromWriteAckEventBuilder for MockChainComponents { async fn build_packet_from_write_ack_event( @@ -254,6 +263,19 @@ impl PacketFromWriteAckEventBuilder for Mock } } +#[cgp_provider(PacketAcknowledgementQuerierComponent)] +impl PacketAcknowledgementQuerier for MockChainComponents { + async fn query_packet_acknowledgement( + _chain: &MockChainContext, + _channel_id: &ChannelId, + _port_id: &PortId, + _sequence: &Sequence, + _height: &MockHeight, + ) -> Result<(Vec, ()), Error> { + todo!() + } +} + #[cgp_provider(EventExtractorComponent)] impl EventExtractor for MockChainComponents { fn try_extract_from_event( @@ -391,8 +413,8 @@ impl ClientStateQuerier for MockChainCompone } } -#[cgp_provider(ReceivedPacketQuerierComponent)] -impl ReceivedPacketQuerier for MockChainComponents { +#[cgp_provider(PacketIsReceivedQuerierComponent)] +impl PacketIsReceivedQuerier for MockChainComponents { async fn query_packet_is_received( chain: &MockChainContext, port_id: &PortId, @@ -474,6 +496,17 @@ impl ReceivePacketMessageBuilder for MockCha } } +impl PacketIsClearedQuerier for MockChainComponents { + async fn query_packet_is_cleared( + _chain: &MockChainContext, + _port_id: &PortId, + _channel_id: &ChannelId, + _sequence: &Sequence, + ) -> Result { + Ok(false) // stub + } +} + #[cgp_provider(AckPacketPayloadTypeComponent)] impl ProvideAckPacketPayloadType for MockChainComponents { type AckPacketPayload = MockMessage; diff --git a/crates/mock/mock-relayer/src/relayer_mock/components/relay.rs b/crates/mock/mock-relayer/src/relayer_mock/components/relay.rs index 900924728..98e3d1681 100644 --- a/crates/mock/mock-relayer/src/relayer_mock/components/relay.rs +++ b/crates/mock/mock-relayer/src/relayer_mock/components/relay.rs @@ -8,7 +8,7 @@ use hermes_relayer_components::relay::impls::update_client::wait::WaitUpdateClie use hermes_relayer_components::relay::impls::packet_relayers::ack::base_ack_packet::BaseAckPacketRelayer; use hermes_relayer_components::relay::impls::packet_relayers::general::full_relay::FullCycleRelayer; use hermes_relayer_components::relay::impls::packet_relayers::receive::base_receive_packet::BaseReceivePacketRelayer; -use hermes_relayer_components::relay::impls::packet_relayers::receive::skip_received_packet::SkipReceivedPacketRelayer; +use hermes_relayer_components::relay::impls::packet_relayers::receive::skip_received_packet::SkipReceivedPacket; use hermes_relayer_components::relay::impls::packet_relayers::timeout_unordered::timeout_unordered_packet::BaseTimeoutUnorderedPacketRelayer; use hermes_relayer_components::relay::traits::ibc_message_sender::{MainSink, IbcMessageSenderComponent}; use hermes_relayer_components::relay::traits::update_client_message_builder::TargetUpdateClientMessageBuilderComponent; @@ -32,7 +32,7 @@ delegate_components! { SendIbcMessagesWithUpdateClient, PacketRelayerComponent: FullCycleRelayer, ReceivePacketRelayerComponent: - SkipReceivedPacketRelayer, + SkipReceivedPacket, AckPacketRelayerComponent: BaseAckPacketRelayer, TimeoutUnorderedPacketRelayerComponent: diff --git a/crates/mock/mock-relayer/src/tests/mock.rs b/crates/mock/mock-relayer/src/tests/mock.rs index 0190e9929..e519f32dc 100644 --- a/crates/mock/mock-relayer/src/tests/mock.rs +++ b/crates/mock/mock-relayer/src/tests/mock.rs @@ -1,7 +1,7 @@ use alloc::string::String; use std::time::Duration; -use hermes_relayer_components::chain::traits::queries::write_ack::CanQueryWriteAck; +use hermes_relayer_components::chain::traits::queries::write_ack::CanQueryWriteAckEvent; use hermes_relayer_components::relay::traits::chains::{HasDstClientId, HasSrcClientId}; use hermes_relayer_components::relay::traits::packet_relayer::CanRelayPacket; use hermes_runtime_components::traits::sleep::CanSleep; diff --git a/crates/relayer/relayer-components-extra/src/relay/impls/packet_relayers/extra.rs b/crates/relayer/relayer-components-extra/src/relay/impls/packet_relayers/extra.rs index 4875a2163..3e006aaee 100644 --- a/crates/relayer/relayer-components-extra/src/relay/impls/packet_relayers/extra.rs +++ b/crates/relayer/relayer-components-extra/src/relay/impls/packet_relayers/extra.rs @@ -1,11 +1,11 @@ use cgp::prelude::*; -use hermes_chain_type_components::traits::types::timeout::HasTimeoutType; use hermes_logging_components::traits::has_logger::HasLogger; use hermes_logging_components::traits::logger::CanLog; use hermes_relayer_components::chain::traits::packet::fields::CanReadPacketFields; use hermes_relayer_components::chain::traits::packet::from_write_ack::CanBuildPacketFromWriteAck; use hermes_relayer_components::chain::traits::queries::chain_status::CanQueryChainStatus; -use hermes_relayer_components::chain::traits::types::ibc::{HasChannelIdType, HasPortIdType}; +use hermes_relayer_components::chain::traits::queries::packet_is_cleared::CanQueryPacketIsCleared; +use hermes_relayer_components::chain::traits::queries::packet_is_received::CanQueryPacketIsReceived; use hermes_relayer_components::chain::traits::types::ibc_events::write_ack::HasWriteAckEvent; use hermes_relayer_components::components::default::relay::PacketRelayerComponent; use hermes_relayer_components::error::impls::error::MaxRetryExceededError; @@ -48,13 +48,12 @@ where + CanRaiseAsyncError + CanRaiseAsyncError + for<'a> CanRaiseAsyncError>, - SrcChain: CanQueryChainStatus + CanReadPacketFields, + SrcChain: + CanQueryChainStatus + CanQueryPacketIsCleared + CanReadPacketFields, DstChain: CanQueryChainStatus + HasWriteAckEvent + CanBuildPacketFromWriteAck - + HasChannelIdType - + HasPortIdType - + HasTimeoutType, + + CanQueryPacketIsReceived, Relay::Logger: for<'a> CanLog> + for<'a> CanLog> + for<'a> CanLog>, diff --git a/crates/relayer/relayer-components/src/components/default/relay.rs b/crates/relayer/relayer-components/src/components/default/relay.rs index d99c1394c..c21779c37 100644 --- a/crates/relayer/relayer-components/src/components/default/relay.rs +++ b/crates/relayer/relayer-components/src/components/default/relay.rs @@ -25,7 +25,8 @@ use crate::relay::impls::packet_lock::ProvidePacketLockWithMutex; use crate::relay::impls::packet_relayers::ack::base_ack_packet::BaseAckPacketRelayer; use crate::relay::impls::packet_relayers::general::default::DefaultPacketRelayer; use crate::relay::impls::packet_relayers::receive::base_receive_packet::BaseReceivePacketRelayer; -use crate::relay::impls::packet_relayers::receive::skip_received_packet::SkipReceivedPacketRelayer; +use crate::relay::impls::packet_relayers::receive::skip_received_packet::SkipReceivedPacket; +use crate::relay::impls::packet_relayers::skip_cleared::SkipClearedPacket; use crate::relay::impls::packet_relayers::timeout_unordered::timeout_unordered_packet::BaseTimeoutUnorderedPacketRelayer; use crate::relay::impls::update_client::default::DefaultTargetUpdateClientMessageBuilder; pub use crate::relay::traits::auto_relayer::{ @@ -57,9 +58,9 @@ cgp_preset! { IbcMessageSenderComponent: SendIbcMessagesWithUpdateClient, TargetUpdateClientMessageBuilderComponent: DefaultTargetUpdateClientMessageBuilder, PacketRelayerComponent: DefaultPacketRelayer, - ReceivePacketRelayerComponent: SkipReceivedPacketRelayer, - AckPacketRelayerComponent: BaseAckPacketRelayer, - TimeoutUnorderedPacketRelayerComponent: BaseTimeoutUnorderedPacketRelayer, + ReceivePacketRelayerComponent: SkipClearedPacket>, + AckPacketRelayerComponent: SkipClearedPacket, + TimeoutUnorderedPacketRelayerComponent: SkipClearedPacket, EventRelayerComponent: PacketEventRelayer, RunnerComponent: RelayBothTargets, AutoRelayerComponent: AutoRelayStartingCurrentHeight, diff --git a/crates/relayer/relayer-components/src/relay/impls/packet_relayers/general/default.rs b/crates/relayer/relayer-components/src/relay/impls/packet_relayers/general/default.rs index b88d91d35..f71001477 100644 --- a/crates/relayer/relayer-components/src/relay/impls/packet_relayers/general/default.rs +++ b/crates/relayer/relayer-components/src/relay/impls/packet_relayers/general/default.rs @@ -1,8 +1,8 @@ use cgp::prelude::*; use hermes_chain_components::traits::packet::fields::CanReadPacketFields; use hermes_chain_components::traits::packet::from_write_ack::CanBuildPacketFromWriteAck; -use hermes_chain_components::traits::types::ibc::{HasChannelIdType, HasPortIdType}; -use hermes_chain_components::traits::types::timestamp::HasTimeoutType; +use hermes_chain_components::traits::queries::packet_is_cleared::CanQueryPacketIsCleared; +use hermes_chain_components::traits::queries::packet_is_received::CanQueryPacketIsReceived; use hermes_logging_components::traits::has_logger::HasLogger; use hermes_logging_components::traits::logger::CanLog; @@ -17,6 +17,7 @@ use crate::relay::impls::packet_relayers::general::lock::{ LockPacketRelayer, LogSkipRelayLockedPacket, }; use crate::relay::impls::packet_relayers::general::log::{LogRelayPacketStatus, LoggerRelayer}; +use crate::relay::impls::packet_relayers::skip_cleared::SkipClearedPacket; use crate::relay::traits::chains::{HasRelayChains, HasRelayPacketType}; use crate::relay::traits::packet_filter::CanFilterRelayPackets; use crate::relay::traits::packet_lock::HasPacketLock; @@ -40,19 +41,18 @@ where + HasRelayChains + CanRaiseAsyncError + CanRaiseAsyncError, - SrcChain: CanQueryChainStatus + CanReadPacketFields, + SrcChain: + CanQueryChainStatus + CanQueryPacketIsCleared + CanReadPacketFields, DstChain: CanQueryChainStatus - + HasWriteAckEvent - + CanBuildPacketFromWriteAck - + HasChannelIdType - + HasPortIdType - + HasTimeoutType, + + HasWriteAckEvent + + CanBuildPacketFromWriteAck + + CanQueryPacketIsReceived, Relay::Logger: for<'a> CanLog> + for<'a> CanLog> + for<'a> CanLog>, { async fn relay_packet(relay: &Relay, packet: &Relay::Packet) -> Result<(), Relay::Error> { - >>>::relay_packet( + >>>>::relay_packet( relay, packet, ) .await diff --git a/crates/relayer/relayer-components/src/relay/impls/packet_relayers/general/full_relay.rs b/crates/relayer/relayer-components/src/relay/impls/packet_relayers/general/full_relay.rs index d44811ea6..eefa41d1c 100644 --- a/crates/relayer/relayer-components/src/relay/impls/packet_relayers/general/full_relay.rs +++ b/crates/relayer/relayer-components/src/relay/impls/packet_relayers/general/full_relay.rs @@ -1,10 +1,7 @@ use cgp::prelude::*; -use hermes_chain_components::traits::packet::fields::{ - HasPacketTimeoutHeight, HasPacketTimeoutTimestamp, -}; +use hermes_chain_components::traits::packet::fields::CanReadPacketFields; use hermes_chain_components::traits::packet::from_write_ack::CanBuildPacketFromWriteAck; -use hermes_chain_components::traits::types::ibc::{HasChannelIdType, HasPortIdType}; -use hermes_chain_components::traits::types::timestamp::HasTimeoutType; +use hermes_chain_components::traits::queries::packet_is_received::CanQueryPacketIsReceived; use hermes_logging_components::traits::has_logger::HasLogger; use hermes_logging_components::traits::logger::CanLog; @@ -47,15 +44,11 @@ where + HasRelayChains + CanRaiseAsyncError + CanRaiseAsyncError, - SrcChain: CanQueryChainStatus - + HasPacketTimeoutHeight - + HasPacketTimeoutTimestamp, + SrcChain: CanQueryChainStatus + CanReadPacketFields, DstChain: CanQueryChainStatus - + HasWriteAckEvent - + CanBuildPacketFromWriteAck - + HasChannelIdType - + HasPortIdType - + HasTimeoutType, + + HasWriteAckEvent + + CanBuildPacketFromWriteAck + + CanQueryPacketIsReceived, Relay::Logger: for<'a> CanLog>, { async fn relay_packet(relay: &Relay, packet: &Relay::Packet) -> Result<(), Relay::Error> { @@ -63,6 +56,15 @@ where let dst_chain = relay.dst_chain(); let logger = relay.logger(); + let is_packet_received = dst_chain + .query_packet_is_received( + &SrcChain::packet_dst_port_id(packet), + &SrcChain::packet_dst_channel_id(packet), + &SrcChain::packet_sequence(packet), + ) + .await + .map_err(Relay::raise_error)?; + let destination_status = dst_chain .query_chain_status() .await @@ -87,7 +89,7 @@ where } }; - if has_packet_timed_out { + if !is_packet_received && has_packet_timed_out { logger .log( "relaying timeout unordered packet", @@ -119,7 +121,7 @@ where ) .await; - let write_ack = relay + let m_ack = relay .relay_receive_packet( Relay::SrcChain::chain_status_height(&src_chain_status), packet, @@ -133,7 +135,7 @@ where let destination_height = DstChain::chain_status_height(&destination_status); - if let Some(ack_event) = write_ack { + if let Some(ack) = m_ack { logger .log( "relaying ack packet", @@ -145,11 +147,6 @@ where ) .await; - let ack = dst_chain - .build_ack_from_write_ack_event(&ack_event) - .await - .map_err(Relay::raise_error)?; - relay .relay_ack_packet(destination_height, packet, &ack) .await?; diff --git a/crates/relayer/relayer-components/src/relay/impls/packet_relayers/mod.rs b/crates/relayer/relayer-components/src/relay/impls/packet_relayers/mod.rs index 5b4d0cc0b..8e296020a 100644 --- a/crates/relayer/relayer-components/src/relay/impls/packet_relayers/mod.rs +++ b/crates/relayer/relayer-components/src/relay/impls/packet_relayers/mod.rs @@ -1,4 +1,5 @@ pub mod ack; pub mod general; pub mod receive; +pub mod skip_cleared; pub mod timeout_unordered; diff --git a/crates/relayer/relayer-components/src/relay/impls/packet_relayers/receive/base_receive_packet.rs b/crates/relayer/relayer-components/src/relay/impls/packet_relayers/receive/base_receive_packet.rs index bfe0fb52b..52df6fe8d 100644 --- a/crates/relayer/relayer-components/src/relay/impls/packet_relayers/receive/base_receive_packet.rs +++ b/crates/relayer/relayer-components/src/relay/impls/packet_relayers/receive/base_receive_packet.rs @@ -2,6 +2,8 @@ use core::marker::PhantomData; use cgp::prelude::*; use hermes_chain_components::traits::extract_data::CanExtractFromEvent; +use hermes_chain_components::traits::packet::from_write_ack::CanBuildPacketFromWriteAck; +use hermes_chain_components::traits::types::packets::ack::HasAcknowledgementType; use hermes_chain_type_components::traits::fields::message_response_events::HasMessageResponseEvents; use crate::chain::traits::message_builders::receive_packet::CanBuildReceivePacketMessage; @@ -20,25 +22,27 @@ use crate::relay::traits::target::{DestinationTarget, HasDestinationTargetChainT pub struct BaseReceivePacketRelayer; #[cgp_provider(ReceivePacketRelayerComponent)] -impl ReceivePacketRelayer for BaseReceivePacketRelayer +impl ReceivePacketRelayer for BaseReceivePacketRelayer where - Relay: HasRelayChains + Relay: HasRelayChains + HasDestinationTargetChainTypes + HasDstClientId + CanSendSingleIbcMessage + CanRaiseRelayChainErrors, - Relay::SrcChain: CanBuildReceivePacketPayload, - Relay::DstChain: CanQueryClientStateWithLatestHeight - + CanBuildReceivePacketMessage + SrcChain: CanBuildReceivePacketPayload, + DstChain: CanQueryClientStateWithLatestHeight + + CanBuildReceivePacketMessage + HasMessageResponseEvents - + HasWriteAckEvent - + CanExtractFromEvent, + + HasWriteAckEvent + + CanExtractFromEvent + + HasAcknowledgementType + + CanBuildPacketFromWriteAck, { async fn relay_receive_packet( relay: &Relay, source_height: &HeightOf, packet: &PacketOf, - ) -> Result, Relay::Error> { + ) -> Result, Relay::Error> { let dst_chain = relay.dst_chain(); let src_client_state = dst_chain @@ -59,10 +63,20 @@ where let response = relay.send_message(DestinationTarget, message).await?; - let ack_event = Relay::DstChain::message_response_events(&response) + let m_ack_event = Relay::DstChain::message_response_events(&response) .iter() .find_map(|event| dst_chain.try_extract_from_event(PhantomData, event)); - Ok(ack_event) + match m_ack_event { + Some(ack_event) => { + let ack = dst_chain + .build_ack_from_write_ack_event(&ack_event) + .await + .map_err(Relay::raise_error)?; + + Ok(Some(ack)) + } + None => Ok(None), + } } } diff --git a/crates/relayer/relayer-components/src/relay/impls/packet_relayers/receive/skip_received_packet.rs b/crates/relayer/relayer-components/src/relay/impls/packet_relayers/receive/skip_received_packet.rs index df7c5a963..52fb7ceae 100644 --- a/crates/relayer/relayer-components/src/relay/impls/packet_relayers/receive/skip_received_packet.rs +++ b/crates/relayer/relayer-components/src/relay/impls/packet_relayers/receive/skip_received_packet.rs @@ -4,36 +4,42 @@ use cgp::prelude::*; use hermes_chain_components::traits::packet::fields::{ HasPacketDstChannelId, HasPacketDstPortId, HasPacketSequence, }; +use hermes_chain_components::traits::queries::chain_status::CanQueryChainHeight; +use hermes_chain_components::traits::queries::packet_acknowledgement::CanQueryPacketAcknowledgement; use crate::chain::traits::queries::packet_is_received::CanQueryPacketIsReceived; use crate::chain::traits::types::ibc_events::write_ack::HasWriteAckEvent; -use crate::chain::types::aliases::{HeightOf, WriteAckEventOf}; +use crate::chain::types::aliases::HeightOf; use crate::components::default::relay::ReceivePacketRelayerComponent; use crate::relay::traits::chains::{CanRaiseRelayChainErrors, HasRelayChains, PacketOf}; use crate::relay::traits::packet_relayers::receive_packet::ReceivePacketRelayer; -pub struct SkipReceivedPacketRelayer { +pub struct SkipReceivedPacket { pub phantom: PhantomData, } #[cgp_provider(ReceivePacketRelayerComponent)] -impl ReceivePacketRelayer for SkipReceivedPacketRelayer +impl ReceivePacketRelayer for SkipReceivedPacket where - Relay: HasRelayChains + CanRaiseRelayChainErrors, + Relay: HasRelayChains + CanRaiseRelayChainErrors, Relayer: ReceivePacketRelayer, - Relay::SrcChain: HasPacketDstChannelId - + HasPacketDstPortId - + HasPacketSequence, - Relay::DstChain: HasWriteAckEvent, - Relay::DstChain: CanQueryPacketIsReceived, + SrcChain: HasPacketDstChannelId + + HasPacketDstPortId + + HasPacketSequence + + HasErrorType, + DstChain: CanQueryChainHeight + + HasWriteAckEvent + + CanQueryPacketIsReceived + + CanQueryPacketAcknowledgement, { async fn relay_receive_packet( relay: &Relay, source_height: &HeightOf, packet: &PacketOf, - ) -> Result>, Relay::Error> { - let is_packet_received = relay - .dst_chain() + ) -> Result, Relay::Error> { + let dst_chain = relay.dst_chain(); + + let is_packet_received = dst_chain .query_packet_is_received( &Relay::SrcChain::packet_dst_port_id(packet), &Relay::SrcChain::packet_dst_channel_id(packet), @@ -45,7 +51,22 @@ where if !is_packet_received { Relayer::relay_receive_packet(relay, source_height, packet).await } else { - Ok(None) + let query_height = dst_chain + .query_chain_height() + .await + .map_err(Relay::raise_error)?; + + let (ack, _) = dst_chain + .query_packet_acknowledgement( + &SrcChain::packet_dst_channel_id(packet), + &SrcChain::packet_dst_port_id(packet), + &SrcChain::packet_sequence(packet), + &query_height, + ) + .await + .map_err(Relay::raise_error)?; + + Ok(Some(ack)) } } } diff --git a/crates/relayer/relayer-components/src/relay/impls/packet_relayers/skip_cleared.rs b/crates/relayer/relayer-components/src/relay/impls/packet_relayers/skip_cleared.rs new file mode 100644 index 000000000..57c121e58 --- /dev/null +++ b/crates/relayer/relayer-components/src/relay/impls/packet_relayers/skip_cleared.rs @@ -0,0 +1,166 @@ +use core::marker::PhantomData; + +use cgp::prelude::*; +use hermes_chain_components::traits::packet::fields::{ + HasPacketSequence, HasPacketSrcChannelId, HasPacketSrcPortId, +}; +use hermes_chain_components::traits::queries::packet_is_cleared::CanQueryPacketIsCleared; +use hermes_chain_components::traits::types::height::HasHeightType; +use hermes_chain_components::traits::types::packet::HasOutgoingPacketType; +use hermes_chain_components::traits::types::packets::ack::HasAcknowledgementType; + +use crate::components::default::relay::{ + AckPacketRelayerComponent, PacketRelayerComponent, ReceivePacketRelayerComponent, + TimeoutUnorderedPacketRelayerComponent, +}; +use crate::relay::traits::chains::HasRelayChains; +use crate::relay::traits::packet_relayer::PacketRelayer; +use crate::relay::traits::packet_relayers::ack_packet::AckPacketRelayer; +use crate::relay::traits::packet_relayers::receive_packet::ReceivePacketRelayer; +use crate::relay::traits::packet_relayers::timeout_unordered_packet::TimeoutUnorderedPacketRelayer; + +pub struct SkipClearedPacket(pub PhantomData); + +#[cgp_provider(ReceivePacketRelayerComponent)] +impl ReceivePacketRelayer + for SkipClearedPacket +where + Relay: + HasRelayChains + CanRaiseError, + SrcChain: HasHeightType + + CanQueryPacketIsCleared + + HasPacketSrcChannelId + + HasPacketSrcPortId + + HasPacketSequence, + DstChain: HasAcknowledgementType, + InRelayer: ReceivePacketRelayer, +{ + async fn relay_receive_packet( + relay: &Relay, + source_height: &SrcChain::Height, + packet: &SrcChain::OutgoingPacket, + ) -> Result, Relay::Error> { + let packet_is_cleared = relay + .src_chain() + .query_packet_is_cleared( + &SrcChain::packet_src_port_id(packet), + &SrcChain::packet_src_channel_id(packet), + &SrcChain::packet_sequence(packet), + ) + .await + .map_err(Relay::raise_error)?; + + if !packet_is_cleared { + InRelayer::relay_receive_packet(relay, source_height, packet).await + } else { + Ok(None) + } + } +} + +#[cgp_provider(AckPacketRelayerComponent)] +impl AckPacketRelayer for SkipClearedPacket +where + Relay: + HasRelayChains + CanRaiseError, + DstChain: HasHeightType + HasAcknowledgementType, + SrcChain: CanQueryPacketIsCleared + + HasPacketSrcChannelId + + HasPacketSrcPortId + + HasPacketSequence, + InRelayer: AckPacketRelayer, +{ + async fn relay_ack_packet( + relay: &Relay, + destination_height: &DstChain::Height, + packet: &SrcChain::OutgoingPacket, + ack: &DstChain::Acknowledgement, + ) -> Result<(), Relay::Error> { + let packet_is_cleared = relay + .src_chain() + .query_packet_is_cleared( + &SrcChain::packet_src_port_id(packet), + &SrcChain::packet_src_channel_id(packet), + &SrcChain::packet_sequence(packet), + ) + .await + .map_err(Relay::raise_error)?; + + if !packet_is_cleared { + InRelayer::relay_ack_packet(relay, destination_height, packet, ack).await?; + } + + Ok(()) + } +} + +#[cgp_provider(TimeoutUnorderedPacketRelayerComponent)] +impl TimeoutUnorderedPacketRelayer + for SkipClearedPacket +where + Relay: + HasRelayChains + CanRaiseError, + SrcChain: HasOutgoingPacketType + + CanQueryPacketIsCleared + + HasPacketSrcChannelId + + HasPacketSrcPortId + + HasPacketSequence, + DstChain: HasHeightType, + InRelayer: TimeoutUnorderedPacketRelayer, +{ + async fn relay_timeout_unordered_packet( + relay: &Relay, + destination_height: &DstChain::Height, + packet: &SrcChain::OutgoingPacket, + ) -> Result<(), Relay::Error> { + let packet_is_cleared = relay + .src_chain() + .query_packet_is_cleared( + &SrcChain::packet_src_port_id(packet), + &SrcChain::packet_src_channel_id(packet), + &SrcChain::packet_sequence(packet), + ) + .await + .map_err(Relay::raise_error)?; + + if !packet_is_cleared { + InRelayer::relay_timeout_unordered_packet(relay, destination_height, packet).await?; + } + + Ok(()) + } +} + +#[cgp_provider(PacketRelayerComponent)] +impl PacketRelayer for SkipClearedPacket +where + Relay: + HasRelayChains + CanRaiseError, + SrcChain: HasOutgoingPacketType + + CanQueryPacketIsCleared + + HasPacketSrcChannelId + + HasPacketSrcPortId + + HasPacketSequence, + InRelayer: PacketRelayer, +{ + async fn relay_packet( + relay: &Relay, + packet: &SrcChain::OutgoingPacket, + ) -> Result<(), Relay::Error> { + let packet_is_cleared = relay + .src_chain() + .query_packet_is_cleared( + &SrcChain::packet_src_port_id(packet), + &SrcChain::packet_src_channel_id(packet), + &SrcChain::packet_sequence(packet), + ) + .await + .map_err(Relay::raise_error)?; + + if !packet_is_cleared { + InRelayer::relay_packet(relay, packet).await?; + } + + Ok(()) + } +} diff --git a/crates/relayer/relayer-components/src/relay/traits/packet_relayers/receive_packet.rs b/crates/relayer/relayer-components/src/relay/traits/packet_relayers/receive_packet.rs index 48fd9dcac..192422e6b 100644 --- a/crates/relayer/relayer-components/src/relay/traits/packet_relayers/receive_packet.rs +++ b/crates/relayer/relayer-components/src/relay/traits/packet_relayers/receive_packet.rs @@ -1,7 +1,9 @@ use cgp::prelude::*; +use hermes_chain_components::traits::types::packets::ack::{ + AcknowledgementOf, HasAcknowledgementType, +}; -use crate::chain::traits::types::ibc_events::write_ack::HasWriteAckEvent; -use crate::chain::types::aliases::{HeightOf, WriteAckEventOf}; +use crate::chain::types::aliases::HeightOf; use crate::relay::traits::chains::{HasRelayChains, PacketOf}; #[cgp_component { @@ -10,11 +12,11 @@ use crate::relay::traits::chains::{HasRelayChains, PacketOf}; }] #[async_trait] pub trait CanRelayReceivePacket: - HasRelayChains> + HasRelayChains> { async fn relay_receive_packet( &self, source_height: &HeightOf, packet: &PacketOf, - ) -> Result>, Self::Error>; + ) -> Result>, Self::Error>; } diff --git a/crates/runtime/runtime-components/src/traits/mod.rs b/crates/runtime/runtime-components/src/traits/mod.rs index 14421d86e..e40259a16 100644 --- a/crates/runtime/runtime-components/src/traits/mod.rs +++ b/crates/runtime/runtime-components/src/traits/mod.rs @@ -8,6 +8,5 @@ pub mod runtime; pub mod sleep; pub mod spawn; pub mod stream; -pub mod subscription; pub mod task; pub mod time; diff --git a/crates/runtime/runtime-components/src/traits/subscription.rs b/crates/runtime/runtime-components/src/traits/subscription.rs deleted file mode 100644 index d55331861..000000000 --- a/crates/runtime/runtime-components/src/traits/subscription.rs +++ /dev/null @@ -1,17 +0,0 @@ -use cgp::prelude::*; - -use crate::traits::stream::HasStreamType; - -#[cgp_component { - name: SubscriptionComponent, - provider: ProvideSubscription, - context: Runtime, -}] -#[async_trait] -pub trait HasSubscription: HasStreamType { - type Subscription: Async; - - async fn subscribe(subcription: &Self::Subscription) -> Option> - where - T: Async; -} diff --git a/crates/runtime/tokio-runtime-components/src/components/concurrent.rs b/crates/runtime/tokio-runtime-components/src/components/concurrent.rs index e45dcfe34..4d240cf0c 100644 --- a/crates/runtime/tokio-runtime-components/src/components/concurrent.rs +++ b/crates/runtime/tokio-runtime-components/src/components/concurrent.rs @@ -24,7 +24,6 @@ pub use hermes_runtime_components::traits::random::RandomGeneratorComponent; pub use hermes_runtime_components::traits::sleep::SleeperComponent; pub use hermes_runtime_components::traits::spawn::TaskSpawnerComponent; pub use hermes_runtime_components::traits::stream::{StreamMapperComponent, StreamTypeComponent}; -pub use hermes_runtime_components::traits::subscription::SubscriptionComponent; pub use hermes_runtime_components::traits::task::ConcurrentTaskRunnerComponent; pub use hermes_runtime_components::traits::time::TimeComponent; @@ -39,7 +38,6 @@ cgp_preset! { MutexComponent, StreamTypeComponent, StreamMapperComponent, - SubscriptionComponent, TaskSpawnerComponent, ChannelTypeComponent, ChannelCreatorComponent, diff --git a/crates/runtime/tokio-runtime-components/src/components/parallel.rs b/crates/runtime/tokio-runtime-components/src/components/parallel.rs index 533b29c1c..8e05f3fd8 100644 --- a/crates/runtime/tokio-runtime-components/src/components/parallel.rs +++ b/crates/runtime/tokio-runtime-components/src/components/parallel.rs @@ -29,7 +29,6 @@ pub use hermes_runtime_components::traits::random::RandomGeneratorComponent; pub use hermes_runtime_components::traits::sleep::SleeperComponent; pub use hermes_runtime_components::traits::spawn::TaskSpawnerComponent; pub use hermes_runtime_components::traits::stream::{StreamMapperComponent, StreamTypeComponent}; -pub use hermes_runtime_components::traits::subscription::SubscriptionComponent; pub use hermes_runtime_components::traits::task::ConcurrentTaskRunnerComponent; pub use hermes_runtime_components::traits::time::TimeComponent; diff --git a/crates/test/test-suite/src/tests/clearing.rs b/crates/test/test-suite/src/tests/clearing.rs index f48bffc29..881b6de83 100644 --- a/crates/test/test-suite/src/tests/clearing.rs +++ b/crates/test/test-suite/src/tests/clearing.rs @@ -7,7 +7,10 @@ use cgp::prelude::*; use hermes_logging_components::traits::has_logger::HasLogger; use hermes_logging_components::traits::logger::CanLogMessage; use hermes_relayer_components::birelay::traits::two_way::HasTwoWayRelay; +use hermes_relayer_components::chain::traits::packet::fields::CanReadPacketFields; use hermes_relayer_components::chain::traits::queries::chain_status::CanQueryChainHeight; +use hermes_relayer_components::chain::traits::queries::packet_is_cleared::CanQueryPacketIsCleared; +use hermes_relayer_components::chain::traits::queries::packet_is_received::CanQueryPacketIsReceived; use hermes_relayer_components::chain::traits::types::chain_id::HasChainId; use hermes_relayer_components::chain::traits::types::ibc::HasIbcChainTypes; use hermes_relayer_components::chain::traits::types::packet::HasOutgoingPacketType; @@ -17,7 +20,6 @@ use hermes_relayer_components::multi::traits::relay_at::RelayAt; use hermes_relayer_components::relay::traits::auto_relayer::CanAutoRelayWithHeights; use hermes_relayer_components::relay::traits::chains::HasRelayChainTypes; use hermes_relayer_components::relay::traits::target::{HasSourceTargetChainTypes, SourceTarget}; -use hermes_test_components::chain::traits::assert::eventual_amount::CanAssertEventualAmount; use hermes_test_components::chain::traits::queries::balance::CanQueryBalance; use hermes_test_components::chain::traits::transfer::amount::CanConvertIbcTransferredAmount; use hermes_test_components::chain::traits::transfer::ibc_transfer::CanIbcTransferToken; @@ -62,7 +64,9 @@ where + HasAmountMethods + CanConvertIbcTransferredAmount + CanIbcTransferToken - + CanAssertEventualAmount + + CanQueryPacketIsReceived + + CanQueryPacketIsCleared + + CanReadPacketFields + HasDefaultMemo, ChainB: HasIbcChainTypes + HasChainId @@ -72,7 +76,9 @@ where + CanQueryBalance + CanIbcTransferToken + CanConvertIbcTransferredAmount - + CanAssertEventualAmount + + CanQueryPacketIsReceived + + CanQueryPacketIsCleared + + CanReadPacketFields + HasDefaultMemo, BiRelay: HasTwoWayRelay, RelayAt, Index<1>>: HasRelayChainTypes @@ -141,7 +147,7 @@ where )) .await; - chain_a + let packet_a = chain_a .ibc_transfer_token( channel_id_a, port_id_a, @@ -152,6 +158,8 @@ where ) .await?; + let sequence_a = ChainA::packet_sequence(&packet_a); + let balance_a2 = ChainA::subtract_amount(&balance_a1, &a_to_b_amount)?; let balance_a3 = chain_a.query_balance(address_a1, denom_a).await?; @@ -160,6 +168,20 @@ where let height_a2 = chain_a.query_chain_height().await?; + { + let is_received = chain_b + .query_packet_is_received(port_id_b, channel_id_b, &sequence_a) + .await?; + + assert!(!is_received); + + let is_cleared = chain_a + .query_packet_is_cleared(port_id_a, channel_id_a, &sequence_a) + .await?; + + assert!(!is_cleared); + } + relay_a_to_b .auto_relay_with_heights(SourceTarget, &height_a1, Some(&height_a2)) .await?; @@ -174,6 +196,20 @@ where assert_eq!(balance_b2, balance_b1); } + { + let is_received = chain_b + .query_packet_is_received(port_id_b, channel_id_b, &sequence_a) + .await?; + + assert!(is_received); + + let is_cleared = chain_a + .query_packet_is_cleared(port_id_a, channel_id_a, &sequence_a) + .await?; + + assert!(is_cleared); + } + let height_b1 = chain_b.query_chain_height().await?; let wallet_a2 = chain_driver_a.wallet_at(UserWallet, PhantomData::>); @@ -189,7 +225,7 @@ where )) .await; - chain_b + let packet_b = chain_b .ibc_transfer_token( channel_id_b, port_id_b, @@ -200,6 +236,8 @@ where ) .await?; + let sequence_b = ChainB::packet_sequence(&packet_b); + let balance_b2 = ChainB::subtract_amount(&balance_b1, &b_to_a_amount)?; let denom_b = ChainB::amount_denom(&balance_b1); @@ -217,6 +255,20 @@ where let height_b2 = chain_b.query_chain_height().await?; + { + let is_received = chain_a + .query_packet_is_received(port_id_a, channel_id_a, &sequence_b) + .await?; + + assert!(!is_received); + + let is_cleared = chain_b + .query_packet_is_cleared(port_id_b, channel_id_b, &sequence_b) + .await?; + + assert!(!is_cleared); + } + relay_b_to_a .auto_relay_with_heights(SourceTarget, &height_b1, Some(&height_b2)) .await?; @@ -229,6 +281,20 @@ where assert_eq!(balance_a6, balance_a5); } + { + let is_received = chain_a + .query_packet_is_received(port_id_a, channel_id_a, &sequence_b) + .await?; + + assert!(is_received); + + let is_cleared = chain_b + .query_packet_is_cleared(port_id_b, channel_id_b, &sequence_b) + .await?; + + assert!(is_cleared); + } + logger .log_message(&format!( "successfully performed reverse IBC transfer from chain {} back to chain {}",