Skip to content

Commit

Permalink
refactor: packet_commitments and packet_acknowledgements return Packe…
Browse files Browse the repository at this point in the history
…tState (#928)

* impl PacketState domain type

* refactor QueryContext method signatures

* update channel query methods

* add changelog entry
  • Loading branch information
rnbguy authored Oct 19, 2023
1 parent fa07561 commit 27592c4
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 28 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- Return PacketStates instead of paths from packet_commitments and
packet_acknowledgements ([\#927](https://github.com/cosmos/ibc-rs/issues/927))
28 changes: 5 additions & 23 deletions crates/ibc-query/src/core/channel/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use ibc::core::ValidationContext;
use ibc::Height;
use ibc_proto::google::protobuf::Any;
use ibc_proto::ibc::core::channel::v1::{
PacketState, QueryChannelClientStateRequest, QueryChannelClientStateResponse,
QueryChannelClientStateRequest, QueryChannelClientStateResponse,
QueryChannelConsensusStateRequest, QueryChannelConsensusStateResponse, QueryChannelRequest,
QueryChannelResponse, QueryChannelsRequest, QueryChannelsResponse,
QueryConnectionChannelsRequest, QueryConnectionChannelsResponse,
Expand Down Expand Up @@ -274,17 +274,8 @@ where
let commitments = ibc_ctx
.packet_commitments(&channel_end_path)?
.into_iter()
.map(|path| {
ibc_ctx
.get_packet_commitment(&path)
.map(|commitment| PacketState {
port_id: path.port_id.as_str().into(),
channel_id: path.channel_id.as_str().into(),
sequence: path.sequence.into(),
data: commitment.into_vec(),
})
})
.collect::<Result<_, _>>()?;
.map(Into::into)
.collect();

Ok(QueryPacketCommitmentsResponse {
commitments,
Expand Down Expand Up @@ -393,17 +384,8 @@ where
let acknowledgements = ibc_ctx
.packet_acknowledgements(&channel_end_path, commitment_sequences)?
.into_iter()
.map(|path| {
ibc_ctx
.get_packet_acknowledgement(&path)
.map(|acknowledgement| PacketState {
port_id: path.port_id.as_str().into(),
channel_id: path.channel_id.as_str().into(),
sequence: path.sequence.into(),
data: acknowledgement.into_vec(),
})
})
.collect::<Result<_, _>>()?;
.map(Into::into)
.collect();

Ok(QueryPacketAcknowledgementsResponse {
acknowledgements,
Expand Down
8 changes: 4 additions & 4 deletions crates/ibc-query/src/core/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
use ibc::core::ics03_connection::connection::IdentifiedConnectionEnd;
use ibc::core::ics04_channel::channel::IdentifiedChannelEnd;
use ibc::core::ics04_channel::packet::Sequence;
use ibc::core::ics04_channel::packet::{PacketState, Sequence};
use ibc::core::ics24_host::identifier::{ClientId, ConnectionId};
use ibc::core::ics24_host::path::{AckPath, ChannelEndPath, CommitmentPath, Path};
use ibc::core::ics24_host::path::{ChannelEndPath, Path};
use ibc::core::{ContextError, ValidationContext};
use ibc::prelude::*;
use ibc::Height;
Expand Down Expand Up @@ -56,15 +56,15 @@ pub trait QueryContext: ProvableContext + ValidationContext {
fn packet_commitments(
&self,
channel_end_path: &ChannelEndPath,
) -> Result<Vec<CommitmentPath>, ContextError>;
) -> Result<Vec<PacketState>, ContextError>;

/// Filters the list of packet sequences for the given channel end that are acknowledged.
/// Returns all the packet acknowledgements if `sequences` is empty.
fn packet_acknowledgements(
&self,
channel_end_path: &ChannelEndPath,
sequences: impl ExactSizeIterator<Item = Sequence>,
) -> Result<Vec<AckPath>, ContextError>;
) -> Result<Vec<PacketState>, ContextError>;

/// Filters the packet sequences for the given channel end that are not received.
fn unreceived_packets(
Expand Down
87 changes: 86 additions & 1 deletion crates/ibc/src/core/ics04_channel/packet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
use core::str::FromStr;

use ibc_proto::ibc::core::channel::v1::Packet as RawPacket;
use ibc_proto::ibc::core::channel::v1::{Packet as RawPacket, PacketState as RawPacketState};

use super::timeout::TimeoutHeight;
use crate::core::ics04_channel::error::{ChannelError, PacketError};
Expand Down Expand Up @@ -287,6 +287,91 @@ impl From<Packet> for RawPacket {
}
}

/// The packet state type.
///
/// Each application defines the structure of the `data` field.
#[cfg_attr(
feature = "parity-scale-codec",
derive(
parity_scale_codec::Encode,
parity_scale_codec::Decode,
scale_info::TypeInfo
)
)]
#[cfg_attr(
feature = "borsh",
derive(borsh::BorshSerialize, borsh::BorshDeserialize)
)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
#[derive(Clone, Default, Hash, PartialEq, Eq)]
pub struct PacketState {
pub port_id: PortId,
pub chan_id: ChannelId,
pub seq: Sequence,
#[cfg_attr(
feature = "serde",
serde(serialize_with = "crate::serializers::ser_hex_upper")
)]
pub data: Vec<u8>,
}
impl core::fmt::Debug for PacketState {
fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> {
let data_wrapper = PacketData(&self.data);

formatter
.debug_struct("PacketState")
.field("port", &self.port_id)
.field("channel", &self.chan_id)
.field("sequence", &self.seq)
.field("data", &data_wrapper)
.finish()
}
}

/// Custom debug output to omit the packet data
impl core::fmt::Display for PacketState {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> {
write!(
f,
"seq:{}, path:{}/{}",
self.seq, self.chan_id, self.port_id,
)
}
}

impl TryFrom<RawPacketState> for PacketState {
type Error = PacketError;

fn try_from(raw_pkt: RawPacketState) -> Result<Self, Self::Error> {
if Sequence::from(raw_pkt.sequence).is_zero() {
return Err(PacketError::ZeroPacketSequence);
}

if raw_pkt.data.is_empty() {
return Err(PacketError::ZeroPacketData);
}

Ok(PacketState {
seq: Sequence::from(raw_pkt.sequence),
port_id: raw_pkt.port_id.parse()?,
chan_id: raw_pkt.channel_id.parse()?,
data: raw_pkt.data,
})
}
}

impl From<PacketState> for RawPacketState {
fn from(packet: PacketState) -> Self {
Self {
sequence: packet.seq.0,
port_id: packet.port_id.to_string(),
channel_id: packet.chan_id.to_string(),
data: packet.data,
}
}
}

#[cfg(test)]
pub mod test_utils {
use ibc_proto::ibc::core::channel::v1::Packet as RawPacket;
Expand Down

0 comments on commit 27592c4

Please sign in to comment.