Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Add checks to skip relaying cleared packet for all stages of relaying #539

Merged
merged 14 commits into from
Feb 17, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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" }
Expand Down
1 change: 1 addition & 0 deletions crates/chain/chain-components/src/traits/queries/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Original file line number Diff line number Diff line change
@@ -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<Counterparty>:
HasChannelIdType<Counterparty>
+ HasPortIdType<Counterparty>
+ HasSequenceType<Counterparty>
+ HasAsyncErrorType
{
async fn query_packet_is_cleared(
&self,
port_id: &Self::PortId,
channel_id: &Self::ChannelId,
sequence: &Self::Sequence,
) -> Result<bool, Self::Error>;
}
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use crate::traits::types::ibc_events::write_ack::HasWriteAckEvent;
context: Chain,
}]
#[async_trait]
pub trait CanQueryWriteAck<Counterparty>:
pub trait CanQueryWriteAckEvent<Counterparty>:
Sized + HasWriteAckEvent<Counterparty> + HasAsyncErrorType
where
Counterparty: HasOutgoingPacketType<Self>,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use core::fmt::Debug;
use core::fmt::{Debug, Display};

use cgp::core::component::WithProvider;
use cgp::core::types::ProvideType;
Expand All @@ -14,7 +14,7 @@ pub trait HasChannelIdType<Counterparty>: 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)]
Expand All @@ -23,7 +23,7 @@ impl<Chain, Counterparty, Provider, ChannelId> ProvideChannelIdType<Chain, Count
where
Chain: Async,
Provider: ProvideType<Chain, ChannelIdTypeComponent, Type = ChannelId>,
ChannelId: Debug + Async,
ChannelId: Debug + Display + Async,
{
type ChannelId = ChannelId;
}
12 changes: 8 additions & 4 deletions crates/cosmos/cosmos-chain-components/src/components/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::{
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -281,8 +283,10 @@ cgp_preset! {
]:
BuildCosmosPacketMessages,

ReceivedPacketQuerierComponent:
QueryCosmosReceivedPacket,
PacketIsReceivedQuerierComponent:
QueryCosmosPacketIsReceived,
PacketIsClearedQuerierComponent:
QueryCosmosPacketIsCleared,

PacketCommitmentQuerierComponent:
QueryPacketCommitmentFromAbci,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Original file line number Diff line number Diff line change
@@ -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<Chain, Counterparty> PacketIsClearedQuerier<Chain, Counterparty> for QueryCosmosPacketIsCleared
where
Chain: HasChannelIdType<Counterparty>
+ HasPortIdType<Counterparty>
+ HasSequenceType<Counterparty>
+ 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<bool, Chain::Error> {
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())
}
}
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -13,10 +13,11 @@ use tonic::{Request, Status};

use crate::traits::grpc_address::HasGrpcAddress;

pub struct QueryCosmosReceivedPacket;
pub struct QueryCosmosPacketIsReceived;

#[cgp_provider(ReceivedPacketQuerierComponent)]
impl<Chain, Counterparty> ReceivedPacketQuerier<Chain, Counterparty> for QueryCosmosReceivedPacket
#[cgp_provider(PacketIsReceivedQuerierComponent)]
impl<Chain, Counterparty> PacketIsReceivedQuerier<Chain, Counterparty>
for QueryCosmosPacketIsReceived
where
Chain: HasIbcChainTypes<Counterparty, ChannelId = ChannelId, PortId = PortId>
+ HasGrpcAddress
Expand Down
3 changes: 2 additions & 1 deletion crates/cosmos/cosmos-relayer/src/contexts/chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -378,6 +378,7 @@ pub trait CanUseCosmosChain:
+ CanExtractFromMessageResponse<CosmosCreateClientEvent>
+ CanUseComponent<ChainStatusQuerierComponent>
+ CanUseComponent<BlockEventsQuerierComponent>
+ CanUseComponent<PacketIsClearedQuerierComponent, CosmosChain>
{
}

Expand Down
8 changes: 8 additions & 0 deletions crates/ibc/ibc-mock-chain/src/types/channel_id.rs
Original file line number Diff line number Diff line change
@@ -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)
}
}
59 changes: 46 additions & 13 deletions crates/mock/mock-relayer/src/relayer_mock/base/impls/chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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::{
Expand Down Expand Up @@ -237,6 +241,11 @@ impl ProvideWriteAckEvent<MockChainContext, MockChainContext> for MockChainCompo
type WriteAckEvent = WriteAckEvent;
}

