Skip to content

Commit 7dd97e4

Browse files
Clear other messages before dry-run to get only the ones produced during (#5581)
The dry-run shows in `forwarded_xcms` all the messages in the queues at the time of calling the API. Each time the API is called, the result could be different. You could get messages even if you dry-run something that doesn't send a message, like a `System::remark`. This PR fixes this by clearing the message queues before doing the dry-run, so the only messages left are the ones the users of the API actually care about. --------- Co-authored-by: Adrian Catangiu <[email protected]> (cherry picked from commit 8d9ebcd)
1 parent d6f482d commit 7dd97e4

10 files changed

Lines changed: 78 additions & 1 deletion

File tree

bridges/modules/xcm-bridge-hub-router/src/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,10 @@ impl<T: Config<I>, I: 'static> SendXcm for Pallet<T, I> {
398398
}
399399

400400
impl<T: Config<I>, I: 'static> InspectMessageQueues for Pallet<T, I> {
401+
fn clear_messages() {
402+
ViaBridgeHubExporter::<T, I>::clear_messages()
403+
}
404+
401405
fn get_messages() -> Vec<(VersionedLocation, Vec<VersionedXcm<()>>)> {
402406
ViaBridgeHubExporter::<T, I>::get_messages()
403407
}

bridges/modules/xcm-bridge-hub-router/src/mock.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,10 @@ impl SendXcm for TestToBridgeHubSender {
131131
}
132132

