Skip to content

Commit dd2e4ec

Browse files
committed
use one runtime call per channel when filtering out messages using best hash instead of one call per message
1 parent 7a42a85 commit dd2e4ec

File tree

10 files changed

+212
-122
lines changed

10 files changed

+212
-122
lines changed

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

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use sp_domains_fraud_proof::fraud_proof::FraudProof;
1717
use sp_domains_fraud_proof::storage_proof::FraudProofStorageKeyRequest;
1818
use sp_messenger::messages::{
1919
BlockMessagesQuery, BlockMessagesWithStorageKey, ChainId, ChannelId, ChannelState,
20-
CrossDomainMessage, MessageId, MessageKey,
20+
CrossDomainMessage, MessageId, MessageKey, Nonce as XdmNonce,
2121
};
2222
use sp_messenger::{ChannelNonce, XdmId};
2323
use sp_runtime::traits::NumberFor;
@@ -418,7 +418,15 @@ 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, ChannelState)> {
422+
unreachable!()
423+
}
424+
425+
fn should_relay_outbox_messages(_: ChainId, _: ChannelId, _: XdmNonce) -> Option<XdmNonce> {
426+
unreachable!()
427+
}
428+
429+
fn should_relay_inbox_message_responses(_: ChainId, _: ChannelId, _: XdmNonce) -> Option<XdmNonce> {
422430
unreachable!()
423431
}
424432
}

