XCM: Tools for uniquely referencing messages (#7234)

* Tools for unique topic references

* Formatting

* Naming

* Repot into routing.rs.

* More things done

* Universal Exporter supports topic-as-reference

* Some tests for the topic routing

* More tests

* Paid bridge tests

* Add message ID to sending events

* Formatting

* fix and integrate into test nets

* Move DenyThenTry and friend from Cumulus

* Append SetTopic rather than prepend

* Docs

* Docs

* Work with new ProcessMessage ID API

* Formatting

* Fix build

* Fixes

* Formatting

* Update xcm/xcm-builder/src/barriers.rs

Co-authored-by: Francisco Aguirre <franciscoaguirreperez@gmail.com>

* Update xcm/xcm-builder/src/routing.rs

Co-authored-by: Francisco Aguirre <franciscoaguirreperez@gmail.com>

* Docs

* Rename message_hash

* Formatting

* ".git/.scripts/commands/fmt/fmt.sh"

* Rename

* Another Rename

* ".git/.scripts/commands/fmt/fmt.sh"

* ".git/.scripts/commands/fmt/fmt.sh"

* Update xcm/xcm-builder/src/routing.rs

Co-authored-by: Keith Yeung <kungfukeith11@gmail.com>

---------

Co-authored-by: Francisco Aguirre <franciscoaguirreperez@gmail.com>
Co-authored-by: command-bot <>
Co-authored-by: Keith Yeung <kungfukeith11@gmail.com>
This commit is contained in:
Gavin Wood
2023-05-25 07:57:32 +01:00
committed by GitHub
parent 28de4f1337
commit 85dfadff2c
29 changed files with 1305 additions and 552 deletions
+152 -124
View File
@@ -40,7 +40,7 @@ use sp_runtime::{
};
use sp_std::{boxed::Box, marker::PhantomData, prelude::*, result::Result, vec};
use xcm::{latest::QueryResponseInfo, prelude::*};
use xcm_executor::traits::{Convert, ConvertOrigin};
use xcm_executor::traits::{Convert, ConvertOrigin, Properties};
use frame_support::{
dispatch::{Dispatchable, GetDispatchInfo},
@@ -272,52 +272,49 @@ pub mod pallet {
#[pallet::generate_deposit(pub(super) fn deposit_event)]
pub enum Event<T: Config> {
/// Execution of an XCM message was attempted.
///
/// \[ outcome \]
Attempted(xcm::latest::Outcome),
Attempted { outcome: xcm::latest::Outcome },
/// A XCM message was sent.
///
/// \[ origin, destination, message \]
Sent(MultiLocation, MultiLocation, Xcm<()>),
Sent {
origin: MultiLocation,
destination: MultiLocation,
message: Xcm<()>,
message_id: XcmHash,
},
/// Query response received which does not match a registered query. This may be because a
/// matching query was never registered, it may be because it is a duplicate response, or
/// because the query timed out.
///
/// \[ origin location, id \]
UnexpectedResponse(MultiLocation, QueryId),
UnexpectedResponse { origin: MultiLocation, query_id: QueryId },
/// Query response has been received and is ready for taking with `take_response`. There is
/// no registered notification call.
///
/// \[ id, response \]
ResponseReady(QueryId, Response),
ResponseReady { query_id: QueryId, response: Response },
/// Query response has been received and query is removed. The registered notification has
/// been dispatched and executed successfully.
///
/// \[ id, pallet index, call index \]
Notified(QueryId, u8, u8),
Notified { query_id: QueryId, pallet_index: u8, call_index: u8 },
/// Query response has been received and query is removed. The registered notification could
/// not be dispatched because the dispatch weight is greater than the maximum weight
/// originally budgeted by this runtime for the query result.
///
/// \[ id, pallet index, call index, actual weight, max budgeted weight \]
NotifyOverweight(QueryId, u8, u8, Weight, Weight),
NotifyOverweight {
query_id: QueryId,
pallet_index: u8,
call_index: u8,
actual_weight: Weight,
max_budgeted_weight: Weight,
},
/// Query response has been received and query is removed. There was a general error with
/// dispatching the notification call.
///
/// \[ id, pallet index, call index \]
NotifyDispatchError(QueryId, u8, u8),
NotifyDispatchError { query_id: QueryId, pallet_index: u8, call_index: u8 },
/// Query response has been received and query is removed. The dispatch was unable to be
/// decoded into a `Call`; this might be due to dispatch function having a signature which
/// is not `(origin, QueryId, Response)`.
///
/// \[ id, pallet index, call index \]
NotifyDecodeFailed(QueryId, u8, u8),
NotifyDecodeFailed { query_id: QueryId, pallet_index: u8, call_index: u8 },
/// Expected query response has been received but the origin location of the response does
/// not match that expected. The query remains registered for a later, valid, response to
/// be received and acted upon.
///
/// \[ origin location, id, expected location \]
InvalidResponder(MultiLocation, QueryId, Option<MultiLocation>),
InvalidResponder {
origin: MultiLocation,
query_id: QueryId,
expected_location: Option<MultiLocation>,
},
/// Expected query response has been received but the expected origin location placed in
/// storage by this runtime previously cannot be decoded. The query remains registered.
///
@@ -325,38 +322,29 @@ pub mod pallet {
/// runtime should be readable prior to query timeout) and dangerous since the possibly
/// valid response will be dropped. Manual governance intervention is probably going to be
/// needed.
///
/// \[ origin location, id \]
InvalidResponderVersion(MultiLocation, QueryId),
InvalidResponderVersion { origin: MultiLocation, query_id: QueryId },
/// Received query response has been read and removed.
///
/// \[ id \]
ResponseTaken(QueryId),
ResponseTaken { query_id: QueryId },
/// Some assets have been placed in an asset trap.
///
/// \[ hash, origin, assets \]
AssetsTrapped(H256, MultiLocation, VersionedMultiAssets),
AssetsTrapped { hash: H256, origin: MultiLocation, assets: VersionedMultiAssets },
/// An XCM version change notification message has been attempted to be sent.
///
/// The cost of sending it (borne by the chain) is included.
///
/// \[ destination, result, cost \]
VersionChangeNotified(MultiLocation, XcmVersion, MultiAssets),
VersionChangeNotified {
destination: MultiLocation,
result: XcmVersion,
cost: MultiAssets,
message_id: XcmHash,
},
/// The supported version of a location has been changed. This might be through an
/// automatic notification or a manual intervention.
///
/// \[ location, XCM version \]
SupportedVersionChanged(MultiLocation, XcmVersion),
SupportedVersionChanged { location: MultiLocation, version: XcmVersion },
/// A given location which had a version change subscription was dropped owing to an error
/// sending the notification to it.
///
/// \[ location, query ID, error \]
NotifyTargetSendFail(MultiLocation, QueryId, XcmError),
NotifyTargetSendFail { location: MultiLocation, query_id: QueryId, error: XcmError },
/// A given location which had a version change subscription was dropped owing to an error
/// migrating the location to our new XCM format.
///
/// \[ location, query ID \]
NotifyTargetMigrationFail(VersionedMultiLocation, QueryId),
NotifyTargetMigrationFail { location: VersionedMultiLocation, query_id: QueryId },
/// Expected query response has been received but the expected querier location placed in
/// storage by this runtime previously cannot be decoded. The query remains registered.
///
@@ -364,36 +352,35 @@ pub mod pallet {
/// runtime should be readable prior to query timeout) and dangerous since the possibly
/// valid response will be dropped. Manual governance intervention is probably going to be
/// needed.
///
/// \[ origin location, id \]
InvalidQuerierVersion(MultiLocation, QueryId),
InvalidQuerierVersion { origin: MultiLocation, query_id: QueryId },
/// Expected query response has been received but the querier location of the response does
/// not match the expected. The query remains registered for a later, valid, response to
/// be received and acted upon.
///
/// \[ origin location, id, expected querier, maybe actual querier \]
InvalidQuerier(MultiLocation, QueryId, MultiLocation, Option<MultiLocation>),
InvalidQuerier {
origin: MultiLocation,
query_id: QueryId,
expected_querier: MultiLocation,
maybe_actual_querier: Option<MultiLocation>,
},
/// A remote has requested XCM version change notification from us and we have honored it.
/// A version information message is sent to them and its cost is included.
///
/// \[ destination location, cost \]
VersionNotifyStarted(MultiLocation, MultiAssets),
/// We have requested that a remote chain sends us XCM version change notifications.
///
/// \[ destination location, cost \]
VersionNotifyRequested(MultiLocation, MultiAssets),
VersionNotifyStarted { destination: MultiLocation, cost: MultiAssets, message_id: XcmHash },
/// We have requested that a remote chain send us XCM version change notifications.
VersionNotifyRequested {
destination: MultiLocation,
cost: MultiAssets,
message_id: XcmHash,
},
/// We have requested that a remote chain stops sending us XCM version change notifications.
///
/// \[ destination location, cost \]
VersionNotifyUnrequested(MultiLocation, MultiAssets),
VersionNotifyUnrequested {
destination: MultiLocation,
cost: MultiAssets,
message_id: XcmHash,
},
/// Fees were paid from a location for an operation (often for using `SendXcm`).
///
/// \[ paying location, fees \]
FeesPaid(MultiLocation, MultiAssets),
FeesPaid { paying: MultiLocation, fees: MultiAssets },
/// Some assets have been claimed from an asset trap
///
/// \[ hash, origin, assets \]
AssetsClaimed(H256, MultiLocation, VersionedMultiAssets),
AssetsClaimed { hash: H256, origin: MultiLocation, assets: VersionedMultiAssets },
}
#[pallet::origin]
@@ -793,8 +780,10 @@ pub mod pallet {
let dest = MultiLocation::try_from(*dest).map_err(|()| Error::<T>::BadVersion)?;
let message: Xcm<()> = (*message).try_into().map_err(|()| Error::<T>::BadVersion)?;
Self::send_xcm(interior, dest, message.clone()).map_err(Error::<T>::from)?;
Self::deposit_event(Event::Sent(origin_location, dest, message));
let message_id =
Self::send_xcm(interior, dest, message.clone()).map_err(Error::<T>::from)?;
let e = Event::Sent { origin: origin_location, destination: dest, message, message_id };
Self::deposit_event(e);
Ok(())
}
@@ -927,7 +916,7 @@ pub mod pallet {
);
let result =
Ok(Some(outcome.weight_used().saturating_add(T::WeightInfo::execute())).into());
Self::deposit_event(Event::Attempted(outcome));
Self::deposit_event(Event::Attempted { outcome });
result
}
@@ -942,16 +931,16 @@ pub mod pallet {
pub fn force_xcm_version(
origin: OriginFor<T>,
location: Box<MultiLocation>,
xcm_version: XcmVersion,
version: XcmVersion,
) -> DispatchResult {
T::AdminOrigin::ensure_origin(origin)?;
let location = *location;
SupportedVersion::<T>::insert(
XCM_VERSION,
LatestVersionedMultiLocation(&location),
xcm_version,
version,
);
Self::deposit_event(Event::SupportedVersionChanged(location, xcm_version));
Self::deposit_event(Event::SupportedVersionChanged { location, version });
Ok(())
}
@@ -1195,7 +1184,7 @@ impl<T: Config> Pallet<T> {
let hash = message.using_encoded(sp_io::hashing::blake2_256);
let outcome =
T::XcmExecutor::execute_xcm_in_credit(origin_location, message, hash, weight, weight);
Self::deposit_event(Event::Attempted(outcome));
Self::deposit_event(Event::Attempted { outcome });
Ok(())
}
@@ -1256,7 +1245,7 @@ impl<T: Config> Pallet<T> {
let hash = message.using_encoded(sp_io::hashing::blake2_256);
let outcome =
T::XcmExecutor::execute_xcm_in_credit(origin_location, message, hash, weight, weight);
Self::deposit_event(Event::Attempted(outcome));
Self::deposit_event(Event::Attempted { outcome });
Ok(())
}
@@ -1331,14 +1320,19 @@ impl<T: Config> Pallet<T> {
let message =
Xcm(vec![QueryResponse { query_id, response, max_weight, querier: None }]);
let event = match send_xcm::<T::XcmRouter>(new_key, message) {
Ok((_hash, cost)) => {
Ok((message_id, cost)) => {
let value = (query_id, max_weight, xcm_version);
VersionNotifyTargets::<T>::insert(XCM_VERSION, key, value);
Event::VersionChangeNotified(new_key, xcm_version, cost)
Event::VersionChangeNotified {
destination: new_key,
result: xcm_version,
cost,
message_id,
}
},
Err(e) => {
VersionNotifyTargets::<T>::remove(XCM_VERSION, key);
Event::NotifyTargetSendFail(new_key, query_id, e.into())
Event::NotifyTargetSendFail { location: new_key, query_id, error: e.into() }
},
};
Self::deposit_event(event);
@@ -1357,7 +1351,10 @@ impl<T: Config> Pallet<T> {
let new_key = match MultiLocation::try_from(old_key.clone()) {
Ok(k) => k,
Err(()) => {
Self::deposit_event(Event::NotifyTargetMigrationFail(old_key, value.0));
Self::deposit_event(Event::NotifyTargetMigrationFail {
location: old_key,
query_id: value.0,
});
weight_used.saturating_accrue(vnt_migrate_fail_weight);
if weight_used.any_gte(weight_cutoff) {
return (weight_used, Some(stage))
@@ -1380,15 +1377,24 @@ impl<T: Config> Pallet<T> {
querier: None,
}]);
let event = match send_xcm::<T::XcmRouter>(new_key, message) {
Ok((_hash, cost)) => {
Ok((message_id, cost)) => {
VersionNotifyTargets::<T>::insert(
XCM_VERSION,
versioned_key,
(query_id, max_weight, xcm_version),
);
Event::VersionChangeNotified(new_key, xcm_version, cost)
Event::VersionChangeNotified {
destination: new_key,
result: xcm_version,
cost,
message_id,
}
},
Err(e) => Event::NotifyTargetSendFail {
location: new_key,
query_id,
error: e.into(),
},
Err(e) => Event::NotifyTargetSendFail(new_key, query_id, e.into()),
};
Self::deposit_event(event);
weight_used.saturating_accrue(vnt_notify_migrate_weight);
@@ -1415,8 +1421,8 @@ impl<T: Config> Pallet<T> {
});
// TODO #3735: Correct weight.
let instruction = SubscribeVersion { query_id, max_response_weight: Weight::zero() };
let (_hash, cost) = send_xcm::<T::XcmRouter>(dest, Xcm(vec![instruction]))?;
Self::deposit_event(Event::VersionNotifyRequested(dest, cost));
let (message_id, cost) = send_xcm::<T::XcmRouter>(dest, Xcm(vec![instruction]))?;
Self::deposit_event(Event::VersionNotifyRequested { destination: dest, cost, message_id });
VersionNotifiers::<T>::insert(XCM_VERSION, &versioned_dest, query_id);
let query_status =
QueryStatus::VersionNotifier { origin: versioned_dest, is_active: false };
@@ -1430,8 +1436,12 @@ impl<T: Config> Pallet<T> {
let versioned_dest = LatestVersionedMultiLocation(&dest);
let query_id = VersionNotifiers::<T>::take(XCM_VERSION, versioned_dest)
.ok_or(XcmError::InvalidLocation)?;
let (_hash, cost) = send_xcm::<T::XcmRouter>(dest, Xcm(vec![UnsubscribeVersion]))?;
Self::deposit_event(Event::VersionNotifyUnrequested(dest, cost));
let (message_id, cost) = send_xcm::<T::XcmRouter>(dest, Xcm(vec![UnsubscribeVersion]))?;
Self::deposit_event(Event::VersionNotifyUnrequested {
destination: dest,
cost,
message_id,
});
Queries::<T>::remove(query_id);
Ok(())
}
@@ -1589,7 +1599,7 @@ impl<T: Config> Pallet<T> {
if let Some(QueryStatus::Ready { response, at }) = Queries::<T>::get(query_id) {
let response = response.try_into().ok()?;
Queries::<T>::remove(query_id);
Self::deposit_event(Event::ResponseTaken(query_id));
Self::deposit_event(Event::ResponseTaken { query_id });
Some((response, at))
} else {
None
@@ -1623,7 +1633,7 @@ impl<T: Config> Pallet<T> {
fn charge_fees(location: MultiLocation, assets: MultiAssets) -> DispatchResult {
T::XcmExecutor::charge_fees(location, assets.clone())
.map_err(|_| Error::<T>::FeesNotMet)?;
Self::deposit_event(Event::FeesPaid(location, assets));
Self::deposit_event(Event::FeesPaid { paying: location, fees: assets });
Ok(())
}
}
@@ -1861,8 +1871,12 @@ impl<T: Config> VersionChangeNotifier for Pallet<T> {
let xcm_version = T::AdvertisedXcmVersion::get();
let response = Response::Version(xcm_version);
let instruction = QueryResponse { query_id, response, max_weight, querier: None };
let (_hash, cost) = send_xcm::<T::XcmRouter>(*dest, Xcm(vec![instruction]))?;
Self::deposit_event(Event::<T>::VersionNotifyStarted(*dest, cost));
let (message_id, cost) = send_xcm::<T::XcmRouter>(*dest, Xcm(vec![instruction]))?;
Self::deposit_event(Event::<T>::VersionNotifyStarted {
destination: *dest,
cost,
message_id,
});
let value = (query_id, max_weight, xcm_version);
VersionNotifyTargets::<T>::insert(XCM_VERSION, versioned_dest, value);
@@ -1891,7 +1905,7 @@ impl<T: Config> DropAssets for Pallet<T> {
let versioned = VersionedMultiAssets::from(MultiAssets::from(assets));
let hash = BlakeTwo256::hash_of(&(&origin, &versioned));
AssetTraps::<T>::mutate(hash, |n| *n += 1);
Self::deposit_event(Event::AssetsTrapped(hash, *origin, versioned));
Self::deposit_event(Event::AssetsTrapped { hash, origin: *origin, assets: versioned });
// TODO #3735: Put the real weight in there.
Weight::zero()
}
@@ -1920,7 +1934,7 @@ impl<T: Config> ClaimAssets for Pallet<T> {
1 => AssetTraps::<T>::remove(hash),
n => AssetTraps::<T>::insert(hash, n - 1),
}
Self::deposit_event(Event::AssetsClaimed(hash, *origin, versioned));
Self::deposit_event(Event::AssetsClaimed { hash, origin: *origin, assets: versioned });
return true
}
}
@@ -1953,19 +1967,28 @@ impl<T: Config> OnResponse for Pallet<T> {
max_weight: Weight,
_context: &XcmContext,
) -> Weight {
let origin = *origin;
match (response, Queries::<T>::get(query_id)) {
(
Response::Version(v),
Some(QueryStatus::VersionNotifier { origin: expected_origin, is_active }),
) => {
let origin: MultiLocation = match expected_origin.try_into() {
Ok(o) if &o == origin => o,
Ok(o) if o == origin => o,
Ok(o) => {
Self::deposit_event(Event::InvalidResponder(*origin, query_id, Some(o)));
Self::deposit_event(Event::InvalidResponder {
origin,
query_id,
expected_location: Some(o),
});
return Weight::zero()
},
_ => {
Self::deposit_event(Event::InvalidResponder(*origin, query_id, None));
Self::deposit_event(Event::InvalidResponder {
origin,
query_id,
expected_location: None,
});
// TODO #3735: Correct weight for this.
return Weight::zero()
},
@@ -1983,7 +2006,10 @@ impl<T: Config> OnResponse for Pallet<T> {
LatestVersionedMultiLocation(&origin),
v,
);
Self::deposit_event(Event::SupportedVersionChanged(origin, v));
Self::deposit_event(Event::SupportedVersionChanged {
location: origin,
version: v,
});
Weight::zero()
},
(
@@ -1994,33 +2020,33 @@ impl<T: Config> OnResponse for Pallet<T> {
let match_querier = match MultiLocation::try_from(match_querier) {
Ok(mq) => mq,
Err(_) => {
Self::deposit_event(Event::InvalidQuerierVersion(*origin, query_id));
Self::deposit_event(Event::InvalidQuerierVersion { origin, query_id });
return Weight::zero()
},
};
if querier.map_or(true, |q| q != &match_querier) {
Self::deposit_event(Event::InvalidQuerier(
*origin,
Self::deposit_event(Event::InvalidQuerier {
origin,
query_id,
match_querier,
querier.cloned(),
));
expected_querier: match_querier,
maybe_actual_querier: querier.cloned(),
});
return Weight::zero()
}
}
let responder = match MultiLocation::try_from(responder) {
Ok(r) => r,
Err(_) => {
Self::deposit_event(Event::InvalidResponderVersion(*origin, query_id));
Self::deposit_event(Event::InvalidResponderVersion { origin, query_id });
return Weight::zero()
},
};
if origin != &responder {
Self::deposit_event(Event::InvalidResponder(
*origin,
if origin != responder {
Self::deposit_event(Event::InvalidResponder {
origin,
query_id,
Some(responder),
));
expected_location: Some(responder),
});
return Weight::zero()
}
return match maybe_notify {
@@ -2035,29 +2061,29 @@ impl<T: Config> OnResponse for Pallet<T> {
Queries::<T>::remove(query_id);
let weight = call.get_dispatch_info().weight;
if weight.any_gt(max_weight) {
let e = Event::NotifyOverweight(
let e = Event::NotifyOverweight {
query_id,
pallet_index,
call_index,
weight,
max_weight,
);
actual_weight: weight,
max_budgeted_weight: max_weight,
};
Self::deposit_event(e);
return Weight::zero()
}
let dispatch_origin = Origin::Response(*origin).into();
let dispatch_origin = Origin::Response(origin).into();
match call.dispatch(dispatch_origin) {
Ok(post_info) => {
let e = Event::Notified(query_id, pallet_index, call_index);
let e = Event::Notified { query_id, pallet_index, call_index };
Self::deposit_event(e);
post_info.actual_weight
},
Err(error_and_info) => {
let e = Event::NotifyDispatchError(
let e = Event::NotifyDispatchError {
query_id,
pallet_index,
call_index,
);
};
Self::deposit_event(e);
// Not much to do with the result as it is. It's up to the parachain to ensure that the
// message makes sense.
@@ -2066,13 +2092,14 @@ impl<T: Config> OnResponse for Pallet<T> {
}
.unwrap_or(weight)
} else {
let e = Event::NotifyDecodeFailed(query_id, pallet_index, call_index);
let e =
Event::NotifyDecodeFailed { query_id, pallet_index, call_index };
Self::deposit_event(e);
Weight::zero()
}
},
None => {
let e = Event::ResponseReady(query_id, response.clone());
let e = Event::ResponseReady { query_id, response: response.clone() };
Self::deposit_event(e);
let at = frame_system::Pallet::<T>::current_block_number();
let response = response.into();
@@ -2082,7 +2109,8 @@ impl<T: Config> OnResponse for Pallet<T> {
}
},
_ => {
Self::deposit_event(Event::UnexpectedResponse(*origin, query_id));
let e = Event::UnexpectedResponse { origin, query_id };
Self::deposit_event(e);
Weight::zero()
},
}
@@ -2094,7 +2122,7 @@ impl<T: Config> CheckSuspension for Pallet<T> {
_origin: &MultiLocation,
_instructions: &mut [Instruction<Call>],
_max_weight: Weight,
_weight_credit: &mut Weight,
_properties: &mut Properties,
) -> bool {
XcmExecutionSuspended::<T>::get()
}
+60 -52
View File
@@ -27,7 +27,10 @@ use polkadot_parachain::primitives::Id as ParaId;
use sp_runtime::traits::{AccountIdConversion, BlakeTwo256, Hash};
use xcm::{latest::QueryResponseInfo, prelude::*};
use xcm_builder::AllowKnownQueryResponses;
use xcm_executor::{traits::ShouldExecute, XcmExecutor};
use xcm_executor::{
traits::{Properties, ShouldExecute},
XcmExecutor,
};
const ALICE: AccountId = AccountId::new([0u8; 32]);
const BOB: AccountId = AccountId::new([1u8; 32]);
@@ -101,7 +104,11 @@ fn report_outcome_notify_works() {
0,
Response::ExecutionResult(None),
)),
RuntimeEvent::XcmPallet(crate::Event::Notified(0, 4, 2)),
RuntimeEvent::XcmPallet(crate::Event::Notified {
query_id: 0,
pallet_index: 4,
call_index: 2
}),
]
);
assert_eq!(crate::Queries::<Test>::iter().collect::<Vec<_>>(), vec![]);
@@ -157,10 +164,10 @@ fn report_outcome_works() {
assert_eq!(r, Outcome::Complete(Weight::from_parts(1_000, 1_000)));
assert_eq!(
last_event(),
RuntimeEvent::XcmPallet(crate::Event::ResponseReady(
0,
Response::ExecutionResult(None),
))
RuntimeEvent::XcmPallet(crate::Event::ResponseReady {
query_id: 0,
response: Response::ExecutionResult(None),
})
);
let response = Some((Response::ExecutionResult(None), 1));
@@ -206,12 +213,12 @@ fn custom_querier_works() {
assert_eq!(r, Outcome::Complete(Weight::from_parts(1_000, 1_000)));
assert_eq!(
last_event(),
RuntimeEvent::XcmPallet(crate::Event::InvalidQuerier(
AccountId32 { network: None, id: ALICE.into() }.into(),
0,
querier.clone(),
None,
)),
RuntimeEvent::XcmPallet(crate::Event::InvalidQuerier {
origin: AccountId32 { network: None, id: ALICE.into() }.into(),
query_id: 0,
expected_querier: querier.clone(),
maybe_actual_querier: None,
}),
);
// Supplying the wrong querier will also fail
@@ -232,12 +239,12 @@ fn custom_querier_works() {
assert_eq!(r, Outcome::Complete(Weight::from_parts(1_000, 1_000)));
assert_eq!(
last_event(),
RuntimeEvent::XcmPallet(crate::Event::InvalidQuerier(
AccountId32 { network: None, id: ALICE.into() }.into(),
0,
querier.clone(),
Some(MultiLocation::here()),
)),
RuntimeEvent::XcmPallet(crate::Event::InvalidQuerier {
origin: AccountId32 { network: None, id: ALICE.into() }.into(),
query_id: 0,
expected_querier: querier.clone(),
maybe_actual_querier: Some(MultiLocation::here()),
}),
);
// Multiple failures should not have changed the query state
@@ -257,10 +264,10 @@ fn custom_querier_works() {
assert_eq!(r, Outcome::Complete(Weight::from_parts(1_000, 1_000)));
assert_eq!(
last_event(),
RuntimeEvent::XcmPallet(crate::Event::ResponseReady(
0,
Response::ExecutionResult(None),
))
RuntimeEvent::XcmPallet(crate::Event::ResponseReady {
query_id: 0,
response: Response::ExecutionResult(None),
})
);
let response = Some((Response::ExecutionResult(None), 1));
@@ -285,6 +292,7 @@ fn send_works() {
buy_execution((Parent, SEND_AMOUNT)),
DepositAsset { assets: AllCounted(1).into(), beneficiary: sender.clone() },
]);
let versioned_dest = Box::new(RelayLocation::get().into());
let versioned_message = Box::new(VersionedXcm::from(message.clone()));
assert_ok!(XcmPallet::send(
@@ -292,19 +300,20 @@ fn send_works() {
versioned_dest,
versioned_message
));
assert_eq!(
sent_xcm(),
vec![(
Here.into(),
Xcm(Some(DescendOrigin(sender.clone().try_into().unwrap()))
.into_iter()
.chain(message.0.clone().into_iter())
.collect())
)],
);
let sent_message = Xcm(Some(DescendOrigin(sender.clone().try_into().unwrap()))
.into_iter()
.chain(message.0.clone().into_iter())
.collect());
let id = fake_message_hash(&sent_message);
assert_eq!(sent_xcm(), vec![(Here.into(), sent_message)]);
assert_eq!(
last_event(),
RuntimeEvent::XcmPallet(crate::Event::Sent(sender, RelayLocation::get(), message))
RuntimeEvent::XcmPallet(crate::Event::Sent {
origin: sender,
destination: RelayLocation::get(),
message,
message_id: id,
})
);
});
}
@@ -376,7 +385,7 @@ fn teleport_assets_works() {
let _check_v2_ok: xcm::v2::Xcm<()> = versioned_sent.try_into().unwrap();
assert_eq!(
last_event(),
RuntimeEvent::XcmPallet(crate::Event::Attempted(Outcome::Complete(weight)))
RuntimeEvent::XcmPallet(crate::Event::Attempted { outcome: Outcome::Complete(weight) })
);
});
}
@@ -420,7 +429,7 @@ fn limited_teleport_assets_works() {
let _check_v2_ok: xcm::v2::Xcm<()> = versioned_sent.try_into().unwrap();
assert_eq!(
last_event(),
RuntimeEvent::XcmPallet(crate::Event::Attempted(Outcome::Complete(weight)))
RuntimeEvent::XcmPallet(crate::Event::Attempted { outcome: Outcome::Complete(weight) })
);
});
}
@@ -462,7 +471,7 @@ fn unlimited_teleport_assets_works() {
);
assert_eq!(
last_event(),
RuntimeEvent::XcmPallet(crate::Event::Attempted(Outcome::Complete(weight)))
RuntimeEvent::XcmPallet(crate::Event::Attempted { outcome: Outcome::Complete(weight) })
);
});
}
@@ -509,7 +518,7 @@ fn reserve_transfer_assets_works() {
let _check_v2_ok: xcm::v2::Xcm<()> = versioned_sent.try_into().unwrap();
assert_eq!(
last_event(),
RuntimeEvent::XcmPallet(crate::Event::Attempted(Outcome::Complete(weight)))
RuntimeEvent::XcmPallet(crate::Event::Attempted { outcome: Outcome::Complete(weight) })
);
});
}
@@ -557,7 +566,7 @@ fn limited_reserve_transfer_assets_works() {
let _check_v2_ok: xcm::v2::Xcm<()> = versioned_sent.try_into().unwrap();
assert_eq!(
last_event(),
RuntimeEvent::XcmPallet(crate::Event::Attempted(Outcome::Complete(weight)))
RuntimeEvent::XcmPallet(crate::Event::Attempted { outcome: Outcome::Complete(weight) })
);
});
}
@@ -603,7 +612,7 @@ fn unlimited_reserve_transfer_assets_works() {
);
assert_eq!(
last_event(),
RuntimeEvent::XcmPallet(crate::Event::Attempted(Outcome::Complete(weight)))
RuntimeEvent::XcmPallet(crate::Event::Attempted { outcome: Outcome::Complete(weight) })
);
});
}
@@ -635,7 +644,7 @@ fn execute_withdraw_to_deposit_works() {
assert_eq!(Balances::total_balance(&BOB), SEND_AMOUNT);
assert_eq!(
last_event(),
RuntimeEvent::XcmPallet(crate::Event::Attempted(Outcome::Complete(weight)))
RuntimeEvent::XcmPallet(crate::Event::Attempted { outcome: Outcome::Complete(weight) })
);
});
}
@@ -670,10 +679,14 @@ fn trapped_assets_can_be_claimed() {
assert_eq!(
last_events(2),
vec![
RuntimeEvent::XcmPallet(crate::Event::AssetsTrapped(hash.clone(), source, vma)),
RuntimeEvent::XcmPallet(crate::Event::Attempted(Outcome::Complete(
BaseXcmWeight::get() * 5
)))
RuntimeEvent::XcmPallet(crate::Event::AssetsTrapped {
hash: hash.clone(),
origin: source,
assets: vma
}),
RuntimeEvent::XcmPallet(crate::Event::Attempted {
outcome: Outcome::Complete(BaseXcmWeight::get() * 5)
}),
]
);
assert_eq!(Balances::total_balance(&ALICE), INITIAL_BALANCE - SEND_AMOUNT);
@@ -707,13 +720,8 @@ fn trapped_assets_can_be_claimed() {
]))),
weight
));
assert_eq!(
last_event(),
RuntimeEvent::XcmPallet(crate::Event::Attempted(Outcome::Incomplete(
BaseXcmWeight::get(),
XcmError::UnknownClaim
)))
);
let outcome = Outcome::Incomplete(BaseXcmWeight::get(), XcmError::UnknownClaim);
assert_eq!(last_event(), RuntimeEvent::XcmPallet(crate::Event::Attempted { outcome }));
});
}
@@ -768,7 +776,7 @@ fn basic_subscription_works() {
&remote,
message.inner_mut(),
weight,
&mut Weight::zero(),
&mut Properties { weight_credit: Weight::zero(), message_id: None },
));
});
}