diff --git a/cairo-contracts/packages/core/src/channel/components/handler.cairo b/cairo-contracts/packages/core/src/channel/components/handler.cairo index 84719d4b..68b43213 100644 --- a/cairo-contracts/packages/core/src/channel/components/handler.cairo +++ b/cairo-contracts/packages/core/src/channel/components/handler.cairo @@ -5,9 +5,8 @@ pub mod ChannelHandlerComponent { use ConnectionHandlerComponent::CoreConnectionQuery; use RouterHandlerComponent::RouterInternalTrait; use core::num::traits::Zero; - use starknet::storage::Map; use starknet::storage::{ - StorageMapReadAccess, StorageMapWriteAccess, StoragePointerReadAccess, + Map, StorageMapReadAccess, StorageMapWriteAccess, StoragePointerReadAccess, StoragePointerWriteAccess }; use starknet::{get_block_timestamp, get_block_number}; @@ -164,7 +163,6 @@ pub mod ChannelHandlerComponent { self.read_packet_ack(@port_id, @channel_id, @sequence) } - fn is_packet_received( self: @ComponentState, port_id: PortId, @@ -174,6 +172,41 @@ pub mod ChannelHandlerComponent { self.packet_ack_exists(@port_id, @channel_id, @sequence) } + fn unreceived_packet_sequences( + self: @ComponentState, + port_id: PortId, + channel_id: ChannelId, + sequences: Array + ) -> Array { + assert(sequences.len() > 0, ChannelErrors::EMPTY_SEQUENCE_LIST); + let mut unreceived_sequences = ArrayTrait::new(); + for seq in sequences { + if self.read_packet_receipt(@port_id, @channel_id, @seq).is_none() { + unreceived_sequences.append(seq); + } + }; + unreceived_sequences + } + + fn unreceived_ack_sequences( + self: @ComponentState, + port_id: PortId, + channel_id: ChannelId, + sequences: Array + ) -> Array { + assert(sequences.len() > 0, ChannelErrors::EMPTY_SEQUENCE_LIST); + let mut unreceived_sequences = ArrayTrait::new(); + for seq in sequences { + if self + .packet_commitments + .read(commitment_key(@port_id, @channel_id, @seq)) + .is_non_zero() { + unreceived_sequences.append(seq) + }; + }; + unreceived_sequences + } + fn next_sequence_send( self: @ComponentState, port_id: PortId, channel_id: ChannelId ) -> Sequence { diff --git a/cairo-contracts/packages/core/src/channel/errors.cairo b/cairo-contracts/packages/core/src/channel/errors.cairo index a5ae1980..0ff98fd3 100644 --- a/cairo-contracts/packages/core/src/channel/errors.cairo +++ b/cairo-contracts/packages/core/src/channel/errors.cairo @@ -6,6 +6,7 @@ pub mod ChannelErrors { pub const EMPTY_ACK: felt252 = 'ICS04: empty acknowledgement'; pub const EMPTY_UNRECEIVED_PROOF: felt252 = 'ICS04: empty unreceived proof'; pub const EMPTY_ACK_PROOF: felt252 = 'ICS04: empty ack proof'; + pub const EMPTY_SEQUENCE_LIST: felt252 = 'ICS04: empty sequence list'; pub const ZERO_PROOF_HEIGHT: felt252 = 'ICS04: zero proof height'; pub const UNSUPPORTED_ORDERING: felt252 = 'ICS04: unsupported ordering'; pub const INVALID_CHANNEL_STATE: felt252 = 'ICS04: invalid channel state'; diff --git a/cairo-contracts/packages/core/src/channel/interface.cairo b/cairo-contracts/packages/core/src/channel/interface.cairo index b469e4ba..5c683a53 100644 --- a/cairo-contracts/packages/core/src/channel/interface.cairo +++ b/cairo-contracts/packages/core/src/channel/interface.cairo @@ -70,6 +70,12 @@ pub trait IChannelQuery { fn is_packet_received( self: @TContractState, port_id: PortId, channel_id: ChannelId, sequence: Sequence ) -> bool; + fn unreceived_packet_sequences( + self: @TContractState, port_id: PortId, channel_id: ChannelId, sequences: Array + ) -> Array; + fn unreceived_ack_sequences( + self: @TContractState, port_id: PortId, channel_id: ChannelId, sequences: Array + ) -> Array; fn next_sequence_send( self: @TContractState, port_id: PortId, channel_id: ChannelId ) -> Sequence;