crates/subspace-runtime/src/lib.rs

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ use sp_domains_fraud_proof::storage_proof::{
7272
use sp_messenger::endpoint::{Endpoint, EndpointHandler as EndpointHandlerT, EndpointId};
7373
use sp_messenger::messages::{
7474
BlockMessagesQuery, BlockMessagesWithStorageKey, ChainId, ChannelState, CrossDomainMessage,
75-
MessageId, MessageKey,
75+
MessageId, MessageKey, Nonce as XdmNonce,
7676
};
7777
use sp_messenger::{ChannelNonce, XdmId};
7878
use sp_messenger_host_functions::{get_storage_key, StorageKeyRequest};
@@ -1684,12 +1684,12 @@ impl_runtime_apis! {
16841684
Messenger::inbox_response_message_unsigned(msg)
16851685
}
16861686

1687-
fn should_relay_outbox_message(dst_chain_id: ChainId, msg_id: MessageId) -> bool {
1688-
Messenger::should_relay_outbox_message(dst_chain_id, msg_id)
1687+
fn should_relay_outbox_message(_: ChainId, _: MessageId) -> bool {
1688+
false
16891689
}
16901690

1691-
fn should_relay_inbox_message_response(dst_chain_id: ChainId, msg_id: MessageId) -> bool {
1692-
Messenger::should_relay_inbox_message_response(dst_chain_id, msg_id)
1691+
fn should_relay_inbox_message_response(_: ChainId, _: MessageId) -> bool {
1692+
false
16931693
}
16941694

16951695
fn updated_channels() -> BTreeSet<(ChainId, ChannelId)> {
@@ -1708,9 +1708,17 @@ 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, ChannelState)> {
17121712
Messenger::channels_and_states()
17131713
}
1714+
1715+
fn should_relay_outbox_messages(dst_chain_id: ChainId, channel_id: ChannelId, from_nonce: XdmNonce) -> Option<XdmNonce> {
1716+
Messenger::should_relay_outbox_messages(dst_chain_id, channel_id, from_nonce)
1717+
}
1718+
1719+
fn should_relay_inbox_message_responses(dst_chain_id: ChainId, channel_id: ChannelId, from_nonce: XdmNonce) -> Option<XdmNonce> {
1720+
Messenger::should_relay_inbox_message_responses(dst_chain_id, channel_id, from_nonce)
1721+
}
17141722
}
17151723

17161724
impl sp_domains_fraud_proof::FraudProofApi<Block, DomainHeader> for Runtime {

domains/client/relayer/src/lib.rs

Lines changed: 66 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -240,58 +240,6 @@ where
240240
.map_err(Error::UnableToSubmitCrossDomainMessage)
241241
}
242242

243-
fn should_relay_outbox_message<Client, Block, CBlock>(
244-
api: &ApiRef<'_, Client::Api>,
245-
best_hash: Block::Hash,
246-
msg: &BlockMessageWithStorageKey,
247-
) -> bool
248-
where
249-
Block: BlockT,
250-
CBlock: BlockT,
251-
Client: ProvideRuntimeApi<Block> + HeaderBackend<Block>,
252-
Client::Api: RelayerApi<Block, NumberFor<Block>, NumberFor<CBlock>, CBlock::Hash>,
253-
{
254-
let id = msg.id();
255-
match api.should_relay_outbox_message(best_hash, msg.dst_chain_id, id) {
256-
Ok(val) => val,
257-
Err(err) => {
258-
tracing::error!(
259-
target: LOG_TARGET,
260-
?err,
261-
"Failed to fetch validity of outbox message {id:?} for domain {0:?}",
262-
msg.dst_chain_id
263-
);
264-
false
265-
}
266-
}
267-
}
268-
269-
fn should_relay_inbox_responses_message<Client, Block, CBlock>(
270-
api: &ApiRef<'_, Client::Api>,
271-
best_hash: Block::Hash,
272-
msg: &BlockMessageWithStorageKey,
273-
) -> bool
274-
where
275-
Block: BlockT,
276-
CBlock: BlockT,
277-
Client: ProvideRuntimeApi<Block> + HeaderBackend<Block>,
278-
Client::Api: RelayerApi<Block, NumberFor<Block>, NumberFor<CBlock>, CBlock::Hash>,
279-
{
280-
let id = msg.id();
281-
match api.should_relay_inbox_message_response(best_hash, msg.dst_chain_id, id) {
282-
Ok(val) => val,
283-
Err(err) => {
284-
tracing::error!(
285-
target: LOG_TARGET,
286-
?err,
287-
"Failed to fetch validity of inbox message response {id:?} for domain {0:?}",
288-
msg.dst_chain_id
289-
);
290-
false
291-
}
292-
}
293-
}
294-
295243
// Fetch the XDM at the given block and filter any already relayed XDM according to the best block
296244
fn fetch_and_filter_messages<Client, Block, CClient, CBlock>(
297245
client: &Arc<Client>,
@@ -306,32 +254,17 @@ where
306254
Client: ProvideRuntimeApi<Block> + HeaderBackend<Block>,
307255
Client::Api: RelayerApi<Block, NumberFor<Block>, NumberFor<CBlock>, CBlock::Hash>,
308256
{
309-
let mut msgs =
310-
if is_relayer_api_version_available::<_, Block, CBlock>(client, 3, fetch_message_at) {
311-
fetch_messages::<_, _, Block, CBlock>(
312-
&**consensus_client,
313-
client,
314-
fetch_message_at,
315-
self_chain_id,
316-
)
317-
.map_err(|_| Error::FetchAssignedMessages)?
318-
} else {
319-
client
320-
.runtime_api()
321-
.block_messages(fetch_message_at)
322-
.map_err(|_| Error::FetchAssignedMessages)?
323-
};
324-
325-
let api = client.runtime_api();
326-
let best_hash = client.info().best_hash;
327-
msgs.outbox
328-
.retain(|msg| should_relay_outbox_message::<Client, Block, CBlock>(&api, best_hash, msg));
329-
330-
msgs.inbox_responses.retain(|msg| {
331-
should_relay_inbox_responses_message::<Client, Block, CBlock>(&api, best_hash, msg)
332-
});
257+
// return no messages for previous relayer version
258+
if !is_relayer_api_version_available::<_, Block, CBlock>(client, 3, fetch_message_at) {
259+
return Ok(BlockMessagesWithStorageKey::default());
260+
}
333261

334-
Ok(msgs)
262+
fetch_messages::<_, _, Block, CBlock>(
263+
&**consensus_client,
264+
client,
265+
fetch_message_at,
266+
self_chain_id,
267+
)
335268
}
336269

337270
// A helper struct used when constructing XDM proof
@@ -534,6 +467,48 @@ where
534467
}
535468
}
536469

470+
fn filter_block_messages<Client, Block, CBlock>(
471+
api: &ApiRef<'_, Client::Api>,
472+
best_hash: Block::Hash,
473+
query: BlockMessagesQuery,
474+
messages: &mut BlockMessagesWithStorageKey,
475+
) -> Result<(), Error>
476+
where
477+
Block: BlockT,
478+
CBlock: BlockT,
479+
Client: ProvideRuntimeApi<Block> + HeaderBackend<Block>,
480+
Client::Api: RelayerApi<Block, NumberFor<Block>, NumberFor<CBlock>, CBlock::Hash>,
481+
{
482+
let BlockMessagesQuery {
483+
chain_id,
484+
channel_id,
485+
outbox_from,
486+
inbox_responses_from,
487+
} = query;
488+
let maybe_outbox_nonce =
489+
api.should_relay_outbox_messages(best_hash, chain_id, channel_id, outbox_from)?;
490+
let maybe_inbox_response_nonce = api.should_relay_inbox_message_responses(
491+
best_hash,
492+
chain_id,
493+
channel_id,
494+
inbox_responses_from,
495+
)?;
496+
497+
if let Some(nonce) = maybe_outbox_nonce {
498+
messages.outbox.retain(|msg| msg.nonce >= nonce)
499+
} else {
500+
messages.outbox.clear()
501+
}
502+
503+
if let Some(nonce) = maybe_inbox_response_nonce {
504+
messages.inbox_responses.retain(|msg| msg.nonce >= nonce)
505+
} else {
506+
messages.inbox_responses.clear();
507+
}
508+
509+
Ok(())
510+
}
511+
537512
// Fetch the unprocessed XDMs at a given block
538513
fn fetch_messages<Backend, Client, Block, CBlock>(
539514
backend: &Backend,
@@ -580,6 +555,8 @@ where
580555
queries
581556
};
582557

558+
let best_hash = client.info().best_hash;
559+
let runtime_api_best = client.runtime_api();
583560
let total_messages = queries
584561
.into_iter()
585562
.filter_map(|query| {
@@ -588,9 +565,19 @@ where
588565
channel_id,
589566
..
590567
} = query;
591-
let messages = runtime_api
592-
.block_messages_with_query(fetch_message_at, query)
568+
let mut messages = runtime_api
569+
.block_messages_with_query(fetch_message_at, query.clone())
593570
.ok()?;
571+
572+
// filter messages with best hash
573+
filter_block_messages::<Client, _, CBlock>(
574+
&runtime_api_best,
575+
best_hash,
576+
query,
577+
&mut messages,
578+
)
579+
.ok()?;
580+
594581
if !messages.outbox.is_empty()
595582
&& let Some(max_nonce) = messages.outbox.iter().map(|key| key.nonce).max()
596583
{

domains/pallets/messenger/src/lib.rs

Lines changed: 48 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,9 @@ use scale_info::TypeInfo;
4545
use sp_core::U256;
4646
use sp_domains::{DomainAllowlistUpdates, DomainId};
4747
use sp_messenger::messages::{
48-
ChainId, Channel, ChannelId, ChannelState, CrossDomainMessage, Message, MessageId, Nonce,
48+
ChainId, Channel, ChannelId, ChannelState, CrossDomainMessage, Message, Nonce,
4949
};
50+
use sp_messenger::MAX_FUTURE_ALLOWED_NONCES;
5051
use sp_runtime::traits::Hash;
5152
use sp_runtime::DispatchError;
5253
use subspace_runtime_primitives::CreateUnsigned;
@@ -1510,14 +1511,54 @@ where
15101511
Some(T::create_unsigned(call.into()))
15111512
}
15121513

1513-
/// Returns true if the outbox message has not received the response yet.
1514-
pub fn should_relay_outbox_message(dst_chain_id: ChainId, msg_id: MessageId) -> bool {
1515-
Outbox::<T>::contains_key((dst_chain_id, msg_id.0, msg_id.1))
1514+
/// Returns the first outbox message nonce that should be relayed to the dst_chain.
1515+
pub fn should_relay_outbox_messages(
1516+
dst_chain_id: ChainId,
1517+
channel_id: ChannelId,
1518+
from_nonce: Nonce,
1519+
) -> Option<Nonce> {
1520+
Self::should_relay_message(
1521+
dst_chain_id,
1522+
channel_id,
1523+
from_nonce,
1524+
Outbox::<T>::contains_key,
1525+
)
15161526
}
15171527

1518-
/// Returns true if the inbox message response has not received acknowledgement yet.
1519-
pub fn should_relay_inbox_message_response(dst_chain_id: ChainId, msg_id: MessageId) -> bool {
1520-
InboxResponses::<T>::contains_key((dst_chain_id, msg_id.0, msg_id.1))
1528+
/// Returns the first inbox response message nonce that should be relayed to the dst_chain.
1529+
pub fn should_relay_inbox_message_responses(
1530+
dst_chain_id: ChainId,
1531+
channel_id: ChannelId,
1532+
from_nonce: Nonce,
1533+
) -> Option<Nonce> {
1534+
Self::should_relay_message(
1535+
dst_chain_id,
1536+
channel_id,
1537+
from_nonce,
1538+
InboxResponses::<T>::contains_key,
1539+
)
1540+
}
1541+
1542+
fn should_relay_message<Check>(
1543+
dst_chain_id: ChainId,
1544+
channel_id: ChannelId,
1545+
from_nonce: Nonce,
1546+
check: Check,
1547+
) -> Option<Nonce>
1548+
where
1549+
Check: Fn((ChainId, ChannelId, Nonce)) -> bool,
1550+
{
1551+
let mut nonce = from_nonce;
1552+
let to_nonce = from_nonce.saturating_add(MAX_FUTURE_ALLOWED_NONCES.into());
1553+
while nonce <= to_nonce {
1554+
if check((dst_chain_id, channel_id, nonce)) {
1555+
return Some(nonce);
1556+
}
1557+
1558+
nonce = nonce.saturating_add(Nonce::one())
1559+
}
1560+
1561+
None
15211562
}
15221563
}
15231564

domains/primitives/messenger/src/lib.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,12 @@ sp_api::decl_runtime_apis! {
310310

311311
/// Returns all the channels to other chains and their local Channel state.
312312
fn channels_and_state() -> Vec<(ChainId, ChannelId, ChannelState)>;
313+
314+
/// Returns the first outbox message nonce that should be relayed to the dst_chain.
315+
fn should_relay_outbox_messages(dst_chain_id: ChainId, channel_id: ChannelId, from_nonce: Nonce) -> Option<Nonce>;
316+
317+
/// Returns the first inbox response message nonce that should be relayed to the dst_chain.
318+
fn should_relay_inbox_message_responses(dst_chain_id: ChainId,channel_id: ChannelId, from_nonce: Nonce) -> Option<Nonce>;
313319
}
314320

315321
/// Api to provide XDM extraction from Runtime Calls.

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

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ use sp_domains::{ChannelId, DomainAllowlistUpdates, DomainId, Transfers};
4343
use sp_messenger::endpoint::{Endpoint, EndpointHandler as EndpointHandlerT, EndpointId};
4444
use sp_messenger::messages::{
4545
BlockMessagesQuery, BlockMessagesWithStorageKey, ChainId, ChannelState, CrossDomainMessage,
46-
MessageId, MessageKey,
46+
MessageId, MessageKey, Nonce as XdmNonce,
4747
};
4848
use sp_messenger::{ChannelNonce, XdmId};
4949
use sp_messenger_host_functions::{get_storage_key, StorageKeyRequest};
@@ -1126,12 +1126,12 @@ impl_runtime_apis! {
11261126
Messenger::inbox_response_message_unsigned(msg)
11271127
}
11281128

1129-
fn should_relay_outbox_message(dst_chain_id: ChainId, msg_id: MessageId) -> bool {
1130-
Messenger::should_relay_outbox_message(dst_chain_id, msg_id)
1129+
fn should_relay_outbox_message(_: ChainId, _: MessageId) -> bool {
1130+
false
11311131
}
11321132

1133-
fn should_relay_inbox_message_response(dst_chain_id: ChainId, msg_id: MessageId) -> bool {
1134-
Messenger::should_relay_inbox_message_response(dst_chain_id, msg_id)
1133+
fn should_relay_inbox_message_response(_: ChainId, _: MessageId) -> bool {
1134+
false
11351135
}
11361136

11371137
fn updated_channels() -> BTreeSet<(ChainId, ChannelId)> {
@@ -1150,9 +1150,17 @@ 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, ChannelState)> {
11541154
Messenger::channels_and_states()
11551155
}
1156+
1157+
fn should_relay_outbox_messages(dst_chain_id: ChainId, channel_id: ChannelId, from_nonce: XdmNonce) -> Option<XdmNonce> {
1158+
Messenger::should_relay_outbox_messages(dst_chain_id, channel_id, from_nonce)
1159+
}
1160+
1161+
fn should_relay_inbox_message_responses(dst_chain_id: ChainId, channel_id: ChannelId, from_nonce: XdmNonce) -> Option<XdmNonce> {
1162+
Messenger::should_relay_inbox_message_responses(dst_chain_id, channel_id, from_nonce)
1163+
}
11561164
}
11571165

11581166
impl sp_domain_sudo::DomainSudoApi<Block> for Runtime {

0 commit comments

Comments
 (0)