#[cgp_provider(CommitmentProofTypeComponent)]
impl ProvideCommitmentProofType<MockChainContext> for MockChainComponents {
type CommitmentProof = ();
}

#[cgp_provider(PacketFromWriteAckEventBuilderComponent)]
impl PacketFromWriteAckEventBuilder<MockChainContext, MockChainContext> for MockChainComponents {
async fn build_packet_from_write_ack_event(
Expand All @@ -254,6 +263,19 @@ impl PacketFromWriteAckEventBuilder<MockChainContext, MockChainContext> for Mock
}
}

#[cgp_provider(PacketAcknowledgementQuerierComponent)]
impl PacketAcknowledgementQuerier<MockChainContext, MockChainContext> for MockChainComponents {
async fn query_packet_acknowledgement(
_chain: &MockChainContext,
_channel_id: &ChannelId,
_port_id: &PortId,
_sequence: &Sequence,
_height: &MockHeight,
) -> Result<(Vec<u8>, ()), Error> {
todo!()
}
}

#[cgp_provider(EventExtractorComponent)]
impl EventExtractor<MockChainContext, WriteAckEvent> for MockChainComponents {
fn try_extract_from_event(
Expand Down Expand Up @@ -391,8 +413,8 @@ impl ClientStateQuerier<MockChainContext, MockChainContext> for MockChainCompone
}
}

#[cgp_provider(ReceivedPacketQuerierComponent)]
impl ReceivedPacketQuerier<MockChainContext, MockChainContext> for MockChainComponents {
#[cgp_provider(PacketIsReceivedQuerierComponent)]
impl PacketIsReceivedQuerier<MockChainContext, MockChainContext> for MockChainComponents {
async fn query_packet_is_received(
chain: &MockChainContext,
port_id: &PortId,
Expand Down Expand Up @@ -474,6 +496,17 @@ impl ReceivePacketMessageBuilder<MockChainContext, MockChainContext> for MockCha
}
}

impl PacketIsClearedQuerier<MockChainContext, MockChainContext> for MockChainComponents {
async fn query_packet_is_cleared(
_chain: &MockChainContext,
_port_id: &PortId,
_channel_id: &ChannelId,
_sequence: &Sequence,
) -> Result<bool, Error> {
Ok(false) // stub
}
}

#[cgp_provider(AckPacketPayloadTypeComponent)]
impl ProvideAckPacketPayloadType<MockChainContext, MockChainContext> for MockChainComponents {
type AckPacketPayload = MockMessage;
Expand Down
4 changes: 2 additions & 2 deletions crates/mock/mock-relayer/src/relayer_mock/components/relay.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -32,7 +32,7 @@ delegate_components! {
SendIbcMessagesWithUpdateClient<SendIbcMessagesToChain>,
PacketRelayerComponent: FullCycleRelayer,
ReceivePacketRelayerComponent:
SkipReceivedPacketRelayer<BaseReceivePacketRelayer>,
SkipReceivedPacket<BaseReceivePacketRelayer>,
AckPacketRelayerComponent:
BaseAckPacketRelayer,
TimeoutUnorderedPacketRelayerComponent:
Expand Down
2 changes: 1 addition & 1 deletion crates/mock/mock-relayer/src/tests/mock.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -48,13 +48,12 @@ where
+ CanRaiseAsyncError<SrcChain::Error>
+ CanRaiseAsyncError<DstChain::Error>
+ for<'a> CanRaiseAsyncError<MaxRetryExceededError<'a, Relay>>,
SrcChain: CanQueryChainStatus + CanReadPacketFields<DstChain>,
SrcChain:
CanQueryChainStatus + CanQueryPacketIsCleared<DstChain> + CanReadPacketFields<DstChain>,
DstChain: CanQueryChainStatus
+ HasWriteAckEvent<Relay::SrcChain>
+ CanBuildPacketFromWriteAck<Relay::SrcChain>
+ HasChannelIdType<SrcChain>
+ HasPortIdType<SrcChain>
+ HasTimeoutType,
+ CanQueryPacketIsReceived<SrcChain>,
Relay::Logger: for<'a> CanLog<LogRelayPacketAction<'a, Relay>>
+ for<'a> CanLog<LogRelayPacketStatus<'a, Relay>>
+ for<'a> CanLog<LogSkipRelayLockedPacket<'a, Relay>>,
Expand Down
Loading
Loading