@@ -12,7 +12,7 @@ use crate::aux_schema::{
1212} ;
1313use async_channel:: TrySendError ;
1414use cross_domain_message_gossip:: {
15- get_channel_state, Message as GossipMessage , MessageData as GossipMessageData ,
15+ get_channel_state, ChannelDetail , Message as GossipMessage , MessageData as GossipMessageData ,
1616} ;
1717use parity_scale_codec:: { Codec , Encode } ;
1818use rand:: seq:: SliceRandom ;
@@ -23,7 +23,7 @@ use sp_core::H256;
2323use sp_domains:: { ChannelId , DomainsApi } ;
2424use sp_messenger:: messages:: {
2525 BlockMessageWithStorageKey , BlockMessagesQuery , BlockMessagesWithStorageKey , ChainId ,
26- ChannelState , CrossDomainMessage , Nonce , Proof ,
26+ ChannelState , ChannelStateWithNonce , CrossDomainMessage , Nonce , Proof ,
2727} ;
2828use sp_messenger:: { MessengerApi , RelayerApi } ;
2929use sp_mmr_primitives:: MmrApi ;
@@ -633,7 +633,7 @@ fn get_channel_state_query<Backend, Client, Block>(
633633 self_chain_id : ChainId ,
634634 dst_chain_id : ChainId ,
635635 channel_id : ChannelId ,
636- local_channel_state : ChannelState ,
636+ local_channel_state : ChannelStateWithNonce ,
637637) -> Result < Option < BlockMessagesQuery > , Error >
638638where
639639 Backend : AuxStore ,
@@ -667,16 +667,19 @@ where
667667 inbox_responses_from : Nonce :: zero ( ) ,
668668 } ) ,
669669 // don't have channel processed state, so use the dst_channel state for query
670- ( Some ( dst_channel_state) , None , None ) => Some ( BlockMessagesQuery {
671- chain_id : dst_chain_id,
672- channel_id,
673- outbox_from : dst_channel_state. next_inbox_nonce ,
674- inbox_responses_from : dst_channel_state
675- . latest_response_received_message_nonce
676- // pick the next inbox message response nonce or default to zero
677- . map ( |nonce| nonce. saturating_add ( One :: one ( ) ) )
678- . unwrap_or ( Nonce :: zero ( ) ) ,
679- } ) ,
670+ ( Some ( dst_channel_state) , None , None ) => {
671+ should_relay_messages_to_channel ( dst_chain_id, & dst_channel_state, local_channel_state)
672+ . then_some ( BlockMessagesQuery {
673+ chain_id : dst_chain_id,
674+ channel_id,
675+ outbox_from : dst_channel_state. next_inbox_nonce ,
676+ inbox_responses_from : dst_channel_state
677+ . latest_response_received_message_nonce
678+ // pick the next inbox message response nonce or default to zero
679+ . map ( |nonce| nonce. saturating_add ( One :: one ( ) ) )
680+ . unwrap_or ( Nonce :: zero ( ) ) ,
681+ } )
682+ }
680683 // don't have dst channel state, so use the last processed channel state
681684 ( None , last_outbox_nonce, last_inbox_message_response_nonce) => Some ( BlockMessagesQuery {
682685 chain_id : dst_chain_id,
@@ -689,61 +692,32 @@ where
689692 . unwrap_or ( Nonce :: zero ( ) ) ,
690693 } ) ,
691694 ( Some ( dst_channel_state) , last_outbox_nonce, last_inbox_message_response_nonce) => {
692- let next_outbox_nonce = max (
693- dst_channel_state. next_inbox_nonce ,
694- last_outbox_nonce
695- . map ( |nonce| nonce. saturating_add ( One :: one ( ) ) )
696- . unwrap_or ( Nonce :: zero ( ) ) ,
697- ) ;
698-
699- let next_inbox_response_nonce = max (
700- dst_channel_state
701- . latest_response_received_message_nonce
702- . map ( |nonce| nonce. saturating_add ( One :: one ( ) ) )
703- . unwrap_or ( Nonce :: zero ( ) ) ,
704- last_inbox_message_response_nonce
705- . map ( |nonce| nonce. saturating_add ( One :: one ( ) ) )
706- . unwrap_or ( Nonce :: zero ( ) ) ,
707- ) ;
708-
709- // if the local channel is closed, and
710- // last outbox message is already included
711- // and
712- // if the dst_channel is closed, and
713- // last inbox message response is already included
714- // we can safely skip the channel as the there is nothing further to send.
715- if local_channel_state == ChannelState :: Closed
716- && dst_channel_state. state == ChannelState :: Closed
717- {
718- let is_last_outbox_nonce = dst_channel_state
719- . next_inbox_nonce
720- . saturating_sub ( One :: one ( ) )
721- == last_outbox_nonce. unwrap_or ( Nonce :: zero ( ) ) ;
722-
723- let is_last_inbox_message_response_nonce = dst_channel_state
724- . latest_response_received_message_nonce
725- . unwrap_or ( Nonce :: zero ( ) )
726- == last_inbox_message_response_nonce. unwrap_or ( Nonce :: zero ( ) ) ;
727-
728- if is_last_outbox_nonce && is_last_inbox_message_response_nonce {
729- tracing:: debug!( target: LOG_TARGET , "Skipping XDM for Chain[{:?}] - Channel[{:?}]" , dst_chain_id, channel_id) ;
730- None
731- } else {
732- Some ( BlockMessagesQuery {
695+ should_relay_messages_to_channel ( dst_chain_id, & dst_channel_state, local_channel_state)
696+ . then ( || {
697+ let next_outbox_nonce = max (
698+ dst_channel_state. next_inbox_nonce ,
699+ last_outbox_nonce
700+ . map ( |nonce| nonce. saturating_add ( One :: one ( ) ) )
701+ . unwrap_or ( Nonce :: zero ( ) ) ,
702+ ) ;
703+
704+ let next_inbox_response_nonce = max (
705+ dst_channel_state
706+ . latest_response_received_message_nonce
707+ . map ( |nonce| nonce. saturating_add ( One :: one ( ) ) )
708+ . unwrap_or ( Nonce :: zero ( ) ) ,
709+ last_inbox_message_response_nonce
710+ . map ( |nonce| nonce. saturating_add ( One :: one ( ) ) )
711+ . unwrap_or ( Nonce :: zero ( ) ) ,
712+ ) ;
713+
714+ BlockMessagesQuery {
733715 chain_id : dst_chain_id,
734716 channel_id,
735717 outbox_from : next_outbox_nonce,
736718 inbox_responses_from : next_inbox_response_nonce,
737- } )
738- }
739- } else {
740- Some ( BlockMessagesQuery {
741- chain_id : dst_chain_id,
742- channel_id,
743- outbox_from : next_outbox_nonce,
744- inbox_responses_from : next_inbox_response_nonce,
719+ }
745720 } )
746- }
747721 }
748722 } ;
749723
@@ -756,6 +730,45 @@ where
756730 Ok ( query)
757731}
758732
733+ fn should_relay_messages_to_channel (
734+ dst_chain_id : ChainId ,
735+ dst_channel_state : & ChannelDetail ,
736+ local_channel_state : ChannelStateWithNonce ,
737+ ) -> bool {
738+ let should_process = if dst_channel_state. state == ChannelState :: Closed
739+ && let ChannelStateWithNonce :: Closed {
740+ next_outbox_nonce,
741+ next_inbox_nonce,
742+ } = local_channel_state
743+ {
744+ // if the next outbox nonce of local channel is same as
745+ // next inbox nonce of dst_channel, then there are no further
746+ // outbox messages to be sent from the local channel
747+ let no_outbox_messages = next_outbox_nonce == dst_channel_state. next_inbox_nonce ;
748+
749+ // if next inbox nonce of local channel is +1 of
750+ // last received response nonce on dst_chain, then there are
751+ // no further messages responses to be sent from the local channel
752+ let no_inbox_responses_messages = dst_channel_state
753+ . latest_response_received_message_nonce
754+ . map ( |nonce| nonce == next_inbox_nonce. saturating_sub ( Nonce :: one ( ) ) )
755+ . unwrap_or ( false ) ;
756+
757+ !( no_outbox_messages && no_inbox_responses_messages)
758+ } else {
759+ true
760+ } ;
761+
762+ if !should_process {
763+ tracing:: debug!( target: LOG_TARGET ,
764+ "Chain[{:?}] for Channel[{:?}] is closed and no messages to process" ,
765+ dst_chain_id, dst_channel_state. channel_id
766+ ) ;
767+ }
768+
769+ should_process
770+ }
771+
759772fn is_relayer_api_version_available < Client , Block , CBlock > (
760773 client : & Arc < Client > ,
761774 version : u32 ,
0 commit comments