Skip to content

Commit b2fdda4

Browse files
committed
fix skipping channels that are closed and no further messages needs to be processed
1 parent dd2e4ec commit b2fdda4

File tree

12 files changed

+131
-89
lines changed

12 files changed

+131
-89
lines changed

crates/subspace-fake-runtime-api/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use sp_domains::{
1616
use sp_domains_fraud_proof::fraud_proof::FraudProof;
1717
use sp_domains_fraud_proof::storage_proof::FraudProofStorageKeyRequest;
1818
use sp_messenger::messages::{
19-
BlockMessagesQuery, BlockMessagesWithStorageKey, ChainId, ChannelId, ChannelState,
19+
BlockMessagesQuery, BlockMessagesWithStorageKey, ChainId, ChannelId, ChannelStateWithNonce,
2020
CrossDomainMessage, MessageId, MessageKey, Nonce as XdmNonce,
2121
};
2222
use sp_messenger::{ChannelNonce, XdmId};
@@ -418,7 +418,7 @@ sp_api::impl_runtime_apis! {
418418
unreachable!()
419419
}
420420

421-
fn channels_and_state() -> Vec<(ChainId, ChannelId, ChannelState)> {
421+
fn channels_and_state() -> Vec<(ChainId, ChannelId, ChannelStateWithNonce)> {
422422
unreachable!()
423423
}
424424

crates/subspace-runtime/src/lib.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,8 @@ use sp_domains_fraud_proof::storage_proof::{
7171
};
7272
use sp_messenger::endpoint::{Endpoint, EndpointHandler as EndpointHandlerT, EndpointId};
7373
use sp_messenger::messages::{
74-
BlockMessagesQuery, BlockMessagesWithStorageKey, ChainId, ChannelState, CrossDomainMessage,
75-
MessageId, MessageKey, Nonce as XdmNonce,
74+
BlockMessagesQuery, BlockMessagesWithStorageKey, ChainId, ChannelStateWithNonce,
75+
CrossDomainMessage, MessageId, MessageKey, Nonce as XdmNonce,
7676
};
7777
use sp_messenger::{ChannelNonce, XdmId};
7878
use sp_messenger_host_functions::{get_storage_key, StorageKeyRequest};
@@ -1708,7 +1708,7 @@ impl_runtime_apis! {
17081708
Messenger::get_block_messages(query)
17091709
}
17101710

1711-
fn channels_and_state() -> Vec<(ChainId, ChannelId, ChannelState)> {
1711+
fn channels_and_state() -> Vec<(ChainId, ChannelId, ChannelStateWithNonce)> {
17121712
Messenger::channels_and_states()
17131713
}
17141714

domains/client/relayer/src/lib.rs

Lines changed: 76 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use crate::aux_schema::{
1212
};
1313
use async_channel::TrySendError;
1414
use 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
};
1717
use parity_scale_codec::{Codec, Encode};
1818
use rand::seq::SliceRandom;
@@ -23,7 +23,7 @@ use sp_core::H256;
2323
use sp_domains::{ChannelId, DomainsApi};
2424
use sp_messenger::messages::{
2525
BlockMessageWithStorageKey, BlockMessagesQuery, BlockMessagesWithStorageKey, ChainId,
26-
ChannelState, CrossDomainMessage, Nonce, Proof,
26+
ChannelState, ChannelStateWithNonce, CrossDomainMessage, Nonce, Proof,
2727
};
2828
use sp_messenger::{MessengerApi, RelayerApi};
2929
use 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>
638638
where
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+
759772
fn is_relayer_api_version_available<Client, Block, CBlock>(
760773
client: &Arc<Client>,
761774
version: u32,

domains/pallets/messenger/src/lib.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -174,8 +174,9 @@ mod pallet {
174174
Endpoint, EndpointHandler, EndpointRequest, EndpointRequestWithCollectedFee, Sender,
175175
};
176176
use sp_messenger::messages::{
177-
ChainId, ChannelOpenParamsV1, CrossDomainMessage, Message, MessageId, MessageKey,
178-
MessageWeightTag, PayloadV1, ProtocolMessageRequest, RequestResponse, VersionedPayload,
177+
ChainId, ChannelOpenParamsV1, ChannelStateWithNonce, CrossDomainMessage, Message,
178+
MessageId, MessageKey, MessageWeightTag, PayloadV1, ProtocolMessageRequest,
179+
RequestResponse, VersionedPayload,
179180
};
180181
use sp_messenger::{
181182
ChannelNonce, DomainRegistration, InherentError, InherentType, NoteChainTransfer,
@@ -1414,7 +1415,7 @@ mod pallet {
14141415
Channels::<T>::iter_keys().collect()
14151416
}
14161417

1417-
pub fn channels_and_states() -> Vec<(ChainId, ChannelId, ChannelState)> {
1418+
pub fn channels_and_states() -> Vec<(ChainId, ChannelId, ChannelStateWithNonce)> {
14181419
crate::migrations::get_channels_and_states::<T>()
14191420
}
14201421

domains/pallets/messenger/src/migrations/v1_to_v2.rs

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ impl<Balance, AccountId> From<Channel<Balance, AccountId>> for ChannelV1<Balance
7777

7878
pub(crate) mod migrate_channels {
7979
use super::*;
80+
use sp_messenger::messages::ChannelStateWithNonce;
8081
use sp_runtime::traits::Get;
8182

8283
#[storage_alias]
@@ -110,12 +111,24 @@ pub(crate) mod migrate_channels {
110111
})
111112
}
112113

113-
pub(crate) fn get_channels_and_states<T: Config>() -> Vec<(ChainId, ChannelId, ChannelState)> {
114+
pub(crate) fn get_channels_and_states<T: Config>(
115+
) -> Vec<(ChainId, ChannelId, ChannelStateWithNonce)> {
114116
let keys: Vec<(ChainId, ChannelId)> = ChannelStorageV1::<T>::iter_keys().collect();
115117
keys.into_iter()
116118
.filter_map(|(chain_id, channel_id)| {
117-
get_channel::<T>(chain_id, channel_id)
118-
.map(|channel| (chain_id, channel_id, channel.state))
119+
get_channel::<T>(chain_id, channel_id).map(|channel| {
120+
let state = channel.state;
121+
let state_with_nonce = match state {
122+
ChannelState::Initiated => ChannelStateWithNonce::Initiated,
123+
ChannelState::Open => ChannelStateWithNonce::Open,
124+
ChannelState::Closed => ChannelStateWithNonce::Closed {
125+
next_outbox_nonce: channel.next_outbox_nonce,
126+
next_inbox_nonce: channel.next_inbox_nonce,
127+
},
128+
};
129+
130+
(chain_id, channel_id, state_with_nonce)
131+
})
119132
})
120133
.collect()
121134
}

domains/primitives/messenger/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ pub mod messages;
2323
#[cfg(not(feature = "std"))]
2424
extern crate alloc;
2525

26-
use crate::messages::{ChannelState, MessageKey, Nonce};
26+
use crate::messages::{ChannelStateWithNonce, MessageKey, Nonce};
2727
#[cfg(not(feature = "std"))]
2828
use alloc::collections::BTreeMap;
2929
#[cfg(not(feature = "std"))]
@@ -309,7 +309,7 @@ sp_api::decl_runtime_apis! {
309309
fn block_messages_with_query(query: BlockMessagesQuery) -> BlockMessagesWithStorageKey;
310310

311311
/// Returns all the channels to other chains and their local Channel state.
312-
fn channels_and_state() -> Vec<(ChainId, ChannelId, ChannelState)>;
312+
fn channels_and_state() -> Vec<(ChainId, ChannelId, ChannelStateWithNonce)>;
313313

314314
/// Returns the first outbox message nonce that should be relayed to the dst_chain.
315315
fn should_relay_outbox_messages(dst_chain_id: ChainId, channel_id: ChannelId, from_nonce: Nonce) -> Option<Nonce>;

domains/primitives/messenger/src/messages.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,21 @@ pub enum ChannelState {
3434
Closed,
3535
}
3636

37+
/// State of channel and nonces when channel is closed.
38+
#[derive(Default, Debug, Encode, Decode, Clone, Eq, PartialEq, TypeInfo)]
39+
pub enum ChannelStateWithNonce {
40+
/// Channel between chains is initiated but do not yet send or receive messages in this state.
41+
#[default]
42+
Initiated,
43+
/// Channel is open and can send and receive messages.
44+
Open,
45+
/// Channel is closed along with nonces at current point.
46+
Closed {
47+
next_outbox_nonce: Nonce,
48+
next_inbox_nonce: Nonce,
49+
},
50+
}
51+
3752
/// Channel describes a bridge to exchange messages between two chains.
3853
#[derive(Default, Debug, Encode, Decode, Clone, Eq, PartialEq, TypeInfo)]
3954
pub struct Channel<Balance, AccountId> {

domains/runtime/auto-id/src/lib.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@ use sp_core::{Get, OpaqueMetadata};
4242
use sp_domains::{ChannelId, DomainAllowlistUpdates, DomainId, Transfers};
4343
use sp_messenger::endpoint::{Endpoint, EndpointHandler as EndpointHandlerT, EndpointId};
4444
use sp_messenger::messages::{
45-
BlockMessagesQuery, BlockMessagesWithStorageKey, ChainId, ChannelState, CrossDomainMessage,
46-
MessageId, MessageKey, Nonce as XdmNonce,
45+
BlockMessagesQuery, BlockMessagesWithStorageKey, ChainId, ChannelStateWithNonce,
46+
CrossDomainMessage, MessageId, MessageKey, Nonce as XdmNonce,
4747
};
4848
use sp_messenger::{ChannelNonce, XdmId};
4949
use sp_messenger_host_functions::{get_storage_key, StorageKeyRequest};
@@ -1150,7 +1150,7 @@ impl_runtime_apis! {
11501150
Messenger::get_block_messages(query)
11511151
}
11521152

1153-
fn channels_and_state() -> Vec<(ChainId, ChannelId, ChannelState)> {
1153+
fn channels_and_state() -> Vec<(ChainId, ChannelId, ChannelStateWithNonce)> {
11541154
Messenger::channels_and_states()
11551155
}
11561156

domains/runtime/evm/src/lib.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,8 @@ use sp_evm_tracker::{
6464
};
6565
use sp_messenger::endpoint::{Endpoint, EndpointHandler as EndpointHandlerT, EndpointId};
6666
use sp_messenger::messages::{
67-
BlockMessagesQuery, BlockMessagesWithStorageKey, ChainId, ChannelState, CrossDomainMessage,
68-
MessageId, MessageKey, Nonce as XdmNonce,
67+
BlockMessagesQuery, BlockMessagesWithStorageKey, ChainId, ChannelStateWithNonce,
68+
CrossDomainMessage, MessageId, MessageKey, Nonce as XdmNonce,
6969
};
7070
use sp_messenger::{ChannelNonce, XdmId};
7171
use sp_messenger_host_functions::{get_storage_key, StorageKeyRequest};
@@ -1579,7 +1579,7 @@ impl_runtime_apis! {
15791579
Messenger::get_block_messages(query)
15801580
}
15811581

1582-
fn channels_and_state() -> Vec<(ChainId, ChannelId, ChannelState)> {
1582+
fn channels_and_state() -> Vec<(ChainId, ChannelId, ChannelStateWithNonce)> {
15831583
Messenger::channels_and_states()
15841584
}
15851585

domains/test/runtime/auto-id/src/lib.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@ use sp_core::{Get, OpaqueMetadata};
4242
use sp_domains::{ChannelId, DomainAllowlistUpdates, DomainId, Transfers};
4343
use sp_messenger::endpoint::{Endpoint, EndpointHandler as EndpointHandlerT, EndpointId};
4444
use sp_messenger::messages::{
45-
BlockMessagesQuery, BlockMessagesWithStorageKey, ChainId, ChannelState, CrossDomainMessage,
46-
MessageId, MessageKey, Nonce as XdmNonce,
45+
BlockMessagesQuery, BlockMessagesWithStorageKey, ChainId, ChannelStateWithNonce,
46+
CrossDomainMessage, MessageId, MessageKey, Nonce as XdmNonce,
4747
};
4848
use sp_messenger::{ChannelNonce, XdmId};
4949
use sp_messenger_host_functions::{get_storage_key, StorageKeyRequest};
@@ -1146,7 +1146,7 @@ impl_runtime_apis! {
11461146
Messenger::get_block_messages(query)
11471147
}
11481148

1149-
fn channels_and_state() -> Vec<(ChainId, ChannelId, ChannelState)> {
1149+
fn channels_and_state() -> Vec<(ChainId, ChannelId, ChannelStateWithNonce)> {
11501150
Messenger::channels_and_states()
11511151
}
11521152

0 commit comments

Comments
 (0)