Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions xcm/pallet-xcm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1340,7 +1340,7 @@ impl<T: Config> Pallet<T> {
let responder = responder.into();
let destination = T::UniversalLocation::get()
.invert_target(&responder)
.map_err(|()| XcmError::MultiLocationNotInvertible)?;
.map_err(|()| XcmError::LocationNotInvertible)?;
let query_id = Self::new_query(responder, timeout, Here);
let response_info = QueryResponseInfo { destination, query_id, max_weight: 0 };
let report_error = Xcm(vec![ReportError(response_info)]);
Expand Down Expand Up @@ -1379,7 +1379,7 @@ impl<T: Config> Pallet<T> {
let responder = responder.into();
let destination = T::UniversalLocation::get()
.invert_target(&responder)
.map_err(|()| XcmError::MultiLocationNotInvertible)?;
.map_err(|()| XcmError::LocationNotInvertible)?;
let notify: <T as Config>::Call = notify.into();
let max_weight = notify.get_dispatch_info().weight;
let query_id = Self::new_notify_query(responder, notify, timeout, Here);
Expand Down
4 changes: 2 additions & 2 deletions xcm/src/v2/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,8 @@ impl TryFrom<NewError> for Error {
Unimplemented => Self::Unimplemented,
UntrustedReserveLocation => Self::UntrustedReserveLocation,
UntrustedTeleportLocation => Self::UntrustedTeleportLocation,
MultiLocationFull => Self::MultiLocationFull,
MultiLocationNotInvertible => Self::MultiLocationNotInvertible,
LocationFull => Self::MultiLocationFull,
LocationNotInvertible => Self::MultiLocationNotInvertible,
BadOrigin => Self::BadOrigin,
InvalidLocation => Self::InvalidLocation,
AssetNotFound => Self::AssetNotFound,
Expand Down
30 changes: 30 additions & 0 deletions xcm/src/v3/junctions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,36 @@ impl Junctions {
}
}

/// Extract the network ID and the interior consensus location, treating this value as a
/// universal location.
///
/// This will return an `Err` if the first item is not a `GlobalConsensus`, which would indicate
/// that this value is not a universal location.
pub fn split_global(self) -> Result<(NetworkId, Junctions), ()> {
match self.clone().split_first() {
(location, Some(Junction::GlobalConsensus(network))) => Ok((network, location)),
_ => return Err(()),
}
}

/// Treat `self` as a universal location and the context of `relative`, returning the universal
/// location of relative.
///
/// This will return an error if `relative` has as many (or more) parents than there are
/// junctions in `self`, implying that relative refers into a different global consensus.
pub fn within_global(mut self, relative: MultiLocation) -> Result<Self, ()> {
if self.len() <= relative.parents as usize {
return Err(())
}
for _ in 0..relative.parents {
self.take_last();
}
for j in relative.interior {
self.push(j).map_err(|_| ())?;
}
Ok(self)
}

/// Consumes `self` and returns how `viewer` would address it locally.
pub fn relative_to(mut self, viewer: &Junctions) -> MultiLocation {
let mut i = 0;
Expand Down
11 changes: 7 additions & 4 deletions xcm/src/v3/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,10 @@ pub enum Error {
UntrustedTeleportLocation,
/// `MultiLocation` value too large to descend further.
#[codec(index = 4)]
MultiLocationFull,
LocationFull,
/// `MultiLocation` value ascend more parents than known ancestors of local location.
#[codec(index = 5)]
MultiLocationNotInvertible,
LocationNotInvertible,
/// The Origin Register does not contain a valid value for instruction.
#[codec(index = 6)]
BadOrigin,
Expand Down Expand Up @@ -126,6 +126,9 @@ pub enum Error {
/// The state was not in a condition where the operation was valid to make.
#[codec(index = 32)]
NoPermission,
/// The universal location of the local consensus is improper.
#[codec(index = 33)]
Unanchored,

// Errors that happen prior to instructions being executed. These fall outside of the XCM spec.
/// XCM version not able to be handled.
Expand Down Expand Up @@ -161,8 +164,8 @@ impl TryFrom<OldError> for Error {
Unimplemented => Self::Unimplemented,
UntrustedReserveLocation => Self::UntrustedReserveLocation,
UntrustedTeleportLocation => Self::UntrustedTeleportLocation,
MultiLocationFull => Self::MultiLocationFull,
MultiLocationNotInvertible => Self::MultiLocationNotInvertible,
MultiLocationFull => Self::LocationFull,
MultiLocationNotInvertible => Self::LocationNotInvertible,
BadOrigin => Self::BadOrigin,
InvalidLocation => Self::InvalidLocation,
AssetNotFound => Self::AssetNotFound,
Expand Down
6 changes: 4 additions & 2 deletions xcm/xcm-builder/src/tests/bridging/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,19 +89,21 @@ struct UnpaidExecutingRouter<Local, Remote, RemoteExporter>(
fn price<RemoteExporter: ExportXcm>(
n: NetworkId,
c: u32,
s: &InteriorMultiLocation,
d: &InteriorMultiLocation,
m: &Xcm<()>,
) -> Result<MultiAssets, SendError> {
Ok(validate_export::<RemoteExporter>(n, c, d.clone(), m.clone())?.1)
Ok(validate_export::<RemoteExporter>(n, c, s.clone(), d.clone(), m.clone())?.1)
}

fn deliver<RemoteExporter: ExportXcm>(
n: NetworkId,
c: u32,
s: InteriorMultiLocation,
d: InteriorMultiLocation,
m: Xcm<()>,
) -> Result<XcmHash, SendError> {
export_xcm::<RemoteExporter>(n, c, d, m).map(|(hash, _)| hash)
export_xcm::<RemoteExporter>(n, c, s, d, m).map(|(hash, _)| hash)
}

impl<Local: Get<Junctions>, Remote: Get<Junctions>, RemoteExporter: ExportXcm> SendXcm
Expand Down
60 changes: 45 additions & 15 deletions xcm/xcm-builder/src/tests/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,10 +107,24 @@ impl GetDispatchInfo for TestCall {

thread_local! {
pub static SENT_XCM: RefCell<Vec<(MultiLocation, Xcm<()>, XcmHash)>> = RefCell::new(Vec::new());
pub static EXPORTED_XCM: RefCell<Vec<(NetworkId, u32, InteriorMultiLocation, Xcm<()>, XcmHash)>> = RefCell::new(Vec::new());
pub static EXPORTED_XCM: RefCell<
Vec<(NetworkId, u32, InteriorMultiLocation, InteriorMultiLocation, Xcm<()>, XcmHash)>
> = RefCell::new(Vec::new());
pub static EXPORTER_OVERRIDE: RefCell<Option<(
fn(NetworkId, u32, &InteriorMultiLocation, &Xcm<()>) -> Result<MultiAssets, SendError>,
fn(NetworkId, u32, InteriorMultiLocation, Xcm<()>) -> Result<XcmHash, SendError>,
fn(
NetworkId,
u32,
&InteriorMultiLocation,
&InteriorMultiLocation,
&Xcm<()>,
) -> Result<MultiAssets, SendError>,
fn(
NetworkId,
u32,
InteriorMultiLocation,
InteriorMultiLocation,
Xcm<()>,
) -> Result<XcmHash, SendError>,
)>> = RefCell::new(None);
pub static SEND_PRICE: RefCell<MultiAssets> = RefCell::new(MultiAssets::new());
}
Expand All @@ -120,12 +134,25 @@ pub fn sent_xcm() -> Vec<(MultiLocation, opaque::Xcm, XcmHash)> {
pub fn set_send_price(p: impl Into<MultiAsset>) {
SEND_PRICE.with(|l| l.replace(p.into().into()));
}
pub fn exported_xcm() -> Vec<(NetworkId, u32, InteriorMultiLocation, opaque::Xcm, XcmHash)> {
pub fn exported_xcm(
) -> Vec<(NetworkId, u32, InteriorMultiLocation, InteriorMultiLocation, opaque::Xcm, XcmHash)> {
EXPORTED_XCM.with(|q| (*q.borrow()).clone())
}
pub fn set_exporter_override(
price: fn(NetworkId, u32, &InteriorMultiLocation, &Xcm<()>) -> Result<MultiAssets, SendError>,
deliver: fn(NetworkId, u32, InteriorMultiLocation, Xcm<()>) -> Result<XcmHash, SendError>,
price: fn(
NetworkId,
u32,
&InteriorMultiLocation,
&InteriorMultiLocation,
&Xcm<()>,
) -> Result<MultiAssets, SendError>,
deliver: fn(
NetworkId,
u32,
InteriorMultiLocation,
InteriorMultiLocation,
Xcm<()>,
) -> Result<XcmHash, SendError>,
) {
EXPORTER_OVERRIDE.with(|x| x.replace(Some((price, deliver))));
}
Expand Down Expand Up @@ -153,40 +180,43 @@ impl SendXcm for TestMessageSender {
}
pub struct TestMessageExporter;
impl ExportXcm for TestMessageExporter {
type Ticket = (NetworkId, u32, InteriorMultiLocation, Xcm<()>, XcmHash);
type Ticket = (NetworkId, u32, InteriorMultiLocation, InteriorMultiLocation, Xcm<()>, XcmHash);
fn validate(
network: NetworkId,
channel: u32,
uni_src: &mut Option<InteriorMultiLocation>,
dest: &mut Option<InteriorMultiLocation>,
msg: &mut Option<Xcm<()>>,
) -> SendResult<(NetworkId, u32, InteriorMultiLocation, Xcm<()>, XcmHash)> {
let (d, m) = (dest.take().unwrap(), msg.take().unwrap());
) -> SendResult<(NetworkId, u32, InteriorMultiLocation, InteriorMultiLocation, Xcm<()>, XcmHash)>
{
let (s, d, m) = (uni_src.take().unwrap(), dest.take().unwrap(), msg.take().unwrap());
let r: Result<MultiAssets, SendError> = EXPORTER_OVERRIDE.with(|e| {
if let Some((ref f, _)) = &*e.borrow() {
f(network, channel, &d, &m)
f(network, channel, &s, &d, &m)
} else {
Ok(MultiAssets::new())
}
});
let h = fake_message_hash(&m);
match r {
Ok(price) => Ok(((network, channel, d, m, h), price)),
Ok(price) => Ok(((network, channel, s, d, m, h), price)),
Err(e) => {
*uni_src = Some(s);
*dest = Some(d);
*msg = Some(m);
Err(e)
},
}
}
fn deliver(
tuple: (NetworkId, u32, InteriorMultiLocation, Xcm<()>, XcmHash),
tuple: (NetworkId, u32, InteriorMultiLocation, InteriorMultiLocation, Xcm<()>, XcmHash),
) -> Result<XcmHash, SendError> {
EXPORTER_OVERRIDE.with(|e| {
if let Some((_, ref f)) = &*e.borrow() {
let (network, channel, dest, msg, _hash) = tuple;
f(network, channel, dest, msg)
let (network, channel, uni_src, dest, msg, _hash) = tuple;
f(network, channel, uni_src, dest, msg)
} else {
let hash = tuple.4;
let hash = tuple.5;
EXPORTED_XCM.with(|q| q.borrow_mut().push(tuple));
Ok(hash)
}
Expand Down
6 changes: 5 additions & 1 deletion xcm/xcm-builder/src/tests/origins.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,5 +71,9 @@ fn export_message_should_work() {
let hash = fake_message_hash(&message);
let r = XcmExecutor::<TestConfig>::execute_xcm(Parachain(1), message, hash, 50);
assert_eq!(r, Outcome::Complete(10));
assert_eq!(exported_xcm(), vec![(Polkadot, 403611790, Here, expected_message, expected_hash)]);
let uni_src = (ByGenesis([0; 32]), Parachain(42), Parachain(1)).into();
assert_eq!(
exported_xcm(),
vec![(Polkadot, 403611790, uni_src, Here, expected_message, expected_hash)]
);
}
Loading