133133
impl InspectMessageQueues for TestToBridgeHubSender {
134+
fn clear_messages() {
135+
SENT_XCM.with(|q| q.borrow_mut().clear());
136+
}
137+
134138
fn get_messages() -> Vec<(VersionedLocation, Vec<VersionedXcm<()>>)> {
135139
SENT_XCM.with(|q| {
136140
(*q.borrow())

cumulus/pallets/parachain-system/src/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1611,6 +1611,10 @@ impl<T: Config> UpwardMessageSender for Pallet<T> {
16111611
}
16121612

16131613
impl<T: Config> InspectMessageQueues for Pallet<T> {
1614+
fn clear_messages() {
1615+
PendingUpwardMessages::<T>::kill();
1616+
}
1617+
16141618
fn get_messages() -> Vec<(VersionedLocation, Vec<VersionedXcm<()>>)> {
16151619
use xcm::prelude::*;
16161620

cumulus/pallets/xcmp-queue/src/lib.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1008,6 +1008,11 @@ impl<T: Config> SendXcm for Pallet<T> {
10081008
}
10091009

10101010
impl<T: Config> InspectMessageQueues for Pallet<T> {
1011+
fn clear_messages() {
1012+
// Best effort.
1013+
let _ = OutboundXcmpMessages::<T>::clear(u32::MAX, None);
1014+
}
1015+
10111016
fn get_messages() -> Vec<(VersionedLocation, Vec<VersionedXcm<()>>)> {
10121017
use xcm::prelude::*;
10131018

cumulus/primitives/utility/src/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,10 @@ where
9999
impl<T: UpwardMessageSender + InspectMessageQueues, W, P> InspectMessageQueues
100100
for ParentAsUmp<T, W, P>
101101
{
102+
fn clear_messages() {
103+
T::clear_messages();
104+
}
105+
102106
fn get_messages() -> Vec<(VersionedLocation, Vec<VersionedXcm<()>>)> {
103107
T::get_messages()
104108
}

polkadot/runtime/common/src/xcm_sender.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,11 @@ where
141141
}
142142

143143
impl<T: dmp::Config, W, P> InspectMessageQueues for ChildParachainRouter<T, W, P> {
144+
fn clear_messages() {
145+
// Best effort.
146+
let _ = dmp::DownwardMessageQueues::<T>::clear(u32::MAX, None);
147+
}
148+
144149
fn get_messages() -> Vec<(VersionedLocation, Vec<VersionedXcm<()>>)> {
145150
dmp::DownwardMessageQueues::<T>::iter()
146151
.map(|(para_id, messages)| {

polkadot/xcm/pallet-xcm/src/lib.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2457,10 +2457,14 @@ impl<T: Config> Pallet<T> {
24572457
<RuntimeCall as Dispatchable>::RuntimeOrigin: From<OriginCaller>,
24582458
{
24592459
crate::Pallet::<Runtime>::set_record_xcm(true);
2460-
frame_system::Pallet::<Runtime>::reset_events(); // To make sure we only record events from current call.
2460+
// Clear other messages in queues...
2461+
Router::clear_messages();
2462+
// ...and reset events to make sure we only record events from current call.
2463+
frame_system::Pallet::<Runtime>::reset_events();
24612464
let result = call.dispatch(origin.into());
24622465
crate::Pallet::<Runtime>::set_record_xcm(false);
24632466
let local_xcm = crate::Pallet::<Runtime>::recorded_xcm();
2467+
// Should only get messages from this call since we cleared previous ones.
24642468
let forwarded_xcms = Router::get_messages();
24652469
let events: Vec<<Runtime as frame_system::Config>::RuntimeEvent> =
24662470
frame_system::Pallet::<Runtime>::read_events_no_consensus()

polkadot/xcm/xcm-builder/src/routing.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,10 @@ impl<Inner: SendXcm> SendXcm for WithUniqueTopic<Inner> {
6262
}
6363
}
6464
impl<Inner: InspectMessageQueues> InspectMessageQueues for WithUniqueTopic<Inner> {
65+
fn clear_messages() {
66+
Inner::clear_messages()
67+
}
68+
6569
fn get_messages() -> Vec<(VersionedLocation, Vec<VersionedXcm<()>>)> {
6670
Inner::get_messages()
6771
}
@@ -149,12 +153,21 @@ impl EnsureDelivery for Tuple {
149153
/// Inspects messages in queues.
150154
/// Meant to be used in runtime APIs, not in runtimes.
151155
pub trait InspectMessageQueues {
156+
/// Clear the queues at the beginning of Runtime API call, so that subsequent
157+
/// `Self::get_messages()` will return only messages generated by said Runtime API.
158+
fn clear_messages();
152159
/// Get queued messages and their destinations.
153160
fn get_messages() -> Vec<(VersionedLocation, Vec<VersionedXcm<()>>)>;
154161
}
155162

156163
#[impl_trait_for_tuples::impl_for_tuples(30)]
157164
impl InspectMessageQueues for Tuple {
165+
fn clear_messages() {
166+
for_tuples!( #(
167+
Tuple::clear_messages();
168+
)* );
169+
}
170+
158171
fn get_messages() -> Vec<(VersionedLocation, Vec<VersionedXcm<()>>)> {
159172
let mut messages = Vec::new();
160173

polkadot/xcm/xcm-builder/src/universal_exports.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,10 @@ impl<Bridges: ExporterFor, Router: SendXcm, UniversalLocation: Get<InteriorLocat
340340
impl<Bridges, Router: InspectMessageQueues, UniversalLocation> InspectMessageQueues
341341
for SovereignPaidRemoteExporter<Bridges, Router, UniversalLocation>
342342
{
343+
fn clear_messages() {
344+
Router::clear_messages()
345+
}
346+
343347
fn get_messages() -> Vec<(VersionedLocation, Vec<VersionedXcm<()>>)> {
344348
Router::get_messages()
345349
}

prdoc/pr_5581.prdoc

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# Schema: Polkadot SDK PRDoc Schema (prdoc) v1.0.0
2+
# See doc at https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/prdoc/schema_user.json
3+
4+
title: Clear other messages before dry-running
5+
6+
doc:
7+
- audience: Runtime Dev
8+
description: |
9+
The DryRunApi.dry_run_call and DryRunApi.dry_run_xcm functions used to populate
10+
`forwarded_xcms` with all the existing messages in the queues at the time.
11+
Now, existing (irrelevant) messages are cleared when dry-running, meaning only the
12+
messages produced by the dry-run call (or xcm) will be returned in `forwarded_xcms`.
13+
14+
crates:
15+
- name: pallet-xcm
16+
bump: minor
17+
- name: staging-xcm-builder
18+
bump: major
19+
- name: pallet-xcm-bridge-hub-router
20+
bump: minor
21+
- name: cumulus-pallet-parachain-system
22+
bump: minor
23+
- name: cumulus-pallet-xcmp-queue
24+
bump: minor
25+
- name: cumulus-primitives-utility
26+
bump: minor
27+
- name: polkadot-runtime-common
28+
bump: minor
29+
- name: pallet-xcm-bridge-hub
30+
bump: minor

0 commit comments

Comments
 (0)